]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c
MdeModulePkg BootMaintenanceManagerUiLib: Move refresh boot option later
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / BootMaintenance.c
index 8189bd10842a45a9180b21672be0ee69ee73216d..fdcb56a9df2b5d7012767eef22c980f12d6d31dc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 The functions for Boot Maintainence Main menu.\r
 \r
-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2017, 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
@@ -30,6 +30,8 @@ UINT32    mBmmSetupTextModeRow            = 0;
 UINT32    mBmmSetupHorizontalResolution   = 0;\r
 UINT32    mBmmSetupVerticalResolution     = 0;\r
 \r
+BOOLEAN   mBmmModeInitialized             = FALSE;\r
+\r
 EFI_DEVICE_PATH_PROTOCOL  EndDevicePath[] = {\r
   {\r
     END_DEVICE_PATH_TYPE,\r
@@ -82,6 +84,7 @@ BMM_CALLBACK_DATA  gBootMaintenancePrivate = {
 \r
 BMM_CALLBACK_DATA *mBmmCallbackInfo = &gBootMaintenancePrivate;\r
 BOOLEAN  mAllMenuInit               = FALSE;\r
+BOOLEAN  mFirstEnterBMMForm         = FALSE;\r
 \r
 /**\r
   Init all memu.\r
@@ -103,6 +106,16 @@ FreeAllMenu (
   VOID\r
   );\r
 \r
+/**\r
+\r
+  Update the menus in the BMM page.\r
+\r
+**/\r
+VOID\r
+CustomizeMenus (\r
+  VOID\r
+  );\r
+\r
 /**\r
   This function will change video resolution and text mode\r
   according to defined setup mode or defined boot mode  \r
@@ -114,8 +127,7 @@ FreeAllMenu (
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-BmmBdsSetConsoleMode (\r
+BmmSetConsoleMode (\r
   BOOLEAN  IsSetupMode\r
   )\r
 {\r
@@ -167,7 +179,7 @@ BmmBdsSetConsoleMode (
 \r
   if (IsSetupMode) {\r
     //\r
-    // The requried resolution and text mode is setup mode.\r
+    // The required resolution and text mode is setup mode.\r
     //\r
     NewHorizontalResolution = mBmmSetupHorizontalResolution;\r
     NewVerticalResolution   = mBmmSetupVerticalResolution;\r
@@ -223,7 +235,7 @@ BmmBdsSetConsoleMode (
             return EFI_SUCCESS;\r
           } else {\r
             //\r
-            // If current text mode is different from requried text mode.  Set new video mode\r
+            // If current text mode is different from required text mode.  Set new video mode\r
             //\r
             for (Index = 0; Index < MaxTextMode; Index++) {\r
               Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);\r
@@ -248,7 +260,7 @@ BmmBdsSetConsoleMode (
             }\r
             if (Index == MaxTextMode) {\r
               //\r
-              // If requried text mode is not supported, return error.\r
+              // If required text mode is not supported, return error.\r
               //\r
               FreePool (Info);\r
               return EFI_UNSUPPORTED;\r
@@ -378,6 +390,7 @@ ExtractFileNameFromDevicePath (
   String = UiDevicePathToStr(DevicePath);\r
   MatchString = String;\r
   LastMatch   = String;\r
+  FileName    = NULL;\r
 \r
   while(MatchString != NULL){\r
     LastMatch   = MatchString + 1;\r
@@ -386,7 +399,9 @@ ExtractFileNameFromDevicePath (
 \r
   Length = StrLen(LastMatch);\r
   FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);\r
-  *(FileName + Length) = 0;\r
+  if (FileName != NULL) {\r
+    *(FileName + Length) = 0;\r
+  }\r
 \r
   FreePool(String);\r
 \r
@@ -428,6 +443,194 @@ BmmExtractDevicePathFromHiiHandle (
 \r
 }\r
 \r
+/**\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\r
+\r
+  @param ConfigString  String to be converted\r
+\r
+**/\r
+VOID\r
+HiiToLower (\r
+  IN EFI_STRING  ConfigString\r
+  )\r
+{\r
+  EFI_STRING  String;\r
+  BOOLEAN     Lower;\r
+\r
+  ASSERT (ConfigString != NULL);\r
+\r
+  //\r
+  // Convert all hex digits in range [A-F] in the configuration header to [a-f]\r
+  //\r
+  for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {\r
+    if (*String == L'=') {\r
+      Lower = TRUE;\r
+    } else if (*String == L'&') {\r
+      Lower = FALSE;\r
+    } else if (Lower && *String >= L'A' && *String <= L'F') {\r
+      *String = (CHAR16) (*String - L'A' + L'a');\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Update the progress string through the offset value.\r
+\r
+  @param Offset           The offset value\r
+  @param Configuration    Point to the configuration string.\r
+\r
+**/\r
+EFI_STRING\r
+UpdateProgress(\r
+  IN  UINTN       Offset,\r
+  IN  EFI_STRING  Configuration\r
+)\r
+{\r
+  UINTN       Length;\r
+  EFI_STRING  StringPtr;\r
+  EFI_STRING  ReturnString;\r
+\r
+  StringPtr    = NULL;\r
+  ReturnString = NULL;\r
+\r
+  //\r
+  // &OFFSET=XXXX followed by a Null-terminator.\r
+  // Length = StrLen (L"&OFFSET=") + 4 + 1\r
+  //\r
+  Length    = StrLen (L"&OFFSET=") + 4 + 1;\r
+\r
+  StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));\r
+\r
+  if (StringPtr == NULL) {\r
+    return  NULL;\r
+  }\r
+\r
+  UnicodeSPrint (\r
+    StringPtr,\r
+    (8 + 4 + 1) * sizeof (CHAR16),\r
+    L"&OFFSET=%04x",\r
+    Offset\r
+    );\r
+\r
+  ReturnString = StrStr (Configuration, StringPtr);\r
+\r
+  if (ReturnString == NULL) {\r
+    //\r
+    // If doesn't find the string in Configuration, convert the string to lower case then search again.\r
+    //\r
+    HiiToLower (StringPtr);\r
+    ReturnString = StrStr (Configuration, StringPtr);\r
+  }\r
+\r
+  FreePool (StringPtr);\r
+\r
+  return ReturnString;\r
+}\r
+\r
+/**\r
+  Update the terminal content in TerminalMenu.\r
+\r
+  @param BmmData           The BMM fake NV data.\r
+\r
+**/\r
+VOID\r
+UpdateTerminalContent (\r
+  IN BMM_FAKE_NV_DATA       *BmmData\r
+  )\r
+{\r
+  UINT16                          Index;\r
+  BM_TERMINAL_CONTEXT             *NewTerminalContext;\r
+  BM_MENU_ENTRY                   *NewMenuEntry;\r
+\r
+  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
+    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
+    ASSERT (NewMenuEntry != NULL);\r
+    NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
+    NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];\r
+    ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));\r
+    NewTerminalContext->BaudRate      = BaudRateList[BmmData->COMBaudRate[Index]].Value;\r
+    NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];\r
+    ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));\r
+    NewTerminalContext->DataBits      = (UINT8) DataBitsList[BmmData->COMDataRate[Index]].Value;\r
+    NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];\r
+    ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));\r
+    NewTerminalContext->StopBits      = (UINT8) StopBitsList[BmmData->COMStopBits[Index]].Value;\r
+    NewTerminalContext->ParityIndex   = BmmData->COMParity[Index];\r
+    ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));\r
+    NewTerminalContext->Parity        = (UINT8) ParityList[BmmData->COMParity[Index]].Value;\r
+    NewTerminalContext->TerminalType  = BmmData->COMTerminalType[Index];\r
+    NewTerminalContext->FlowControl   = BmmData->COMFlowControl[Index];\r
+    ChangeTerminalDevicePath (\r
+      NewTerminalContext->DevicePath,\r
+      FALSE\r
+      );\r
+  }\r
+}\r
+\r
+/**\r
+  Update the console content in ConsoleMenu.\r
+\r
+  @param ConsoleName       The name for the console device type.\r
+  @param BmmData           The BMM fake NV data.\r
+\r
+**/\r
+VOID\r
+UpdateConsoleContent(\r
+  IN CHAR16                 *ConsoleName,\r
+  IN BMM_FAKE_NV_DATA       *BmmData\r
+  )\r
+{\r
+  UINT16                          Index;\r
+  BM_CONSOLE_CONTEXT              *NewConsoleContext;\r
+  BM_TERMINAL_CONTEXT             *NewTerminalContext;\r
+  BM_MENU_ENTRY                   *NewMenuEntry;\r
+\r
+  if (StrCmp (ConsoleName, L"ConIn") == 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 = BmmData->ConsoleInCheck[Index];\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 = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
+    }\r
+  }\r
+\r
+  if (StrCmp (ConsoleName, L"ConOut") == 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 = BmmData->ConsoleOutCheck[Index];\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 = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
+    }\r
+  }\r
+  if (StrCmp (ConsoleName, L"ErrOut") == 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 = BmmData->ConsoleErrCheck[Index];\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 = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
+    }\r
+  }\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
@@ -574,13 +777,12 @@ BootMaintRouteConfig (
   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
+  BMM_CALLBACK_DATA               *Private;\r
+  UINTN                           Offset;\r
 \r
   if (Progress == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -615,6 +817,7 @@ BootMaintRouteConfig (
   BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
   OldBmmData = &Private->BmmOldFakeNVData;\r
   NewBmmData = &Private->BmmFakeNvData;\r
+  Offset     = 0;\r
   //\r
   // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
   //\r
@@ -636,6 +839,10 @@ BootMaintRouteConfig (
   //         \r
   if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
     Status = Var_UpdateBootNext (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   //\r
@@ -652,11 +859,19 @@ BootMaintRouteConfig (
       NewBmmData->BootOptionDelMark[Index] = FALSE;\r
     }\r
 \r
-    Var_DelBootOption ();\r
+    Status = Var_DelBootOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {\r
     Status = Var_UpdateBootOrder (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){\r
@@ -667,8 +882,10 @@ BootMaintRouteConfig (
                     sizeof(UINT16),\r
                     &(NewBmmData->BootTimeOut)\r
                     );\r
-    ASSERT_EFI_ERROR(Status);\r
-\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);\r
+      goto Exit;\r
+    }\r
     Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;\r
   }\r
 \r
@@ -685,15 +902,27 @@ BootMaintRouteConfig (
       NewBmmData->DriverOptionDel[Index] = FALSE;\r
       NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
     }\r
-    Var_DelDriverOption ();  \r
+    Status = Var_DelDriverOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {  \r
     Status = Var_UpdateDriverOrder (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){\r
-    Var_UpdateConMode(Private);\r
+    Status = Var_UpdateConMode(Private);\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   TerminalAttChange = FALSE;\r
@@ -711,83 +940,60 @@ BootMaintRouteConfig (
       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
+    if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);\r
+    } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);\r
+    } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);\r
+    } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);\r
+    } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);\r
+    } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);\r
+    }\r
+    Status = Var_UpdateConsoleInpOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+    Status = Var_UpdateConsoleOutOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+    Status = Var_UpdateErrorOutOption ();\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\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
-    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 = NewBmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
+    Status = Var_UpdateConsoleInpOption();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);\r
+      goto Exit;\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
-    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 = NewBmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
+    Status = Var_UpdateConsoleOutOption();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);\r
+      goto Exit;\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
-    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 = NewBmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
+    Status = Var_UpdateErrorOutOption();\r
+    if (EFI_ERROR (Status)) {\r
+      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);\r
+      goto Exit;\r
     }\r
-    Var_UpdateErrorOutOption();\r
   }\r
 \r
   if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 ||\r
@@ -795,7 +1001,12 @@ BootMaintRouteConfig (
     Status = Var_UpdateBootOption (Private);\r
     NewBmmData->BootOptionChanged = FALSE;\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);\r
+      } else {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);\r
+      }\r
+      goto Exit;\r
     }\r
     BOpt_GetBootOptions (Private);\r
   }\r
@@ -812,7 +1023,12 @@ BootMaintRouteConfig (
     NewBmmData->DriverOptionChanged = FALSE;\r
     NewBmmData->ForceReconnect      = TRUE;\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);\r
+      } else {\r
+        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);\r
+      }\r
+      goto Exit;\r
     }\r
 \r
     BOpt_GetDriverOptions (Private);\r
@@ -824,6 +1040,17 @@ BootMaintRouteConfig (
   CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
 \r
   return EFI_SUCCESS;\r
+\r
+Exit:\r
+  //\r
+  // Fail to save the data, update the progress string.\r
+  //\r
+  *Progress = UpdateProgress (Offset, Configuration);\r
+  if (Status == EFI_OUT_OF_RESOURCES) {\r
+    return Status;\r
+  } else {\r
+    return EFI_NOT_FOUND;\r
+  }\r
 }\r
 \r
 /**\r
@@ -858,27 +1085,43 @@ BootMaintCallback (
   BMM_CALLBACK_DATA *Private;\r
   BM_MENU_ENTRY     *NewMenuEntry;\r
   BMM_FAKE_NV_DATA  *CurrentFakeNVMap;\r
-  UINTN             OldValue;\r
-  UINTN             NewValue;\r
-  UINTN             Number;\r
+  BMM_FAKE_NV_DATA  *OldFakeNVMap;\r
   UINTN             Index;\r
   EFI_DEVICE_PATH_PROTOCOL * File;\r
 \r
-  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
+  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED && Action != EFI_BROWSER_ACTION_FORM_OPEN) {\r
     //\r
-    // Do nothing for other UEFI Action. Only do call back when data is changed.\r
+    // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.\r
     //\r
     return EFI_UNSUPPORTED;\r
   }\r
-  OldValue       = 0;\r
-  NewValue       = 0;\r
-  Number         = 0;\r
 \r
   Private        = BMM_CALLBACK_DATA_FROM_THIS (This);\r
+\r
+  if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
+    if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {\r
+      if (!mFirstEnterBMMForm) {\r
+        //\r
+        // BMMUiLib depends on LegacyUi library to show legacy menus.\r
+        // If we want to show Legacy menus correctly in BMM page,\r
+        // we must do it after the LegacyUi library has already been initialized.\r
+        // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.\r
+        // So we do the tasks which are related to legacy menus here.\r
+        // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.\r
+        // 2. Re-scan the BootOption menus (including the legacy boot option).\r
+        //\r
+        CustomizeMenus ();\r
+        EfiBootManagerRefreshAllBootOption ();\r
+        BOpt_GetBootOptions (Private);\r
+        mFirstEnterBMMForm = TRUE;\r
+      }\r
+    }\r
+  }\r
   //\r
-  // Retrive uncommitted data from Form Browser\r
+  // Retrieve uncommitted data from Form Browser\r
   //\r
   CurrentFakeNVMap = &Private->BmmFakeNvData;\r
+  OldFakeNVMap     = &Private->BmmOldFakeNVData;\r
   HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
 \r
   if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
@@ -893,12 +1136,12 @@ BootMaintCallback (
         switch (QuestionId) {\r
         case FORM_BOOT_ADD_ID:\r
           // Leave BMM and enter FileExplorer. \r
-          ChooseFile( NULL, L".efi", (CHOOSE_HANDLER) CreateBootOptionFromFile, &File);\r
+          ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);\r
           break;\r
 \r
         case FORM_DRV_ADD_FILE_ID:\r
           // Leave BMM and enter FileExplorer.\r
-          ChooseFile( NULL, L".efi", (CHOOSE_HANDLER) CreateDriverOptionFromFile, &File);\r
+          ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);\r
           break;\r
 \r
         case FORM_DRV_ADD_HANDLE_ID:\r
@@ -921,16 +1164,6 @@ BootMaintCallback (
           UpdateDrvDelPage (Private);\r
           break;\r
 \r
-        case FORM_BOOT_NEXT_ID:\r
-          CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
-          UpdateBootNextPage (Private);\r
-          break;\r
-\r
-        case FORM_TIME_OUT_ID:\r
-          CleanUpPage (FORM_TIME_OUT_ID, Private);\r
-          UpdateTimeOutPage (Private);\r
-          break;\r
-\r
         case FORM_CON_IN_ID:\r
         case FORM_CON_OUT_ID:\r
         case FORM_CON_ERR_ID:\r
@@ -974,7 +1207,7 @@ BootMaintCallback (
     }\r
     if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){\r
       // Leave BMM and enter FileExplorer.\r
-      ChooseFile( NULL, L".efi", (CHOOSE_HANDLER) BootFromFile, &File);\r
+      ChooseFile (NULL, L".efi", BootFromFile, &File);\r
     }\r
   } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
     if ((Value == NULL) || (ActionRequest == NULL)) {\r
@@ -982,17 +1215,21 @@ BootMaintCallback (
     }\r
    \r
     if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
+      CleanUselessBeforeSubmit (Private);\r
       CurrentFakeNVMap->BootOptionChanged = FALSE;\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
     } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
+      CleanUselessBeforeSubmit (Private);\r
       CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
     } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
       //\r
       // Discard changes and exit formset\r
       //\r
-      CurrentFakeNVMap->DriverOptionalData[0]     = 0x0000;\r
-      CurrentFakeNVMap->DriverDescriptionData[0]  = 0x0000;\r
+      ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));\r
+      ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));\r
+      ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));\r
+      ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));\r
       CurrentFakeNVMap->DriverOptionChanged = FALSE;\r
       CurrentFakeNVMap->ForceReconnect      = TRUE;\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
@@ -1000,8 +1237,10 @@ BootMaintCallback (
       //\r
       // Discard changes and exit formset\r
       //\r
-      CurrentFakeNVMap->BootOptionalData[0]     = 0x0000;\r
-      CurrentFakeNVMap->BootDescriptionData[0]  = 0x0000;\r
+      ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));\r
+      ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));\r
+      ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));\r
+      ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));\r
       CurrentFakeNVMap->BootOptionChanged = FALSE;\r
       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
     } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {\r
@@ -1033,6 +1272,7 @@ BootMaintCallback (
       case KEY_VALUE_SAVE_AND_EXIT:\r
       case KEY_VALUE_NO_SAVE_AND_EXIT:\r
         if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
+          CleanUselessBeforeSubmit (Private);\r
           *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
         } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
           DiscardChangeHandler (Private, CurrentFakeNVMap);\r
@@ -1049,6 +1289,22 @@ BootMaintCallback (
         break;\r
       }\r
     }\r
+    //\r
+    // Update the content in Terminal menu and Console menu here.\r
+    //\r
+    if (QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal ||\r
+      QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal ||\r
+      QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal\r
+    ) {\r
+      UpdateTerminalContent(CurrentFakeNVMap);\r
+    }\r
+    if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
+      UpdateConsoleContent (L"ConIn",CurrentFakeNVMap);\r
+    } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
+      UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);\r
+    } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {\r
+      UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);\r
+    }\r
   }\r
 \r
   //\r
@@ -1119,42 +1375,50 @@ DiscardChangeHandler (
 }\r
 \r
 /**\r
-  Create dynamic code for BMM.\r
+  This function is to clean some useless data before submit changes.\r
 \r
-  @param  BmmCallbackInfo        The BMM context data.\r
+  @param Private            The BMM context data.\r
 \r
 **/\r
 VOID\r
-InitializeDrivers(\r
-  IN BMM_CALLBACK_DATA        *BmmCallbackInfo\r
+CleanUselessBeforeSubmit (\r
+  IN  BMM_CALLBACK_DATA               *Private\r
+  )\r
+{\r
+  UINT16  Index;\r
+  if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {\r
+    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
+      if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {\r
+        Private->BmmFakeNvData.BootOptionDel[Index] = FALSE;\r
+        Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;\r
+      }\r
+    }\r
+  }\r
+  if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {\r
+    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
+      if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {\r
+        Private->BmmFakeNvData.DriverOptionDel[Index] = FALSE;\r
+        Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Update the menus in the BMM page.\r
+\r
+**/\r
+VOID\r
+CustomizeMenus (\r
+  VOID\r
   )\r
 {\r
-  EFI_HII_HANDLE              HiiHandle;\r
   VOID                        *StartOpCodeHandle;\r
   VOID                        *EndOpCodeHandle;\r
-  EFI_IFR_GUID_LABEL          *StartLabel;\r
-  EFI_IFR_GUID_LABEL          *EndLabel;\r
-  UINTN                       Index;    \r
-  EFI_STRING                  String;\r
-  EFI_STRING_ID               Token;\r
-  EFI_STRING_ID               TokenHelp;  \r
-  EFI_HII_HANDLE              *HiiHandles;\r
-  EFI_GUID                    FormSetGuid;\r
-  CHAR16                      *DevicePathStr;\r
-  EFI_STRING_ID               DevicePathId;\r
-  EFI_IFR_FORM_SET            *Buffer;      \r
-  UINTN                       BufferSize;   \r
-  UINT8                       ClassGuidNum; \r
-  EFI_GUID                    *ClassGuid;   \r
-  UINTN                       TempSize;\r
-  UINT8                       *Ptr;\r
-  EFI_STATUS                  Status;\r
-\r
-  TempSize =0;\r
-  BufferSize = 0;\r
-  Buffer = NULL;\r
-\r
-  HiiHandle = BmmCallbackInfo->BmmHiiHandle;\r
+  EFI_IFR_GUID_LABEL          *StartGuidLabel;\r
+  EFI_IFR_GUID_LABEL          *EndGuidLabel;\r
+\r
   //\r
   // Allocate space for creation of UpdateData Buffer\r
   //\r
@@ -1163,104 +1427,29 @@ InitializeDrivers(
 \r
   EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
   ASSERT (EndOpCodeHandle != NULL);\r
-\r
   //\r
   // Create Hii Extend Label OpCode as the start opcode\r
   //\r
-  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
-  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
-  StartLabel->Number       = LABEL_BMM_PLATFORM_INFORMATION;\r
-\r
+  StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+  StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+  StartGuidLabel->Number       = LABEL_FORM_MAIN_START;\r
   //\r
   // Create Hii Extend Label OpCode as the end opcode\r
   //\r
-  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
-  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
-  EndLabel->Number       = LABEL_END;\r
-\r
-  //\r
-  // Get all the Hii handles\r
-  //\r
-  HiiHandles = HiiGetHiiHandles (NULL);\r
-  ASSERT (HiiHandles != NULL);\r
+  EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+  EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+  EndGuidLabel->Number       = LABEL_FORM_MAIN_END;\r
 \r
   //\r
-  // Search for formset of each class type\r
+  //Updata Front Page form\r
   //\r
-  for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
-    Status = HiiGetFormSetFromHiiHandle(HiiHandles[Index], &Buffer,&BufferSize);\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-\r
-    Ptr = (UINT8 *)Buffer;\r
-    while(TempSize < BufferSize)  {\r
-      TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
-\r
-      if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){\r
-        Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
-        continue;\r
-      }\r
-\r
-      //\r
-      // Find FormSet OpCode\r
-      //\r
-      ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);\r
-      ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));\r
-      while (ClassGuidNum-- > 0) {\r
-        if (CompareGuid (&gEfiIfrBootMaintenanceGuid, ClassGuid) == 0){\r
-          ClassGuid ++;\r
-          continue;\r
-        }\r
-\r
-        String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL);\r
-        if (String == NULL) {\r
-          String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
-          ASSERT (String != NULL);\r
-        }\r
-        Token = HiiSetString (HiiHandle, 0, String, NULL);\r
-        FreePool (String);\r
-\r
-        String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL);\r
-        if (String == NULL) {\r
-          String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
-          ASSERT (String != NULL);\r
-        }\r
-        TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);\r
-        FreePool (String);\r
-\r
-        FormSetGuid = ((EFI_IFR_FORM_SET *)Ptr)->Guid;\r
-\r
-        DevicePathStr = BmmExtractDevicePathFromHiiHandle(HiiHandles[Index]);\r
-        DevicePathId  = 0;\r
-        if (DevicePathStr != NULL){\r
-          DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);\r
-          FreePool (DevicePathStr);\r
-        }\r
-         HiiCreateGotoExOpCode (\r
-           StartOpCodeHandle,\r
-           0,\r
-           Token,\r
-           TokenHelp,\r
-           0,\r
-           (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_OFFSET),\r
-           0,\r
-           &FormSetGuid,\r
-           DevicePathId\r
-         );\r
-        break;\r
-      }\r
-      Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
-    }\r
+  UiCustomizeBMMPage (\r
+    mBmmCallbackInfo->BmmHiiHandle,\r
+    StartOpCodeHandle\r
+    );\r
 \r
-    FreePool(Buffer);\r
-    Buffer = NULL;\r
-    TempSize = 0;\r
-    BufferSize = 0;\r
-  } \r
-  \r
   HiiUpdateForm (\r
-    HiiHandle,\r
+    mBmmCallbackInfo->BmmHiiHandle,\r
     &mBootMaintGuid,\r
     FORM_MAIN_ID,\r
     StartOpCodeHandle,\r
@@ -1268,8 +1457,7 @@ InitializeDrivers(
     );\r
 \r
   HiiFreeOpCodeHandle (StartOpCodeHandle);\r
-  HiiFreeOpCodeHandle (EndOpCodeHandle);  \r
-  FreePool (HiiHandles);\r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
 }\r
 \r
 /**\r
@@ -1290,8 +1478,6 @@ InitializeBmmConfig (
 \r
   ASSERT (CallbackData != NULL);\r
 \r
-  InitializeDrivers (CallbackData);\r
-\r
   //\r
   // Initialize data which located in BMM main page\r
   //\r
@@ -1379,6 +1565,77 @@ FreeAllMenu (
   mAllMenuInit = FALSE;\r
 }\r
 \r
+/**\r
+  Initial the boot mode related parameters.\r
+\r
+**/\r
+VOID\r
+BmmInitialBootModeInfo (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL       *GraphicsOutput;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *SimpleTextOut;\r
+  UINTN                              BootTextColumn;\r
+  UINTN                              BootTextRow;\r
+\r
+  if (mBmmModeInitialized) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // After the console is ready, get current video resolution\r
+  // and text mode before launching setup at first time.\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  gST->ConsoleOutHandle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  (VOID**)&GraphicsOutput\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    GraphicsOutput = NULL;\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  gST->ConsoleOutHandle,\r
+                  &gEfiSimpleTextOutProtocolGuid,\r
+                  (VOID**)&SimpleTextOut\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    SimpleTextOut = NULL;\r
+  }\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    //\r
+    // Get current video resolution and text mode.\r
+    //\r
+    mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+    mBmmBootVerticalResolution   = GraphicsOutput->Mode->Info->VerticalResolution;\r
+  }\r
+\r
+  if (SimpleTextOut != NULL) {\r
+    Status = SimpleTextOut->QueryMode (\r
+                              SimpleTextOut,\r
+                              SimpleTextOut->Mode->Mode,\r
+                              &BootTextColumn,\r
+                              &BootTextRow\r
+                              );\r
+    mBmmBootTextModeColumn = (UINT32)BootTextColumn;\r
+    mBmmBootTextModeRow    = (UINT32)BootTextRow;\r
+  }\r
+\r
+  //\r
+  // Get user defined text mode for setup.\r
+  //\r
+  mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
+  mBmmSetupVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);\r
+  mBmmSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);\r
+  mBmmSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);\r
+\r
+  mBmmModeInitialized           = TRUE;\r
+}\r
+\r
 /**\r
 \r
   Install Boot Maintenance Manager Menu driver.\r
@@ -1434,8 +1691,6 @@ BootMaintenanceManagerUiLibConstructor (
   Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mBmmCallbackInfo->FormBrowser2);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  EfiBootManagerRefreshAllBootOption ();\r
-\r
   //\r
   // Create LoadOption in BmmCallbackInfo for Driver Callback\r
   //\r
@@ -1467,6 +1722,8 @@ BootMaintenanceManagerUiLibConstructor (
   //\r
   InitializeBmmConfig(mBmmCallbackInfo);\r
 \r
+  BmmInitialBootModeInfo();\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r