]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
IntelFrameworkModulePkg: Replace [Ascii|Unicode]ValueToString
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / FrontPage.c
index 39d2e235e3d935a771088a1a5e930e68b0ec717b..ec9142245a46d7a3837ba2e90d87759a458ea228 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   FrontPage routines to handle the callbacks and browser calls\r
 \r
-Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\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
 http://opensource.org/licenses/bsd-license.php\r
@@ -15,11 +15,28 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "Bds.h"\r
 #include "FrontPage.h"\r
 #include "Language.h"\r
+#include "Hotkey.h"\r
 \r
-EFI_GUID  mFrontPageGuid      = FRONT_PAGE_FORMSET_GUID;\r
+BOOLEAN   mModeInitialized = FALSE;\r
 \r
 BOOLEAN   gConnectAllHappened = FALSE;\r
 UINTN     gCallbackKey;\r
+CHAR8     *mLanguageString;\r
+\r
+//\r
+// Boot video resolution and text mode.\r
+//\r
+UINT32    mBootHorizontalResolution    = 0;\r
+UINT32    mBootVerticalResolution      = 0;\r
+UINT32    mBootTextModeColumn          = 0;\r
+UINT32    mBootTextModeRow             = 0;\r
+//\r
+// BIOS setup video resolution and text mode.\r
+//\r
+UINT32    mSetupTextModeColumn         = 0;\r
+UINT32    mSetupTextModeRow            = 0;\r
+UINT32    mSetupHorizontalResolution   = 0;\r
+UINT32    mSetupVerticalResolution     = 0;\r
 \r
 EFI_FORM_BROWSER2_PROTOCOL      *gFormBrowser2;\r
 \r
@@ -45,10 +62,7 @@ HII_VENDOR_DEVICE_PATH  mFrontPageHiiVendorDevicePath = {
         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
       }\r
     },\r
-    //\r
-    // {8E6D99EE-7531-48f8-8745-7F6144468FF2}\r
-    //\r
-    { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }\r
+    FRONT_PAGE_FORMSET_GUID\r
   },\r
   {\r
     END_DEVICE_PATH_TYPE,\r
@@ -127,8 +141,8 @@ FakeRouteConfig (
   }\r
 \r
   *Progress = Configuration;\r
-  if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)\r
-      && !HiiIsConfigHdrMatch (Configuration, &mFileExplorerGuid, mFileExplorerStorageName)) {\r
+  if (!HiiIsConfigHdrMatch (Configuration, &gBootMaintFormSetGuid, mBootMaintStorageName)\r
+      && !HiiIsConfigHdrMatch (Configuration, &gFileExploreFormSetGuid, mFileExplorerStorageName)) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
@@ -165,119 +179,107 @@ FrontPageCallback (
   OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
   )\r
 {\r
-  CHAR8                         *LanguageString;\r
   CHAR8                         *LangCode;\r
   CHAR8                         *Lang;\r
   UINTN                         Index;\r
-  EFI_STATUS                    Status;\r
-  CHAR8                         *PlatformSupportedLanguages;\r
-  CHAR8                         *BestLanguage;\r
 \r
-  if ((Value == NULL) || (ActionRequest == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
+  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
+    //\r
+    // All other action return unsupported.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
   }\r
-\r
+  \r
   gCallbackKey = QuestionId;\r
 \r
-  //\r
-  // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
-  // describe to their customers in documentation how to find their setup information (namely\r
-  // under the device manager and specific buckets)\r
-  //\r
-  switch (QuestionId) {\r
-  case FRONT_PAGE_KEY_CONTINUE:\r
-    //\r
-    // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
-    //\r
-    break;\r
+  if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    if ((Value == NULL) || (ActionRequest == NULL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
 \r
-  case FRONT_PAGE_KEY_LANGUAGE:\r
-    //\r
-    // Collect the languages from what our current Language support is based on our VFR\r
-    //\r
-    LanguageString = HiiGetSupportedLanguages (gFrontPagePrivate.HiiHandle);\r
-    ASSERT (LanguageString != NULL);\r
-    //\r
-    // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
-    //\r
-    Lang = AllocatePool (AsciiStrSize (LanguageString));\r
-    ASSERT (Lang != NULL);\r
+    switch (QuestionId) {\r
+    case FRONT_PAGE_KEY_CONTINUE:\r
+      //\r
+      // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
+      //\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+      break;\r
 \r
-    Index = 0;\r
-    LangCode = LanguageString;\r
-    while (*LangCode != 0) {\r
-      GetNextLanguage (&LangCode, Lang);\r
+    case FRONT_PAGE_KEY_LANGUAGE:\r
+      //\r
+      // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
+      //\r
+      Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
+      ASSERT (Lang != NULL);  \r
+\r
+      Index = 0;\r
+      LangCode = mLanguageString;\r
+      while (*LangCode != 0) {\r
+        GetNextLanguage (&LangCode, Lang);\r
+\r
+        if (Index == Value->u8) {\r
+          break;\r
+        }\r
+\r
+        Index++;\r
+      }\r
 \r
       if (Index == Value->u8) {\r
-        break;\r
+        BdsDxeSetVariableAndReportStatusCodeOnError (\r
+                        L"PlatformLang",\r
+                        &gEfiGlobalVariableGuid,\r
+                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                        AsciiStrSize (Lang),\r
+                        Lang\r
+                        );\r
+      } else {\r
+        ASSERT (FALSE);\r
       }\r
 \r
-      Index++;\r
-    }\r
+      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
 \r
-    PlatformSupportedLanguages = GetEfiGlobalVariable (L"PlatformLangCodes");\r
-    if (PlatformSupportedLanguages == NULL) {\r
-      PlatformSupportedLanguages = AllocateCopyPool (\r
-                                     AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
-                                     (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
-                                     );\r
-      ASSERT (PlatformSupportedLanguages != NULL);\r
-    }\r
+      FreePool (Lang);\r
+      break;\r
 \r
-    //\r
-    // Select the best language in platform supported Language.\r
-    //\r
-    BestLanguage = GetBestLanguage (\r
-                     PlatformSupportedLanguages,\r
-                     FALSE,\r
-                     Lang,\r
-                     NULL\r
-                     );\r
-    if (BestLanguage != NULL) {\r
-      Status = gRT->SetVariable (\r
-                      L"PlatformLang",\r
-                      &gEfiGlobalVariableGuid,\r
-                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
-                      AsciiStrSize (BestLanguage),\r
-                      Lang\r
-                      );\r
-      ASSERT_EFI_ERROR(Status);\r
-      FreePool (BestLanguage);\r
-    } else {\r
-      ASSERT (FALSE);\r
+    default:\r
+      break;\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    if (Value == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
 \r
-    FreePool (PlatformSupportedLanguages);\r
-    FreePool (Lang);\r
-    FreePool (LanguageString);\r
-    break;\r
-\r
-  case FRONT_PAGE_KEY_BOOT_MANAGER:\r
     //\r
-    // Boot Manager\r
+    // The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can\r
+    // describe to their customers in documentation how to find their setup information (namely\r
+    // under the device manager and specific buckets)\r
     //\r
-    break;\r
+    switch (QuestionId) {\r
+    case FRONT_PAGE_KEY_BOOT_MANAGER:\r
+      //\r
+      // Boot Manager\r
+      //\r
+      break;\r
 \r
-  case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
-    //\r
-    // Device Manager\r
-    //\r
-    break;\r
+    case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
+      //\r
+      // Device Manager\r
+      //\r
+      break;\r
 \r
-  case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
-    //\r
-    // Boot Maintenance Manager\r
-    //\r
-    break;\r
+    case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
+      //\r
+      // Boot Maintenance Manager\r
+      //\r
+      break;\r
 \r
-  default:\r
-    gCallbackKey = 0;\r
-    break;\r
+    default:\r
+      gCallbackKey = 0;\r
+      break;\r
+    }\r
   }\r
 \r
-  *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
-\r
-  return EFI_SUCCESS;\r
+  return EFI_SUCCESS;  \r
 }\r
 \r
 /**\r
@@ -296,11 +298,10 @@ InitializeFrontPage (
   )\r
 {\r
   EFI_STATUS                  Status;\r
-  CHAR8                       *LanguageString;\r
   CHAR8                       *LangCode;\r
   CHAR8                       *Lang;\r
+  UINTN                       LangSize;\r
   CHAR8                       *CurrentLang;\r
-  CHAR8                       *BestLanguage;\r
   UINTN                       OptionCount;\r
   CHAR16                      *StringBuffer;\r
   EFI_HII_HANDLE              HiiHandle;\r
@@ -309,7 +310,11 @@ InitializeFrontPage (
   VOID                        *EndOpCodeHandle;\r
   EFI_IFR_GUID_LABEL          *StartLabel;\r
   EFI_IFR_GUID_LABEL          *EndLabel;\r
-  BOOLEAN                     FirstFlag;\r
+  EFI_HII_STRING_PROTOCOL     *HiiString;\r
+  UINTN                       StringSize;\r
+\r
+  Lang         = NULL;\r
+  StringBuffer = NULL;\r
 \r
   if (InitializeHiiData) {\r
     //\r
@@ -349,7 +354,7 @@ InitializeFrontPage (
     // Publish our HII data\r
     //\r
     gFrontPagePrivate.HiiHandle = HiiAddPackages (\r
-                                    &mFrontPageGuid,\r
+                                    &gFrontPageFormSetGuid,\r
                                     gFrontPagePrivate.DriverHandle,\r
                                     FrontPageVfrBin,\r
                                     BdsDxeStrings,\r
@@ -390,62 +395,85 @@ InitializeFrontPage (
   // Collect the languages from what our current Language support is based on our VFR\r
   //\r
   HiiHandle = gFrontPagePrivate.HiiHandle;\r
-  LanguageString = HiiGetSupportedLanguages (HiiHandle);\r
-  ASSERT (LanguageString != NULL);\r
-  //\r
-  // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
-  //\r
-  Lang = AllocatePool (AsciiStrSize (LanguageString));\r
-  ASSERT (Lang != NULL);\r
 \r
-  CurrentLang = GetEfiGlobalVariable (L"PlatformLang");\r
-  //\r
-  // Select the best language in LanguageString as the default one.\r
-  //\r
-  BestLanguage = GetBestLanguage (\r
-                   LanguageString,\r
-                   FALSE,\r
-                   (CurrentLang != NULL) ? CurrentLang : "",\r
-                   (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
-                   LanguageString,\r
-                   NULL\r
-                   );\r
+  GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);\r
+\r
   //\r
-  // BestLanguage must be selected as it is the first language in LanguageString by default\r
+  // Get Support language list from variable.\r
   //\r
-  ASSERT (BestLanguage != NULL);\r
-\r
-  OptionCount = 0;\r
-  LangCode    = LanguageString;\r
-  FirstFlag   = FALSE;\r
+  if (mLanguageString == NULL){\r
+    GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&mLanguageString, NULL);\r
+    if (mLanguageString == NULL) {\r
+      mLanguageString = AllocateCopyPool (\r
+                                 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
+                                 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
+                                 );\r
+      ASSERT (mLanguageString != NULL);\r
+    }\r
+  }\r
 \r
   if (gFrontPagePrivate.LanguageToken == NULL) {\r
+    //\r
+    // Count the language list number.\r
+    //  \r
+    LangCode      = mLanguageString;\r
+    Lang          = AllocatePool (AsciiStrSize (mLanguageString));\r
+    ASSERT (Lang != NULL);\r
+    OptionCount = 0;\r
     while (*LangCode != 0) {\r
       GetNextLanguage (&LangCode, Lang);\r
       OptionCount ++;\r
     }\r
-    gFrontPagePrivate.LanguageToken = AllocatePool (OptionCount * sizeof (EFI_STRING_ID));\r
+\r
+    //\r
+    // Allocate extra 1 as the end tag.\r
+    //\r
+    gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));\r
     ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
-    FirstFlag = TRUE;\r
-  }\r
 \r
-  OptionCount = 0;\r
-  LangCode = LanguageString;\r
-  while (*LangCode != 0) {\r
-    GetNextLanguage (&LangCode, Lang);\r
+    Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-    if (FirstFlag) {\r
-      StringBuffer = HiiGetString (HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, Lang);\r
-      ASSERT_EFI_ERROR (StringBuffer != NULL);\r
+    LangCode     = mLanguageString;\r
+    OptionCount  = 0;\r
+    while (*LangCode != 0) {\r
+      GetNextLanguage (&LangCode, Lang);\r
 \r
-      //\r
-      // Save the string Id for each language\r
-      //\r
+      StringSize = 0;\r
+      Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
+      if (Status == EFI_BUFFER_TOO_SMALL) {\r
+        StringBuffer = AllocateZeroPool (StringSize);\r
+        ASSERT (StringBuffer != NULL);\r
+        Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        LangSize = AsciiStrSize (Lang);\r
+        StringBuffer = AllocatePool (LangSize * sizeof (CHAR16));\r
+        ASSERT (StringBuffer != NULL);\r
+        AsciiStrToUnicodeStrS (Lang, StringBuffer, LangSize);\r
+      }\r
+\r
+      ASSERT (StringBuffer != NULL);\r
       gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
       FreePool (StringBuffer);\r
+\r
+      OptionCount++;\r
     }\r
+  }\r
 \r
-    if (AsciiStrCmp (Lang, BestLanguage) == 0) {\r
+  ASSERT (gFrontPagePrivate.LanguageToken != NULL);\r
+  LangCode     = mLanguageString;\r
+  OptionCount  = 0;\r
+  if (Lang == NULL) {\r
+    Lang = AllocatePool (AsciiStrSize (mLanguageString));\r
+    ASSERT (Lang != NULL);\r
+  }\r
+  while (*LangCode != 0) {\r
+    GetNextLanguage (&LangCode, Lang);\r
+\r
+    if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {\r
       HiiCreateOneOfOptionOpCode (\r
         OptionsOpCodeHandle,\r
         gFrontPagePrivate.LanguageToken[OptionCount],\r
@@ -469,9 +497,7 @@ InitializeFrontPage (
   if (CurrentLang != NULL) {\r
     FreePool (CurrentLang);\r
   }\r
-  FreePool (BestLanguage);\r
   FreePool (Lang);\r
-  FreePool (LanguageString);\r
 \r
   HiiCreateOneOfOpCode (\r
     StartOpCodeHandle,\r
@@ -488,7 +514,7 @@ InitializeFrontPage (
 \r
   Status = HiiUpdateForm (\r
              HiiHandle,\r
-             &mFrontPageGuid,\r
+             &gFrontPageFormSetGuid,\r
              FRONT_PAGE_FORM_ID,\r
              StartOpCodeHandle, // LABEL_SELECT_LANGUAGE\r
              EndOpCodeHandle    // LABEL_END\r
@@ -528,7 +554,7 @@ CallFrontPage (
                             gFormBrowser2,\r
                             &gFrontPagePrivate.HiiHandle,\r
                             1,\r
-                            &mFrontPageGuid,\r
+                            &gFrontPageFormSetGuid,\r
                             0,\r
                             NULL,\r
                             &ActionRequest\r
@@ -603,10 +629,17 @@ ConvertProcessorToString (
 \r
   StringBuffer = AllocateZeroPool (0x20);\r
   ASSERT (StringBuffer != NULL);\r
-  Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
-  StrCat (StringBuffer, L".");\r
-  UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);\r
-  StrCat (StringBuffer, L" GHz");\r
+  UnicodeValueToStringS (StringBuffer, 0x20, LEFT_JUSTIFY, FreqMhz / 1000, 3);\r
+  Index = StrnLenS (StringBuffer, 0x20 / sizeof (CHAR16));\r
+  StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L".");\r
+  UnicodeValueToStringS (\r
+    StringBuffer + Index + 1,\r
+    0x20 - sizeof (CHAR16) * (Index + 1),\r
+    PREFIX_ZERO,\r
+    (FreqMhz % 1000) / 10,\r
+    2\r
+    );\r
+  StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L" GHz");\r
   *String = (CHAR16 *) StringBuffer;\r
   return ;\r
 }\r
@@ -629,8 +662,8 @@ ConvertMemorySizeToString (
 \r
   StringBuffer = AllocateZeroPool (0x20);\r
   ASSERT (StringBuffer != NULL);\r
-  UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);\r
-  StrCat (StringBuffer, L" MB RAM");\r
+  UnicodeValueToStringS (StringBuffer, 0x20, LEFT_JUSTIFY, MemorySize, 6);\r
+  StrCatS (StringBuffer, 0x20 / sizeof (CHAR16), L" MB RAM");\r
 \r
   *String = (CHAR16 *) StringBuffer;\r
 \r
@@ -656,51 +689,31 @@ GetOptionalStringByIndex (
   OUT     CHAR16                  **String\r
   )\r
 {\r
-  UINT8          StrNum;\r
-  UINTN          CurrentStrLen;\r
-  CHAR8*         CharInStr;\r
-  EFI_STATUS     Status;\r
+  UINTN          StrSize;\r
+\r
+  if (Index == 0) {\r
+    *String = AllocateZeroPool (sizeof (CHAR16));\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
-  StrNum        = 0;\r
-  Status        = EFI_NOT_FOUND;\r
-  CharInStr     = OptionalStrStart;\r
+  StrSize = 0;\r
+  do {\r
+    Index--;\r
+    OptionalStrStart += StrSize;\r
+    StrSize           = AsciiStrSize (OptionalStrStart);\r
+  } while (OptionalStrStart[StrSize] != 0 && Index != 0);\r
 \r
-  if (Index != 1) {\r
-    CurrentStrLen = 0;\r
+  if ((Index != 0) || (StrSize == 1)) {\r
     //\r
-    // look for the two consecutive zeros, check the string limit by the way.\r
+    // Meet the end of strings set but Index is non-zero, or\r
+    // Find an empty string\r
     //\r
-    while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
-      if (*CharInStr == 0) {\r
-        StrNum += 1;\r
-        CharInStr++;\r
-      }\r
-  \r
-      if (StrNum == Index) {\r
-        Status = EFI_SUCCESS;\r
-        break;\r
-      }\r
-  \r
-      CurrentStrLen = AsciiStrLen(CharInStr);\r
-  \r
-      //\r
-      // forward the pointer\r
-      //\r
-      OptionalStrStart = CharInStr;\r
-      CharInStr += CurrentStrLen;\r
-    }\r
-  \r
-    if (EFI_ERROR (Status)) {\r
-      *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
-      return Status;\r
-    }\r
+    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
   } else {\r
-    CurrentStrLen = AsciiStrLen(CharInStr);\r
+    *String = AllocatePool (StrSize * sizeof (CHAR16));\r
+    AsciiStrToUnicodeStrS (OptionalStrStart, *String, StrSize);\r
   }\r
 \r
-  *String = AllocatePool((CurrentStrLen + 1)*sizeof(CHAR16));\r
-  AsciiStrToUnicodeStr(OptionalStrStart, *String);\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -716,7 +729,6 @@ UpdateFrontPageStrings (
 {\r
   UINT8                             StrIndex;\r
   CHAR16                            *NewString;\r
-  BOOLEAN                           Find[5];\r
   EFI_STATUS                        Status;\r
   EFI_STRING_ID                     TokenToUpdate;\r
   EFI_SMBIOS_HANDLE                 SmbiosHandle;\r
@@ -726,8 +738,9 @@ UpdateFrontPageStrings (
   SMBIOS_TABLE_TYPE4                *Type4Record;\r
   SMBIOS_TABLE_TYPE19               *Type19Record;\r
   EFI_SMBIOS_TABLE_HEADER           *Record;\r
-\r
-  ZeroMem (Find, sizeof (Find));\r
+  UINT64                            InstalledMemory;\r
+  \r
+  InstalledMemory = 0;\r
 \r
   //\r
   // Update Front Page strings\r
@@ -737,66 +750,66 @@ UpdateFrontPageStrings (
                   NULL,\r
                   (VOID **) &Smbios\r
                   );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  SmbiosHandle = 0;\r
-  do {\r
+  if (!EFI_ERROR (Status)) {\r
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
     Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
-    if (EFI_ERROR(Status)) {\r
-      break;\r
-    }\r
+    while (!EFI_ERROR(Status)) {\r
+      if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {\r
+        Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
+        StrIndex = Type0Record->BiosVersion;\r
+        GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
+        TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
+        HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
+        FreePool (NewString);\r
+      }\r
 \r
-    if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {\r
-      Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;\r
-      StrIndex = Type0Record->BiosVersion;\r
-      GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);\r
-      TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);\r
-      HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
-      FreePool (NewString);\r
-      Find[0] = TRUE;\r
-    }  \r
+      if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
+        Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
+        StrIndex = Type1Record->ProductName;\r
+        GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
+        TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
+        HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
+        FreePool (NewString);\r
+      }\r
 \r
-    if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {\r
-      Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;\r
-      StrIndex = Type1Record->ProductName;\r
-      GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);\r
-      TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);\r
-      HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
-      FreePool (NewString);\r
-      Find[1] = TRUE;\r
-    }\r
-      \r
-    if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
-      Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
-      StrIndex = Type4Record->ProcessorVersion;\r
-      GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
-      TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
-      HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
-      FreePool (NewString);\r
-      Find[2] = TRUE;\r
-    }    \r
-\r
-    if (Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
-      Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
-      ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
-      TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
-      HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
-      FreePool (NewString);\r
-      Find[3] = TRUE;\r
-    } \r
-\r
-    if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
-      Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
-      ConvertMemorySizeToString (\r
-        (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)),\r
-        &NewString\r
-        );\r
-      TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
-      HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
-      FreePool (NewString);\r
-      Find[4] = TRUE;  \r
+      if (Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
+        Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
+        StrIndex = Type4Record->ProcessorVersion;\r
+        GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);\r
+        TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);\r
+        HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
+        FreePool (NewString);\r
+      }\r
+\r
+      if (Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) {\r
+        Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;\r
+        ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);\r
+        TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);\r
+        HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
+        FreePool (NewString);\r
+      }\r
+\r
+      if ( Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {\r
+        Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;\r
+        if (Type19Record->StartingAddress != 0xFFFFFFFF ) {\r
+          InstalledMemory += RShiftU64(Type19Record->EndingAddress -\r
+                                       Type19Record->StartingAddress + 1, 10);\r
+        } else {\r
+          InstalledMemory += RShiftU64(Type19Record->ExtendedEndingAddress -\r
+                                       Type19Record->ExtendedStartingAddress + 1, 20);\r
+        }\r
+      }\r
+\r
+      Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\r
     }\r
-  } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
+\r
+    // now update the total installed RAM size\r
+    ConvertMemorySizeToString ((UINT32)InstalledMemory, &NewString );\r
+    TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);\r
+    HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);\r
+    FreePool (NewString);\r
+  }\r
+\r
   return ;\r
 }\r
 \r
@@ -887,70 +900,79 @@ ShowProgress (
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
 \r
-  if (TimeoutDefault == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
+  if (TimeoutDefault != 0) {\r
+    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
 \r
-  SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
-  SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
-  SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
+    SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
+    SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
+    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);\r
+    \r
+    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
 \r
-  //\r
-  // Clear the progress status bar first\r
-  //\r
-  TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
-  if (TmpStr != NULL) {\r
-    PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
-  }\r
+    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
+      //\r
+      // Clear the progress status bar first\r
+      //\r
+      if (TmpStr != NULL) {\r
+        PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
+      }\r
+    }\r
+    \r
 \r
-  TimeoutRemain = TimeoutDefault;\r
-  while (TimeoutRemain != 0) {\r
-    DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
+    TimeoutRemain = TimeoutDefault;\r
+    while (TimeoutRemain != 0) {\r
+      DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
 \r
-    Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
-    if (Status != EFI_TIMEOUT) {\r
-      break;\r
+      Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
+      if (Status != EFI_TIMEOUT) {\r
+        break;\r
+      }\r
+      TimeoutRemain--;\r
+      \r
+      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {\r
+        //\r
+        // Show progress\r
+        //\r
+        if (TmpStr != NULL) {\r
+          PlatformBdsShowProgress (\r
+            Foreground,\r
+            Background,\r
+            TmpStr,\r
+            Color,\r
+            ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
+            0\r
+            );\r
+        }\r
+      }\r
+    }\r
+    \r
+    if (TmpStr != NULL) {\r
+      gBS->FreePool (TmpStr);\r
     }\r
-    TimeoutRemain--;\r
 \r
     //\r
-    // Show progress\r
+    // Timeout expired\r
     //\r
-    if (TmpStr != NULL) {\r
-      PlatformBdsShowProgress (\r
-        Foreground,\r
-        Background,\r
-        TmpStr,\r
-        Color,\r
-        ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),\r
-        0\r
-        );\r
+    if (TimeoutRemain == 0) {\r
+      return EFI_TIMEOUT;\r
     }\r
   }\r
-  gBS->FreePool (TmpStr);\r
-\r
-  //\r
-  // Timeout expired\r
-  //\r
-  if (TimeoutRemain == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
 \r
   //\r
   // User pressed some key\r
   //\r
-  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  if (!PcdGetBool (PcdConInConnectOnDemand)) {\r
+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-  if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
-    //\r
-    // User pressed enter, equivalent to select "continue"\r
-    //\r
-    return EFI_TIMEOUT;\r
+    if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+      //\r
+      // User pressed enter, equivalent to select "continue"\r
+      //\r
+      return EFI_TIMEOUT;\r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -974,7 +996,19 @@ PlatformBdsEnterFrontPage (
   IN BOOLEAN                      ConnectAllHappened\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
+  EFI_STATUS                         Status;\r
+  EFI_STATUS                         StatusHotkey; \r
+  EFI_BOOT_LOGO_PROTOCOL             *BootLogo;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL       *GraphicsOutput;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *SimpleTextOut;\r
+  UINTN                              BootTextColumn;\r
+  UINTN                              BootTextRow;\r
+  UINT64                             OsIndication;\r
+  UINTN                              DataSize;\r
+  EFI_INPUT_KEY                      Key;\r
+\r
+  GraphicsOutput = NULL;\r
+  SimpleTextOut = NULL;\r
 \r
   PERF_START (NULL, "BdsTimeOut", "BDS", 0);\r
   //\r
@@ -984,8 +1018,99 @@ PlatformBdsEnterFrontPage (
     gConnectAllHappened = TRUE;\r
   }\r
 \r
-  if (TimeoutDefault != 0xffff) {\r
-    Status = ShowProgress (TimeoutDefault);\r
+  if (!mModeInitialized) {\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
+      mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+      mBootVerticalResolution   = 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
+      mBootTextModeColumn = (UINT32)BootTextColumn;\r
+      mBootTextModeRow    = (UINT32)BootTextRow;\r
+    }\r
+\r
+    //\r
+    // Get user defined text mode for setup.\r
+    //  \r
+    mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
+    mSetupVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);      \r
+    mSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);\r
+    mSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);\r
+\r
+    mModeInitialized           = TRUE;\r
+  }\r
+\r
+\r
+  //\r
+  // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set\r
+  //\r
+  OsIndication = 0;\r
+  DataSize = sizeof(UINT64);\r
+  Status = gRT->GetVariable (\r
+                  L"OsIndications",\r
+                  &gEfiGlobalVariableGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &OsIndication\r
+                  );\r
+\r
+  //\r
+  // goto FrontPage directly when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot\r
+  //\r
+  if (!EFI_ERROR(Status) && ((OsIndication & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0)) {\r
+    //\r
+    // Clear EFI_OS_INDICATIONS_BOOT_TO_FW_UI to acknowledge OS\r
+    // \r
+    OsIndication &= ~((UINT64)EFI_OS_INDICATIONS_BOOT_TO_FW_UI);\r
+    Status = gRT->SetVariable (\r
+                    L"OsIndications",\r
+                    &gEfiGlobalVariableGuid,\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                    sizeof(UINT64),\r
+                    &OsIndication\r
+                    );\r
+    //\r
+    // Changing the content without increasing its size with current variable implementation shouldn't fail.\r
+    //\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Follow generic rule, Call ReadKeyStroke to connect ConIn before enter UI\r
+    //\r
+    if (PcdGetBool (PcdConInConnectOnDemand)) {\r
+      gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);\r
+    }\r
 \r
     //\r
     // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
@@ -993,16 +1118,52 @@ PlatformBdsEnterFrontPage (
     gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
     gST->ConOut->ClearScreen (gST->ConOut);\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      //\r
-      // Timeout or user press enter to continue\r
-      //\r
-      goto Exit;\r
+  } else {\r
+\r
+    HotkeyBoot ();\r
+    if (TimeoutDefault != 0xffff) {\r
+      Status = ShowProgress (TimeoutDefault);\r
+      StatusHotkey = HotkeyBoot ();\r
+\r
+      if (!FeaturePcdGet(PcdBootlogoOnlyEnable) || !EFI_ERROR(Status) || !EFI_ERROR(StatusHotkey)){\r
+        //\r
+        // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
+        // Skip it in normal boot \r
+        //\r
+        gST->ConOut->EnableCursor (gST->ConOut, TRUE);\r
+        gST->ConOut->ClearScreen (gST->ConOut);\r
+      }\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        //\r
+        // Timeout or user press enter to continue\r
+        //\r
+        goto Exit;\r
+      }\r
     }\r
   }\r
 \r
-  do {\r
+  //\r
+  // Boot Logo is corrupted, report it using Boot Logo protocol.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);\r
+  if (!EFI_ERROR (Status) && (BootLogo != NULL)) {\r
+    BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);\r
+  }\r
 \r
+  //\r
+  // Install BM HiiPackages. \r
+  // Keep BootMaint HiiPackage, so that it can be covered by global setting. \r
+  //\r
+  InitBMPackage ();\r
+\r
+  Status = EFI_SUCCESS;\r
+  do {\r
+    //\r
+    // Set proper video resolution and text mode for setup\r
+    //\r
+    BdsSetConsoleMode (TRUE);\r
+    \r
     InitializeFrontPage (FALSE);\r
 \r
     //\r
@@ -1011,7 +1172,7 @@ PlatformBdsEnterFrontPage (
     UpdateFrontPageStrings ();\r
 \r
     gCallbackKey = 0;\r
-    Status = CallFrontPage ();\r
+    CallFrontPage ();\r
 \r
     //\r
     // If gCallbackKey is greater than 1 and less or equal to 5,\r
@@ -1051,10 +1212,20 @@ PlatformBdsEnterFrontPage (
       break;\r
 \r
     case FRONT_PAGE_KEY_BOOT_MANAGER:\r
+      //\r
+      // Remove the installed BootMaint HiiPackages when exit.\r
+      //\r
+      FreeBMPackage ();\r
+\r
       //\r
       // User chose to run the Boot Manager\r
       //\r
       CallBootManager ();\r
+\r
+      //\r
+      // Reinstall BootMaint HiiPackages after exiting from Boot Manager.\r
+      //\r
+      InitBMPackage ();\r
       break;\r
 \r
     case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
@@ -1076,11 +1247,20 @@ PlatformBdsEnterFrontPage (
 \r
   } while ((Status == EFI_SUCCESS) && (gCallbackKey != FRONT_PAGE_KEY_CONTINUE));\r
 \r
+  if (mLanguageString != NULL) {\r
+    FreePool (mLanguageString);\r
+    mLanguageString = NULL;\r
+  }\r
   //\r
   //Will leave browser, check any reset required change is applied? if yes, reset system\r
   //\r
   SetupResetReminder ();\r
 \r
+  //\r
+  // Remove the installed BootMaint HiiPackages when exit.\r
+  //\r
+  FreeBMPackage ();\r
+\r
 Exit:\r
   //\r
   // Automatically load current entry\r
@@ -1089,3 +1269,219 @@ Exit:
   //\r
   PERF_END (NULL, "BdsTimeOut", "BDS", 0);\r
 }\r
+\r
+/**\r
+  This function will change video resolution and text mode\r
+  according to defined setup mode or defined boot mode  \r
+\r
+  @param  IsSetupMode   Indicate mode is changed to setup mode or boot mode. \r
+\r
+  @retval  EFI_SUCCESS  Mode is changed successfully.\r
+  @retval  Others             Mode failed to be changed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BdsSetConsoleMode (\r
+  BOOLEAN  IsSetupMode\r
+  )\r
+{\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *SimpleTextOut;\r
+  UINTN                                 SizeOfInfo;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;\r
+  UINT32                                MaxGopMode;\r
+  UINT32                                MaxTextMode;\r
+  UINT32                                ModeNumber;\r
+  UINT32                                NewHorizontalResolution;\r
+  UINT32                                NewVerticalResolution;\r
+  UINT32                                NewColumns;\r
+  UINT32                                NewRows;\r
+  UINTN                                 HandleCount;\r
+  EFI_HANDLE                            *HandleBuffer;\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 Index;\r
+  UINTN                                 CurrentColumn;\r
+  UINTN                                 CurrentRow;  \r
+\r
+  MaxGopMode  = 0;\r
+  MaxTextMode = 0;\r
+\r
+  //\r
+  // Get current video resolution and text mode \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) || (SimpleTextOut == NULL)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (IsSetupMode) {\r
+    //\r
+    // The required resolution and text mode is setup mode.\r
+    //\r
+    NewHorizontalResolution = mSetupHorizontalResolution;\r
+    NewVerticalResolution   = mSetupVerticalResolution;\r
+    NewColumns              = mSetupTextModeColumn;\r
+    NewRows                 = mSetupTextModeRow;\r
+  } else {\r
+    //\r
+    // The required resolution and text mode is boot mode.\r
+    //\r
+    NewHorizontalResolution = mBootHorizontalResolution;\r
+    NewVerticalResolution   = mBootVerticalResolution;\r
+    NewColumns              = mBootTextModeColumn;\r
+    NewRows                 = mBootTextModeRow;   \r
+  }\r
+  \r
+  if (GraphicsOutput != NULL) {\r
+    MaxGopMode  = GraphicsOutput->Mode->MaxMode;\r
+  } \r
+\r
+  if (SimpleTextOut != NULL) {\r
+    MaxTextMode = SimpleTextOut->Mode->MaxMode;\r
+  }\r
+\r
+  //\r
+  // 1. If current video resolution is same with required video resolution,\r
+  //    video resolution need not be changed.\r
+  //    1.1. If current text mode is same with required text mode, text mode need not be changed.\r
+  //    1.2. If current text mode is different from required text mode, text mode need be changed.\r
+  // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.\r
+  //\r
+  for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {\r
+    Status = GraphicsOutput->QueryMode (\r
+                       GraphicsOutput,\r
+                       ModeNumber,\r
+                       &SizeOfInfo,\r
+                       &Info\r
+                       );\r
+    if (!EFI_ERROR (Status)) {\r
+      if ((Info->HorizontalResolution == NewHorizontalResolution) &&\r
+          (Info->VerticalResolution == NewVerticalResolution)) {\r
+        if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&\r
+            (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {\r
+          //\r
+          // Current resolution is same with required resolution, check if text mode need be set\r
+          //\r
+          Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);\r
+          ASSERT_EFI_ERROR (Status);\r
+          if (CurrentColumn == NewColumns && CurrentRow == NewRows) {\r
+            //\r
+            // If current text mode is same with required text mode. Do nothing\r
+            //\r
+            FreePool (Info);\r
+            return EFI_SUCCESS;\r
+          } else {\r
+            //\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
+              if (!EFI_ERROR(Status)) {\r
+                if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {\r
+                  //\r
+                  // Required text mode is supported, set it.\r
+                  //\r
+                  Status = SimpleTextOut->SetMode (SimpleTextOut, Index);\r
+                  ASSERT_EFI_ERROR (Status);\r
+                  //\r
+                  // Update text mode PCD.\r
+                  //\r
+                  Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);\r
+                  ASSERT_EFI_ERROR (Status);\r
+                  Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);\r
+                  ASSERT_EFI_ERROR (Status);\r
+                  FreePool (Info);\r
+                  return EFI_SUCCESS;\r
+                }\r
+              }\r
+            }\r
+            if (Index == MaxTextMode) {\r
+              //\r
+              // If required text mode is not supported, return error.\r
+              //\r
+              FreePool (Info);\r
+              return EFI_UNSUPPORTED;\r
+            }\r
+          }\r
+        } else {\r
+          //\r
+          // If current video resolution is not same with the new one, set new video resolution.\r
+          // In this case, the driver which produces simple text out need be restarted.\r
+          //\r
+          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);\r
+          if (!EFI_ERROR (Status)) {\r
+            FreePool (Info);\r
+            break;\r
+          }\r
+        }\r
+      }\r
+      FreePool (Info);\r
+    }\r
+  }\r
+\r
+  if (ModeNumber == MaxGopMode) {\r
+    //\r
+    // If the resolution is not supported, return error.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Set PCD to Inform GraphicsConsole to change video resolution.\r
+  // Set PCD to Inform Consplitter to change text mode.\r
+  //\r
+  Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = PcdSet32S (PcdConOutColumn, NewColumns);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = PcdSet32S (PcdConOutRow, NewRows);\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  \r
+  //\r
+  // Video mode is changed, so restart graphics console driver and higher level driver.\r
+  // Reconnect graphics console driver and higher level driver.\r
+  // Locate all the handles with GOP protocol and reconnect it.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiSimpleTextOutProtocolGuid,\r
+                   NULL,\r
+                   &HandleCount,\r
+                   &HandleBuffer\r
+                   );\r
+  if (!EFI_ERROR (Status)) {\r
+    for (Index = 0; Index < HandleCount; Index++) {\r
+      gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
+    }\r
+    for (Index = 0; Index < HandleCount; Index++) {\r
+      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
+    }\r
+    if (HandleBuffer != NULL) {\r
+      FreePool (HandleBuffer);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r