]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Support RouteConfig function for BdsDxe driver.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
index b974a67ea53402b4c8a850278858b6ff1c680ed1..6f5b56ec8afc09be79fb4f6d247e305e5b1feebc 100644 (file)
@@ -74,6 +74,7 @@ HII_VENDOR_DEVICE_PATH  mFeHiiVendorDevicePath = {
 \r
 CHAR16  mBootMaintStorageName[]     = L"BmmData";\r
 CHAR16  mFileExplorerStorageName[]  = L"FeData";\r
+BMM_CALLBACK_DATA *mBmmCallbackInfo = NULL;\r
 \r
 /**\r
   Init all memu.\r
@@ -95,6 +96,66 @@ FreeAllMenu (
   VOID\r
   );\r
 \r
+/**\r
+  Initialize all of BMM configuration data in BmmFakeNvData and BmmOldFakeNVData member\r
+  in BMM context data and create all of dynamic OP code for BMM.\r
+\r
+  @param CallbackData    The BMM context data.\r
+\r
+**/\r
+VOID\r
+InitializeBmmConfig (\r
+  IN  BMM_CALLBACK_DATA    *CallbackData\r
+  )\r
+{\r
+  BM_MENU_ENTRY   *NewMenuEntry;\r
+  BM_LOAD_CONTEXT *NewLoadContext;\r
+  UINT16          Index;\r
+\r
+  ASSERT (CallbackData != NULL);\r
+\r
+  //\r
+  // Initialize data which located in BMM main page\r
+  //\r
+  CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);\r
+  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
+    NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+    NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (NewLoadContext->IsBootNext) {\r
+      CallbackData->BmmFakeNvData.BootNext = Index;\r
+      break;\r
+    }\r
+  }\r
+\r
+  CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
+\r
+  //\r
+  // Initialize data which located in Boot Options Menu\r
+  //\r
+  GetBootOrder (CallbackData);\r
+  GetLegacyDeviceOrder (CallbackData);\r
+\r
+  //\r
+  // Initialize data which located in Driver Options Menu\r
+  //\r
+  GetDriverOrder (CallbackData);\r
+\r
+  //\r
+  // Initialize data which located in Console Options Menu\r
+  //  \r
+  GetConsoleOutMode (CallbackData);  \r
+  GetConsoleInCheck (CallbackData);\r
+  GetConsoleOutCheck (CallbackData);\r
+  GetConsoleErrCheck (CallbackData);\r
+  GetTerminalAttribute (CallbackData);\r
+\r
+  //\r
+  // Backup Initialize BMM configuartion data to BmmOldFakeNVData\r
+  //\r
+  CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
+}\r
+\r
 /**\r
   Create string tokens for a menu from its help strings and display strings\r
 \r
@@ -241,6 +302,353 @@ BootMaintExtractConfig (
   return Status;\r
 }\r
 \r
+/**\r
+  This function applies changes in a driver's configuration.\r
+  Input is a Configuration, which has the routing data for this\r
+  driver followed by name / value configuration pairs. The driver\r
+  must apply those pairs to its configurable storage. If the\r
+  driver's configuration is stored in a linear block of data\r
+  and the driver's name / value pairs are in <BlockConfig>\r
+  format, it may use the ConfigToBlock helper function (above) to\r
+  simplify the job. Currently not implemented.\r
+\r
+  @param[in]  This                Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param[in]  Configuration       A null-terminated Unicode string in\r
+                                  <ConfigString> format.   \r
+  @param[out] Progress            A pointer to a string filled in with the\r
+                                  offset of the most recent '&' before the\r
+                                  first failing name / value pair (or the\r
+                                  beginn ing of the string if the failure\r
+                                  is in the first name / value pair) or\r
+                                  the terminating NULL if all was\r
+                                  successful.\r
+\r
+  @retval EFI_SUCCESS             The results have been distributed or are\r
+                                  awaiting distribution.  \r
+  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the\r
+                                  parts of the results that must be\r
+                                  stored awaiting possible future\r
+                                  protocols.\r
+  @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the\r
+                                  Results parameter would result\r
+                                  in this type of error.\r
+  @retval EFI_NOT_FOUND           Target for the specified routing data\r
+                                  was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootMaintRouteConfig (\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
+  UINTN                           BufferSize;\r
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
+  BMM_FAKE_NV_DATA                *NewBmmData;\r
+  BMM_FAKE_NV_DATA                *OldBmmData;\r
+  BM_CONSOLE_CONTEXT              *NewConsoleContext;\r
+  BM_TERMINAL_CONTEXT             *NewTerminalContext;\r
+  BM_MENU_ENTRY                   *NewMenuEntry;\r
+  BM_LOAD_CONTEXT                 *NewLoadContext;\r
+  UINT16                          Index;  \r
+  BOOLEAN                         TerminalAttChange;\r
+  BMM_CALLBACK_DATA               *Private;  \r
+\r
+  if (Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *Progress = Configuration;\r
+\r
+  if (Configuration == 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, &gBootMaintFormSetGuid, mBootMaintStorageName)) {\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
+  Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
+  //\r
+  // Get Buffer Storage data from EFI variable\r
+  //\r
+  BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
+  OldBmmData = &Private->BmmOldFakeNVData;\r
+  NewBmmData = &Private->BmmFakeNvData;\r
+  //\r
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
+  //\r
+  Status = ConfigRouting->ConfigToBlock (\r
+                            ConfigRouting,\r
+                            Configuration,\r
+                            (UINT8 *) NewBmmData,\r
+                            &BufferSize,\r
+                            Progress\r
+                            );\r
+  ASSERT_EFI_ERROR (Status);\r
+  //\r
+  // Compare new and old BMM configuration data and only do action for modified item to \r
+  // avoid setting unnecessary non-volatile variable\r
+  //\r
+\r
+  //\r
+  // Check data which located in BMM main page and save the settings if need\r
+  //\r
+  if (CompareMem (NewBmmData->LegacyFD, OldBmmData->LegacyFD, sizeof (NewBmmData->LegacyFD)) != 0) {\r
+    Var_UpdateBBSOption (Private, FORM_SET_FD_ORDER_ID);\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->LegacyHD, OldBmmData->LegacyHD, sizeof (NewBmmData->LegacyHD)) != 0) {\r
+    Var_UpdateBBSOption (Private, FORM_SET_HD_ORDER_ID);\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->LegacyCD, OldBmmData->LegacyCD, sizeof (NewBmmData->LegacyCD)) != 0) {\r
+    Var_UpdateBBSOption (Private, FORM_SET_CD_ORDER_ID);\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->LegacyNET, OldBmmData->LegacyNET, sizeof (NewBmmData->LegacyNET)) != 0) {\r
+    Var_UpdateBBSOption (Private, FORM_SET_NET_ORDER_ID);\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->LegacyBEV, OldBmmData->LegacyBEV, sizeof (NewBmmData->LegacyBEV)) != 0) {\r
+    Var_UpdateBBSOption (Private, FORM_SET_BEV_ORDER_ID);\r
+  }\r
+\r
+  //\r
+  // Check data which located in Boot Options Menu and save the settings if need\r
+  //\r
+  if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {  \r
+    for (Index = 0; \r
+         ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
+         Index ++) {\r
+      NewMenuEntry            = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+      NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+      NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
+    }\r
+\r
+    Var_DelBootOption ();\r
+  }\r
+\r
+  //\r
+  // Check data which located in Driver Options Menu and save the settings if need\r
+  //\r
+  if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {       \r
+    for (Index = 0; \r
+         ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
+         Index++) {\r
+      NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
+      NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+      NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
+    }\r
+    Var_DelDriverOption ();\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {  \r
+    Status = Var_UpdateBootOrder (Private);\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {  \r
+    Status = Var_UpdateDriverOrder (Private);\r
+  }\r
+\r
+  if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {\r
+    Status = gRT->SetVariable (\r
+                    L"Timeout",\r
+                    &gEfiGlobalVariableGuid,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                    sizeof (UINT16),\r
+                    &(NewBmmData->BootTimeOut)\r
+                    );\r
+    ASSERT_EFI_ERROR(Status);\r
+\r
+    //\r
+    // Bugbug: code not exit in UiApp but in IntelFrameworkModulePkg, need do more check.\r
+    //\r
+    Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut; \r
+  }\r
+\r
+  if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
+    Status = Var_UpdateBootNext (Private);\r
+  }\r
+\r
+  if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) {  \r
+    Var_UpdateConMode (Private);\r
+  }\r
+\r
+  TerminalAttChange = FALSE;\r
+  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
+\r
+    //\r
+    // only need update modified items\r
+    //\r
+    if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
+         CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
+         CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
+         CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
+         CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
+         CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
+      continue;\r
+    }\r
+\r
+    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
+    ASSERT (NewMenuEntry != NULL);\r
+    NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
+    NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];\r
+    ASSERT (NewBmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
+    NewTerminalContext->BaudRate      = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;\r
+    NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];\r
+    ASSERT (NewBmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
+    NewTerminalContext->DataBits      = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;\r
+    NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];\r
+    ASSERT (NewBmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
+    NewTerminalContext->StopBits      = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;\r
+    NewTerminalContext->ParityIndex   = NewBmmData->COMParity[Index];\r
+    ASSERT (NewBmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
+    NewTerminalContext->Parity        = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;\r
+    NewTerminalContext->TerminalType  = NewBmmData->COMTerminalType[Index];\r
+    NewTerminalContext->FlowControl   = NewBmmData->COMFlowControl[Index];\r
+    ChangeTerminalDevicePath (\r
+      &(NewTerminalContext->DevicePath),\r
+      FALSE\r
+      );\r
+    TerminalAttChange = TRUE;\r
+  }\r
+  if (TerminalAttChange) {\r
+    Var_UpdateConsoleInpOption ();\r
+    Var_UpdateConsoleOutOption ();\r
+    Var_UpdateErrorOutOption ();\r
+  }\r
+\r
+  //\r
+  // Check data which located in Console Options Menu and save the settings if need\r
+  //\r
+  if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {\r
+    for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
+      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
+      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+      ASSERT (Index < MAX_MENU_NUMBER);\r
+      NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];\r
+    }\r
+\r
+    Var_UpdateConsoleInpOption ();\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {\r
+    for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
+      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
+      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+      ASSERT (Index < MAX_MENU_NUMBER);\r
+      NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];\r
+    }\r
+\r
+    Var_UpdateConsoleOutOption ();\r
+  }\r
+\r
+  if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) {  \r
+    for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
+      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
+      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
+      ASSERT (Index < MAX_MENU_NUMBER);\r
+      NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];\r
+    }\r
+\r
+    Var_UpdateErrorOutOption ();\r
+  }\r
+\r
+  //\r
+  // After user do the save action, need to update OldBmmData.\r
+  //\r
+  CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create GoTo OP code into FORM_BOOT_LEGACY_DEVICE label for legacy boot option.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeLegacyBootOption (\r
+  VOID\r
+  )\r
+{\r
+  RefreshUpdateData ();\r
+  mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
+  \r
+  //\r
+  // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
+  // in BootOption form: legacy FD/HD/CD/NET/BEV\r
+  //\r
+  HiiCreateGotoOpCode (\r
+    mStartOpCodeHandle,\r
+    FORM_SET_FD_ORDER_ID,\r
+    STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
+    STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    FORM_SET_FD_ORDER_ID\r
+    );\r
+\r
+  HiiCreateGotoOpCode (\r
+    mStartOpCodeHandle,\r
+    FORM_SET_HD_ORDER_ID,\r
+    STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
+    STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    FORM_SET_HD_ORDER_ID\r
+    );\r
+\r
+  HiiCreateGotoOpCode (\r
+    mStartOpCodeHandle,\r
+    FORM_SET_CD_ORDER_ID,\r
+    STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
+    STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    FORM_SET_CD_ORDER_ID\r
+    );\r
+\r
+  HiiCreateGotoOpCode (\r
+    mStartOpCodeHandle,\r
+    FORM_SET_NET_ORDER_ID,\r
+    STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
+    STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    FORM_SET_NET_ORDER_ID\r
+    );\r
+\r
+  HiiCreateGotoOpCode (\r
+    mStartOpCodeHandle,\r
+    FORM_SET_BEV_ORDER_ID,\r
+    STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
+    STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
+    EFI_IFR_FLAG_CALLBACK,\r
+    FORM_SET_BEV_ORDER_ID\r
+    );\r
+  \r
+  HiiUpdateForm (\r
+    mBmmCallbackInfo->BmmHiiHandle,\r
+    &gBootMaintFormSetGuid,\r
+    FORM_BOOT_SETUP_ID,\r
+    mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID\r
+    mEndOpCodeHandle    // LABEL_END\r
+    );\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This function processes the results of changes in configuration.\r
 \r
@@ -286,6 +694,20 @@ BootMaintCallback (
   UINT8             *OldLegacyDev;\r
   UINT8             *NewLegacyDev;\r
   UINT8             *DisMap;\r
+  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;\r
+\r
+  Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
+  if (Action == EFI_BROWSER_ACTION_FORM_OPEN && QuestionId == FORM_BOOT_SETUP_ID) {\r
+    //\r
+    // Initilize Form for legacy boot option.\r
+    //\r
+    Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
+    if (!EFI_ERROR (Status)) {\r
+      InitializeLegacyBootOption ();\r
+    }\r
+    \r
+    return EFI_SUCCESS;\r
+  }\r
 \r
   if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {    \r
     //\r
@@ -636,16 +1058,16 @@ ApplyChangeHandler (
   case FORM_SET_CD_ORDER_ID:\r
   case FORM_SET_NET_ORDER_ID:\r
   case FORM_SET_BEV_ORDER_ID:\r
-    Var_UpdateBBSOption (Private);\r
+    Var_UpdateBBSOption (Private, FormId);\r
     break;\r
 \r
   case FORM_BOOT_DEL_ID:\r
     for (Index = 0; \r
-         ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])))); \r
+         ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])))); \r
          Index ++) {\r
       NewMenuEntry            = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
       NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
-      NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];\r
+      NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
     }\r
 \r
     Var_DelBootOption ();\r
@@ -653,11 +1075,11 @@ ApplyChangeHandler (
 \r
   case FORM_DRV_DEL_ID:\r
     for (Index = 0; \r
-         ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])))); \r
+         ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])))); \r
          Index++) {\r
       NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
       NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
-      NewLoadContext->Deleted = CurrentFakeNVMap->OptionDel[Index];\r
+      NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
     }\r
 \r
     Var_DelDriverOption ();\r
@@ -692,26 +1114,27 @@ ApplyChangeHandler (
     break;\r
 \r
   case FORM_CON_COM_SETUP_ID:\r
-    NewMenuEntry                      = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
+    Index         = (UINT16)Private->CurrentTerminal;\r
+    NewMenuEntry                      = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
 \r
     ASSERT (NewMenuEntry != NULL);\r
 \r
     NewTerminalContext                = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
 \r
-    NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
-    ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
-    NewTerminalContext->BaudRate      = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
-    NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
-    ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
-    NewTerminalContext->DataBits      = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
-    NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
-    ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
-    NewTerminalContext->StopBits      = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
-    NewTerminalContext->ParityIndex   = CurrentFakeNVMap->COMParity;\r
-    ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));\r
-    NewTerminalContext->Parity        = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
-    NewTerminalContext->TerminalType  = CurrentFakeNVMap->COMTerminalType;\r
-    NewTerminalContext->FlowControl   = CurrentFakeNVMap->COMFlowControl;\r
+    NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate[Index];\r
+    ASSERT (CurrentFakeNVMap->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
+    NewTerminalContext->BaudRate      = BaudRateList[CurrentFakeNVMap->COMBaudRate[Index]].Value;\r
+    NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate[Index];\r
+    ASSERT (CurrentFakeNVMap->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
+    NewTerminalContext->DataBits      = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate[Index]].Value;\r
+    NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits[Index];\r
+    ASSERT (CurrentFakeNVMap->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
+    NewTerminalContext->StopBits      = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits[Index]].Value;\r
+    NewTerminalContext->ParityIndex   = CurrentFakeNVMap->COMParity[Index];\r
+    ASSERT (CurrentFakeNVMap->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
+    NewTerminalContext->Parity        = (UINT8) ParityList[CurrentFakeNVMap->COMParity[Index]].Value;\r
+    NewTerminalContext->TerminalType  = CurrentFakeNVMap->COMTerminalType[Index];\r
+    NewTerminalContext->FlowControl   = CurrentFakeNVMap->COMFlowControl[Index];\r
 \r
     ChangeTerminalDevicePath (\r
       &(NewTerminalContext->DevicePath),\r
@@ -728,14 +1151,14 @@ ApplyChangeHandler (
       NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
       NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
       ASSERT (Index < MAX_MENU_NUMBER);\r
-      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
+      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleInCheck[Index];\r
     }\r
 \r
     for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
       NewMenuEntry                = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
       NewTerminalContext          = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
       ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
-      NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
+      NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
     }\r
 \r
     Var_UpdateConsoleInpOption ();\r
@@ -746,14 +1169,14 @@ ApplyChangeHandler (
       NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
       NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
       ASSERT (Index < MAX_MENU_NUMBER);\r
-      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
+      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleOutCheck[Index];\r
     }\r
 \r
     for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
       NewMenuEntry                  = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
       NewTerminalContext            = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
       ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
-      NewTerminalContext->IsConOut  = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
+      NewTerminalContext->IsConOut  = CurrentFakeNVMap->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
     }\r
 \r
     Var_UpdateConsoleOutOption ();\r
@@ -764,14 +1187,14 @@ ApplyChangeHandler (
       NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
       NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
       ASSERT (Index < MAX_MENU_NUMBER);\r
-      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
+      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleErrCheck[Index];\r
     }\r
 \r
     for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
       NewMenuEntry                  = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
       NewTerminalContext            = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
       ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
-      NewTerminalContext->IsStdErr  = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
+      NewTerminalContext->IsStdErr  = CurrentFakeNVMap->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
     }\r
 \r
     Var_UpdateErrorOutOption ();\r
@@ -819,21 +1242,24 @@ DiscardChangeHandler (
 \r
   switch (Private->BmmPreviousPageId) {\r
   case FORM_BOOT_CHG_ID:\r
+    CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
+    break;\r
+\r
   case FORM_DRV_CHG_ID:\r
-    CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, sizeof (CurrentFakeNVMap->OptionOrder));\r
+    CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
     break;\r
 \r
   case FORM_BOOT_DEL_ID:\r
-    ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));\r
+    ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
     for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
-      CurrentFakeNVMap->OptionDel[Index] = FALSE;\r
+      CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
     }\r
     break;\r
 \r
   case FORM_DRV_DEL_ID:\r
-    ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->OptionDel) / sizeof (CurrentFakeNVMap->OptionDel[0])));\r
+    ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
     for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
-      CurrentFakeNVMap->OptionDel[Index] = FALSE;\r
+      CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
     }\r
     break;\r
 \r
@@ -870,109 +1296,78 @@ InitializeBM (
   VOID\r
   )\r
 {\r
-  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;\r
   BMM_CALLBACK_DATA           *BmmCallbackInfo;\r
   EFI_STATUS                  Status;\r
-  UINT8                       *Ptr;\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;\r
+  UINT32                      Length;\r
+  UINT8                       *Data;\r
 \r
   Status = EFI_SUCCESS;\r
+  BmmCallbackInfo = mBmmCallbackInfo;  \r
+\r
+  BmmCallbackInfo->BmmPreviousPageId             = FORM_MAIN_ID;\r
+  BmmCallbackInfo->BmmCurrentPageId              = FORM_MAIN_ID;\r
+  BmmCallbackInfo->FeCurrentState                = FileExplorerStateInActive;\r
+  BmmCallbackInfo->FeDisplayContext              = FileExplorerDisplayUnknown;\r
 \r
   //\r
-  // Create CallbackData structures for Driver Callback\r
+  // Reinstall String packages to include more new strings.\r
   //\r
-  BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
-  if (BmmCallbackInfo == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
+  \r
   //\r
-  // Create LoadOption in BmmCallbackInfo for Driver Callback\r
+  // String package size\r
   //\r
-  Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
-  if (Ptr == NULL) {\r
-    FreePool (BmmCallbackInfo);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
+  Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);\r
 \r
   //\r
-  // Initialize Bmm callback data.\r
+  // Add the length of the Package List Header and the terminating Package Header \r
   //\r
-  BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
-  Ptr += sizeof (BM_LOAD_CONTEXT);\r
-\r
-  BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
-  Ptr += sizeof (BM_FILE_CONTEXT);\r
-\r
-  BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
-  Ptr += sizeof (BM_HANDLE_CONTEXT);\r
-\r
-  BmmCallbackInfo->MenuEntry      = (BM_MENU_ENTRY *) Ptr;\r
-\r
-  BmmCallbackInfo->Signature                     = BMM_CALLBACK_DATA_SIGNATURE;\r
-  BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
-  BmmCallbackInfo->BmmConfigAccess.RouteConfig   = FakeRouteConfig;\r
-  BmmCallbackInfo->BmmConfigAccess.Callback      = BootMaintCallback;\r
-  BmmCallbackInfo->BmmPreviousPageId             = FORM_MAIN_ID;\r
-  BmmCallbackInfo->BmmCurrentPageId              = FORM_MAIN_ID;\r
-  BmmCallbackInfo->FeConfigAccess.ExtractConfig  = FakeExtractConfig;\r
-  BmmCallbackInfo->FeConfigAccess.RouteConfig    = FakeRouteConfig;\r
-  BmmCallbackInfo->FeConfigAccess.Callback       = FileExplorerCallback;\r
-  BmmCallbackInfo->FeCurrentState                = FileExplorerStateInActive;\r
-  BmmCallbackInfo->FeDisplayContext              = FileExplorerDisplayUnknown;\r
+  Length += sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EFI_HII_PACKAGE_HEADER);\r
+  \r
+  //\r
+  // Allocate the storage for the entire Package List\r
+  //\r
+  PackageListHeader = AllocateZeroPool (Length);\r
 \r
   //\r
-  // Install Device Path Protocol and Config Access protocol to driver handle\r
+  // If the Package List can not be allocated, then return a NULL HII Handle\r
   //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &BmmCallbackInfo->BmmDriverHandle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  &mBmmHiiVendorDevicePath,\r
-                  &gEfiHiiConfigAccessProtocolGuid,\r
-                  &BmmCallbackInfo->BmmConfigAccess,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
+  if (PackageListHeader == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   //\r
-  // Install Device Path Protocol and Config Access protocol to driver handle\r
+  // Fill in the GUID and Length of the Package List Header\r
   //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &BmmCallbackInfo->FeDriverHandle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  &mFeHiiVendorDevicePath,\r
-                  &gEfiHiiConfigAccessProtocolGuid,\r
-                  &BmmCallbackInfo->FeConfigAccess,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
-  }\r
+  PackageListHeader->PackageLength = Length;\r
 \r
   //\r
-  // Post our Boot Maint VFR binary to the HII database.\r
+  // Copy String Data into Package list. \r
   //\r
-  BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
-                                    &gBootMaintFormSetGuid,\r
-                                    BmmCallbackInfo->BmmDriverHandle,\r
-                                    BmBin,\r
-                                    BdsDxeStrings,\r
-                                    NULL\r
-                                    );\r
-  ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);\r
+  Data = (UINT8 *)(PackageListHeader + 1);\r
+  Length = ReadUnaligned32 ((UINT32 *) BdsDxeStrings) - sizeof (UINT32);\r
+  CopyMem (Data, (UINT8 *) BdsDxeStrings + sizeof (UINT32), Length);\r
+  \r
+  //\r
+  // Add End type HII package.\r
+  //\r
+  Data += Length;\r
+  ((EFI_HII_PACKAGE_HEADER *) Data)->Type   = EFI_HII_PACKAGE_END;\r
+  ((EFI_HII_PACKAGE_HEADER *) Data)->Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
 \r
   //\r
-  // Post our File Explorer VFR binary to the HII database.\r
+  // Update String package for BM\r
   //\r
-  BmmCallbackInfo->FeHiiHandle = HiiAddPackages (\r
-                                   &gFileExploreFormSetGuid,\r
-                                   BmmCallbackInfo->FeDriverHandle,\r
-                                   FEBin,\r
-                                   BdsDxeStrings,\r
-                                   NULL\r
-                                   );\r
-  ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);\r
+  CopyGuid (&PackageListHeader->PackageListGuid, &gBootMaintFormSetGuid);\r
+  Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle, PackageListHeader);\r
+  \r
+  //\r
+  // Update String package for FE.\r
+  //\r
+  CopyGuid (&PackageListHeader->PackageListGuid, &gFileExploreFormSetGuid);\r
+  Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle, PackageListHeader);\r
+  \r
+  FreePool (PackageListHeader);\r
 \r
   //\r
   // Init OpCode Handle and Allocate space for creation of Buffer\r
@@ -1013,77 +1408,8 @@ InitializeBM (
   CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
   CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
   CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
-\r
-  UpdateBootDelPage (BmmCallbackInfo);\r
-  UpdateDrvDelPage (BmmCallbackInfo);\r
-\r
-  if (TerminalMenu.MenuNumber > 0) {\r
-    BmmCallbackInfo->CurrentTerminal = 0;\r
-    UpdateTerminalPage (BmmCallbackInfo);\r
-  }\r
-\r
-  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
-  if (!EFI_ERROR (Status)) {\r
-    RefreshUpdateData ();\r
-    mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
-\r
-    //\r
-    // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
-    // in BootOption form: legacy FD/HD/CD/NET/BEV\r
-    //\r
-    HiiCreateGotoOpCode (\r
-      mStartOpCodeHandle,\r
-      FORM_SET_FD_ORDER_ID,\r
-      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
-      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
-      EFI_IFR_FLAG_CALLBACK,\r
-      FORM_SET_FD_ORDER_ID\r
-      );\r
-\r
-    HiiCreateGotoOpCode (\r
-      mStartOpCodeHandle,\r
-      FORM_SET_HD_ORDER_ID,\r
-      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
-      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
-      EFI_IFR_FLAG_CALLBACK,\r
-      FORM_SET_HD_ORDER_ID\r
-      );\r
-\r
-    HiiCreateGotoOpCode (\r
-      mStartOpCodeHandle,\r
-      FORM_SET_CD_ORDER_ID,\r
-      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
-      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
-      EFI_IFR_FLAG_CALLBACK,\r
-      FORM_SET_CD_ORDER_ID\r
-      );\r
-\r
-    HiiCreateGotoOpCode (\r
-      mStartOpCodeHandle,\r
-      FORM_SET_NET_ORDER_ID,\r
-      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
-      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
-      EFI_IFR_FLAG_CALLBACK,\r
-      FORM_SET_NET_ORDER_ID\r
-      );\r
-\r
-    HiiCreateGotoOpCode (\r
-      mStartOpCodeHandle,\r
-      FORM_SET_BEV_ORDER_ID,\r
-      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
-      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
-      EFI_IFR_FLAG_CALLBACK,\r
-      FORM_SET_BEV_ORDER_ID\r
-      );\r
-    \r
-    HiiUpdateForm (\r
-      BmmCallbackInfo->BmmHiiHandle,\r
-      &gBootMaintFormSetGuid,\r
-      FORM_BOOT_SETUP_ID,\r
-      mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID\r
-      mEndOpCodeHandle    // LABEL_END\r
-      );\r
-  }\r
+  \r
+  InitializeBmmConfig (BmmCallbackInfo);\r
 \r
   //\r
   // Dispatch BMM main formset and File Explorer formset.\r
@@ -1091,13 +1417,10 @@ InitializeBM (
   FormSetDispatcher (BmmCallbackInfo);\r
 \r
   //\r
-  // Remove our IFR data from HII database\r
+  // Clean up.\r
   //\r
-  HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);\r
-  HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);\r
-\r
   CleanUpStringDepository ();\r
-\r
+  \r
   FreeAllMenu ();\r
 \r
 Exit:\r
@@ -1109,34 +1432,10 @@ Exit:
     HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
   }\r
 \r
-  if (BmmCallbackInfo->FeDriverHandle != NULL) {\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-           BmmCallbackInfo->FeDriverHandle,\r
-           &gEfiDevicePathProtocolGuid,\r
-           &mFeHiiVendorDevicePath,\r
-           &gEfiHiiConfigAccessProtocolGuid,\r
-           &BmmCallbackInfo->FeConfigAccess,\r
-           NULL\r
-           );\r
-  }\r
-\r
-  if (BmmCallbackInfo->BmmDriverHandle != NULL) {\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-           BmmCallbackInfo->BmmDriverHandle,\r
-           &gEfiDevicePathProtocolGuid,\r
-           &mBmmHiiVendorDevicePath,\r
-           &gEfiHiiConfigAccessProtocolGuid,\r
-           &BmmCallbackInfo->BmmConfigAccess,\r
-           NULL\r
-           );\r
-  }\r
-\r
-  FreePool (BmmCallbackInfo->LoadContext);\r
-  FreePool (BmmCallbackInfo);\r
-\r
   return Status;\r
 }\r
 \r
+\r
 /**\r
   Initialized all Menu Option List.\r
 \r
@@ -1415,3 +1714,159 @@ FormSetDispatcher (
   return Status;\r
 }\r
 \r
+/**\r
+  Intall BootMaint and FileExplorer HiiPackages.\r
+\r
+**/\r
+EFI_STATUS\r
+InitBMPackage (\r
+  VOID\r
+  )\r
+{\r
+  BMM_CALLBACK_DATA           *BmmCallbackInfo;\r
+  EFI_STATUS                  Status;\r
+  UINT8                       *Ptr;\r
+  \r
+  //\r
+  // Create CallbackData structures for Driver Callback\r
+  //\r
+  BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
+  if (BmmCallbackInfo == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  //\r
+  // Create LoadOption in BmmCallbackInfo for Driver Callback\r
+  //\r
+  Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
+  if (Ptr == NULL) {\r
+    FreePool (BmmCallbackInfo);\r
+    BmmCallbackInfo = NULL;\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  //\r
+  // Initialize Bmm callback data.\r
+  //\r
+  BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
+  Ptr += sizeof (BM_LOAD_CONTEXT);\r
+\r
+  BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
+  Ptr += sizeof (BM_FILE_CONTEXT);\r
+\r
+  BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
+  Ptr += sizeof (BM_HANDLE_CONTEXT);\r
+\r
+  BmmCallbackInfo->MenuEntry      = (BM_MENU_ENTRY *) Ptr;\r
+\r
+  BmmCallbackInfo->Signature                     = BMM_CALLBACK_DATA_SIGNATURE;\r
+  BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
+  BmmCallbackInfo->BmmConfigAccess.RouteConfig   = BootMaintRouteConfig;\r
+  BmmCallbackInfo->BmmConfigAccess.Callback      = BootMaintCallback;\r
+  BmmCallbackInfo->FeConfigAccess.ExtractConfig  = FakeExtractConfig;\r
+  BmmCallbackInfo->FeConfigAccess.RouteConfig    = FileExplorerRouteConfig;\r
+  BmmCallbackInfo->FeConfigAccess.Callback       = FileExplorerCallback;\r
+\r
+  //\r
+  // Install Device Path Protocol and Config Access protocol to driver handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &BmmCallbackInfo->BmmDriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mBmmHiiVendorDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  &BmmCallbackInfo->BmmConfigAccess,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Install Device Path Protocol and Config Access protocol to driver handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &BmmCallbackInfo->FeDriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &mFeHiiVendorDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  &BmmCallbackInfo->FeConfigAccess,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Post our Boot Maint VFR binary to the HII database.\r
+  //\r
+  BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
+                                    &gBootMaintFormSetGuid,\r
+                                    BmmCallbackInfo->BmmDriverHandle,\r
+                                    BmBin,\r
+                                    BdsDxeStrings,\r
+                                    NULL\r
+                                    );\r
+  ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);\r
+\r
+  //\r
+  // Post our File Explorer VFR binary to the HII database.\r
+  //\r
+  BmmCallbackInfo->FeHiiHandle = HiiAddPackages (\r
+                                   &gFileExploreFormSetGuid,\r
+                                   BmmCallbackInfo->FeDriverHandle,\r
+                                   FEBin,\r
+                                   BdsDxeStrings,\r
+                                   NULL\r
+                                   );\r
+  ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);\r
+  \r
+  mBmmCallbackInfo = BmmCallbackInfo;\r
+  \r
+  return EFI_SUCCESS; \r
+}\r
+\r
+/**\r
+  Remvoe the intalled BootMaint and FileExplorer HiiPackages.\r
+\r
+**/\r
+VOID\r
+FreeBMPackage (\r
+  VOID\r
+  )\r
+{\r
+  BMM_CALLBACK_DATA           *BmmCallbackInfo;\r
+\r
+  BmmCallbackInfo = mBmmCallbackInfo;\r
+\r
+  //\r
+  // Remove our IFR data from HII database\r
+  //\r
+  HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);\r
+  HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);\r
+\r
+  if (BmmCallbackInfo->FeDriverHandle != NULL) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           BmmCallbackInfo->FeDriverHandle,\r
+           &gEfiDevicePathProtocolGuid,\r
+           &mFeHiiVendorDevicePath,\r
+           &gEfiHiiConfigAccessProtocolGuid,\r
+           &BmmCallbackInfo->FeConfigAccess,\r
+           NULL\r
+           );\r
+  }\r
+\r
+  if (BmmCallbackInfo->BmmDriverHandle != NULL) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
+           BmmCallbackInfo->BmmDriverHandle,\r
+           &gEfiDevicePathProtocolGuid,\r
+           &mBmmHiiVendorDevicePath,\r
+           &gEfiHiiConfigAccessProtocolGuid,\r
+           &BmmCallbackInfo->BmmConfigAccess,\r
+           NULL\r
+           );\r
+  }\r
+\r
+  FreePool (BmmCallbackInfo->LoadContext);\r
+  FreePool (BmmCallbackInfo);\r
+\r
+  mBmmCallbackInfo = NULL; \r
+  \r
+  return;\r
+}\r
+\r