]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
IntelFrameworkModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / FrontPage.c
index 5a3443bbe3b49d3bff72de6c46fec4981affd020..67f9371a9d34432c020f140fb492742b1a3e2df9 100644 (file)
@@ -1,30 +1,38 @@
 /** @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
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #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_HII_DATABASE_PROTOCOL       *gHiiDatabase;\r
-EFI_HII_STRING_PROTOCOL         *gHiiString;\r
 EFI_FORM_BROWSER2_PROTOCOL      *gFormBrowser2;\r
-EFI_HII_CONFIG_ROUTING_PROTOCOL *gHiiConfigRouting;\r
 \r
 FRONT_PAGE_CALLBACK_DATA  gFrontPagePrivate = {\r
   FRONT_PAGE_CALLBACK_DATA_SIGNATURE,\r
@@ -48,15 +56,12 @@ 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
     END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-    { \r
+    {\r
       (UINT8) (END_DEVICE_PATH_LENGTH),\r
       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
     }\r
@@ -81,7 +86,7 @@ HII_VENDOR_DEVICE_PATH  mFrontPageHiiVendorDevicePath = {
 \r
   @retval  EFI_SUCCESS            The Results is filled with the requested values.\r
   @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
-  @retval  EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.\r
+  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
   @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
 \r
 **/\r
@@ -94,7 +99,7 @@ FakeExtractConfig (
   OUT EFI_STRING                             *Results\r
   )\r
 {\r
-  if (Request == NULL || Progress == NULL || Results == NULL) {\r
+  if (Progress == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   *Progress = Request;\r
@@ -130,8 +135,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
@@ -168,118 +173,106 @@ 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
   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
-    \r
-    Index = 0;\r
-    LangCode = LanguageString;\r
-    while (*LangCode != 0) {\r
-      GetNextLanguage (&LangCode, Lang);\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
+    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
+      FreePool (Lang);\r
+      break;\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
+    default:\r
+      break;\r
     }\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
+  } 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
 }\r
 \r
@@ -299,21 +292,23 @@ 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
-  UINTN                       BufferSize;\r
   EFI_HII_HANDLE              HiiHandle;\r
   VOID                        *OptionsOpCodeHandle;\r
   VOID                        *StartOpCodeHandle;\r
   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
@@ -331,26 +326,11 @@ InitializeFrontPage (
     //\r
     // Locate Hii relative protocols\r
     //\r
-    Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gHiiString);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
     Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
 \r
-    Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &gHiiConfigRouting);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
     //\r
     // Install Device Path Protocol and Config Access protocol to driver handle\r
     //\r
@@ -368,7 +348,7 @@ InitializeFrontPage (
     // Publish our HII data\r
     //\r
     gFrontPagePrivate.HiiHandle = HiiAddPackages (\r
-                                    &mFrontPageGuid,\r
+                                    &gFrontPageFormSetGuid,\r
                                     gFrontPagePrivate.DriverHandle,\r
                                     FrontPageVfrBin,\r
                                     BdsDxeStrings,\r
@@ -409,89 +389,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
+  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
-  OptionCount = 0;\r
-  LangCode    = LanguageString;\r
-  FirstFlag   = FALSE;\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
-      //\r
-      // Get Language Name from String Package. The StringId of Printable Language\r
-      // Name is always 1 which is generated by StringGather Tool.\r
-      //\r
-      BufferSize = 0x100;\r
-      StringBuffer = AllocatePool (BufferSize);\r
-      Status = gHiiString->GetString (\r
-                           gHiiString,\r
-                           Lang,\r
-                           HiiHandle,\r
-                           PRINTABLE_LANGUAGE_NAME_STRING_ID,\r
-                           StringBuffer,\r
-                           &BufferSize,\r
-                           NULL\r
-                           );\r
+    LangCode     = mLanguageString;\r
+    OptionCount  = 0;\r
+    while (*LangCode != 0) {\r
+      GetNextLanguage (&LangCode, Lang);\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
-        FreePool (StringBuffer);\r
-        StringBuffer = AllocatePool (BufferSize);\r
-        Status = gHiiString->GetString (\r
-                             gHiiString,\r
-                             Lang,\r
-                             HiiHandle,\r
-                             PRINTABLE_LANGUAGE_NAME_STRING_ID,\r
-                             StringBuffer,\r
-                             &BufferSize,\r
-                             NULL\r
-                             );\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
-      ASSERT_EFI_ERROR (Status);\r
 \r
-      //\r
-      // Save the string Id for each language\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
@@ -515,9 +491,7 @@ InitializeFrontPage (
   if (CurrentLang != NULL) {\r
     FreePool (CurrentLang);\r
   }\r
-  FreePool (BestLanguage);\r
   FreePool (Lang);\r
-  FreePool (LanguageString);\r
 \r
   HiiCreateOneOfOpCode (\r
     StartOpCodeHandle,\r
@@ -534,7 +508,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
@@ -574,13 +548,13 @@ CallFrontPage (
                             gFormBrowser2,\r
                             &gFrontPagePrivate.HiiHandle,\r
                             1,\r
-                            &mFrontPageGuid,\r
+                            &gFrontPageFormSetGuid,\r
                             0,\r
                             NULL,\r
                             &ActionRequest\r
                             );\r
   //\r
-  // Check whether user  change any option setting which needs a reset to be effective\r
+  // Check whether user change any option setting which needs a reset to be effective\r
   //\r
   if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
     EnableResetRequired ();\r
@@ -589,56 +563,29 @@ CallFrontPage (
   return Status;\r
 }\r
 \r
-/**\r
-  Acquire the string associated with the ProducerGuid and return it.\r
-\r
-\r
-  @param ProducerGuid    The Guid to search the HII database for\r
-  @param Token           The token value of the string to extract\r
-  @param String          The string that is extracted\r
-\r
-  @retval  EFI_SUCCESS  The function returns EFI_SUCCESS always.\r
-\r
-**/\r
-EFI_STATUS\r
-GetProducerString (\r
-  IN      EFI_GUID                  *ProducerGuid,\r
-  IN      EFI_STRING_ID             Token,\r
-  OUT     CHAR16                    **String\r
-  )\r
-{\r
-  EFI_STRING      TmpString;\r
-\r
-  TmpString = HiiGetPackageString (ProducerGuid, Token, NULL);\r
-  if (TmpString == NULL) {\r
-    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
-  } else {\r
-    *String = TmpString;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
 \r
 /**\r
-  Convert Processor Frequency Data to a string\r
+  Convert Processor Frequency Data to a string.\r
 \r
   @param ProcessorFrequency The frequency data to process\r
+  @param Base10Exponent     The exponent based on 10\r
   @param String             The string that is created\r
 \r
 **/\r
 VOID\r
 ConvertProcessorToString (\r
-  IN  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,\r
-  OUT CHAR16                            **String\r
+  IN  UINT16                               ProcessorFrequency,\r
+  IN  UINT16                               Base10Exponent,\r
+  OUT CHAR16                               **String\r
   )\r
 {\r
   CHAR16  *StringBuffer;\r
   UINTN   Index;\r
   UINT32  FreqMhz;\r
 \r
-  if (ProcessorFrequency->Exponent >= 6) {\r
-    FreqMhz = ProcessorFrequency->Value;\r
-    for (Index = 0; Index < (UINTN) (ProcessorFrequency->Exponent - 6); Index++) {\r
+  if (Base10Exponent >= 6) {\r
+    FreqMhz = ProcessorFrequency;\r
+    for (Index = 0; Index < ((UINT32)Base10Exponent - 6); Index++) {\r
       FreqMhz *= 10;\r
     }\r
   } else {\r
@@ -647,16 +594,22 @@ 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
-\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
-\r
   return ;\r
 }\r
 \r
+\r
 /**\r
   Convert Memory Size to a string.\r
 \r
@@ -674,14 +627,62 @@ 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
   return ;\r
 }\r
 \r
+/**\r
+\r
+  Acquire the string associated with the Index from smbios structure and return it.\r
+  The caller is responsible for free the string buffer.\r
+\r
+  @param    OptionalStrStart  The start position to search the string\r
+  @param    Index             The index of the string to extract\r
+  @param    String            The string that is extracted\r
+\r
+  @retval   EFI_SUCCESS       The function returns EFI_SUCCESS always.\r
+\r
+**/\r
+EFI_STATUS\r
+GetOptionalStringByIndex (\r
+  IN      CHAR8                   *OptionalStrStart,\r
+  IN      UINT8                   Index,\r
+  OUT     CHAR16                  **String\r
+  )\r
+{\r
+  UINTN          StrSize;\r
+\r
+  if (Index == 0) {\r
+    *String = AllocateZeroPool (sizeof (CHAR16));\r
+    return EFI_SUCCESS;\r
+  }\r
+\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 != 0) || (StrSize == 1)) {\r
+    //\r
+    // Meet the end of strings set but Index is non-zero, or\r
+    // Find an empty string\r
+    //\r
+    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
+  } else {\r
+    *String = AllocatePool (StrSize * sizeof (CHAR16));\r
+    AsciiStrToUnicodeStrS (OptionalStrStart, *String, StrSize);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Update the banner information for the Front Page based on DataHub information.\r
 \r
@@ -691,106 +692,98 @@ UpdateFrontPageStrings (
   VOID\r
   )\r
 {\r
+  UINT8                             StrIndex;\r
+  CHAR16                            *NewString;\r
   EFI_STATUS                        Status;\r
   EFI_STRING_ID                     TokenToUpdate;\r
-  CHAR16                            *NewString;\r
-  UINT64                            MonotonicCount;\r
-  EFI_DATA_HUB_PROTOCOL             *DataHub;\r
-  EFI_DATA_RECORD_HEADER            *Record;\r
-  EFI_SUBCLASS_TYPE1_HEADER         *DataHeader;\r
-  EFI_MISC_BIOS_VENDOR_DATA         *BiosVendor;\r
-  EFI_MISC_SYSTEM_MANUFACTURER_DATA *SystemManufacturer;\r
-  EFI_PROCESSOR_VERSION_DATA        *ProcessorVersion;\r
-  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency;\r
-  EFI_MEMORY_ARRAY_START_ADDRESS_DATA    *MemoryArray;\r
-  BOOLEAN                           Find[5];\r
-\r
-  ZeroMem (Find, sizeof (Find));\r
+  EFI_SMBIOS_HANDLE                 SmbiosHandle;\r
+  EFI_SMBIOS_PROTOCOL               *Smbios;\r
+  SMBIOS_TABLE_TYPE0                *Type0Record;\r
+  SMBIOS_TABLE_TYPE1                *Type1Record;\r
+  SMBIOS_TABLE_TYPE4                *Type4Record;\r
+  SMBIOS_TABLE_TYPE19               *Type19Record;\r
+  EFI_SMBIOS_TABLE_HEADER           *Record;\r
+  UINT64                            InstalledMemory;\r
+\r
+  InstalledMemory = 0;\r
 \r
   //\r
   // Update Front Page strings\r
   //\r
   Status = gBS->LocateProtocol (\r
-                  &gEfiDataHubProtocolGuid,\r
+                  &gEfiSmbiosProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &DataHub\r
+                  (VOID **) &Smbios\r
                   );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  MonotonicCount  = 0;\r
-  Record          = NULL;\r
-  do {\r
-    Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);\r
-    if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {\r
-      DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);\r
-      if (CompareGuid (&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&\r
-          (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)\r
-          ) {\r
-        BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);\r
-        GetProducerString (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);\r
+  if (!EFI_ERROR (Status)) {\r
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+    Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);\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
-        Find[0] = TRUE;\r
       }\r
 \r
-      if (CompareGuid (&Record->DataRecordGuid, &gEfiMiscSubClassGuid) &&\r
-          (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)\r
-          ) {\r
-        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);\r
-        GetProducerString (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);\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
-        Find[1] = TRUE;\r
       }\r
 \r
-      if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&\r
-          (DataHeader->RecordType == ProcessorVersionRecordType)\r
-          ) {\r
-        ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);\r
-        GetProducerString (&Record->ProducerName, *ProcessorVersion, &NewString);\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
-        Find[2] = TRUE;\r
       }\r
 \r
-      if (CompareGuid (&Record->DataRecordGuid, &gEfiProcessorSubClassGuid) &&\r
-          (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)\r
-          ) {\r
-        ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);\r
-        ConvertProcessorToString (ProcessorFrequency, &NewString);\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
-        Find[3] = TRUE;\r
       }\r
 \r
-      if (CompareGuid (&Record->DataRecordGuid, &gEfiMemorySubClassGuid) &&\r
-          (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)\r
-          ) {\r
-        MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);\r
-        ConvertMemorySizeToString (\r
-          (UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - MemoryArray->MemoryArrayStartAddress + 1), 20)),\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_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 (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(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
+\r
 /**\r
   Function waits for a given event to fire, or for an optional timeout to expire.\r
 \r
-  @param Event              The event to wait for\r
-  @param Timeout            An optional timeout value in 100 ns units.\r
+  @param   Event              The event to wait for\r
+  @param   Timeout            An optional timeout value in 100 ns units.\r
 \r
   @retval  EFI_SUCCESS      Event fired before Timeout expired.\r
   @retval  EFI_TIME_OUT     Timout expired before Event fired..\r
@@ -802,8 +795,8 @@ WaitForSingleEvent (
   IN UINT64                     Timeout OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
   UINTN       Index;\r
+  EFI_STATUS  Status;\r
   EFI_EVENT   TimerEvent;\r
   EFI_EVENT   WaitList[2];\r
 \r
@@ -817,10 +810,10 @@ WaitForSingleEvent (
       // Set the timer event\r
       //\r
       gBS->SetTimer (\r
-            TimerEvent,\r
-            TimerRelative,\r
-            Timeout\r
-            );\r
+             TimerEvent,\r
+             TimerRelative,\r
+             Timeout\r
+             );\r
 \r
       //\r
       // Wait for the original event or the timer\r
@@ -853,10 +846,10 @@ WaitForSingleEvent (
   Function show progress bar to wait for user input.\r
 \r
 \r
-  @param TimeoutDefault  The fault time out value before the system continue to boot.\r
+  @param   TimeoutDefault  The fault time out value before the system continue to boot.\r
 \r
   @retval  EFI_SUCCESS       User pressed some key except "Enter"\r
-  @retval  EFI_TIME_OUT      Timout expired or user press "Enter"\r
+  @retval  EFI_TIME_OUT      Timeout expired or user press "Enter"\r
 \r
 **/\r
 EFI_STATUS\r
@@ -864,78 +857,87 @@ ShowProgress (
   IN UINT16                       TimeoutDefault\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
   CHAR16                        *TmpStr;\r
+  UINT16                        TimeoutRemain;\r
+  EFI_STATUS                    Status;\r
+  EFI_INPUT_KEY                 Key;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
   EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\r
-  EFI_INPUT_KEY                 Key;\r
-  UINT16                        TimeoutRemain;\r
 \r
-  if (TimeoutDefault == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
+  if (TimeoutDefault != 0) {\r
+    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));\r
 \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
-  //\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
+    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
 \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
+    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
+\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
-    TimeoutRemain--;\r
 \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
+      gBS->FreePool (TmpStr);\r
     }\r
-  }\r
-  gBS->FreePool (TmpStr);\r
 \r
-  //\r
-  // Timeout expired\r
-  //\r
-  if (TimeoutRemain == 0) {\r
-    return EFI_TIMEOUT;\r
+    //\r
+    // Timeout expired\r
+    //\r
+    if (TimeoutRemain == 0) {\r
+      return EFI_TIMEOUT;\r
+    }\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
@@ -950,7 +952,7 @@ ShowProgress (
   @param TimeoutDefault     The fault time out value before the system\r
                             continue to boot.\r
   @param ConnectAllHappened The indicater to check if the connect all have\r
-                            already happended.\r
+                            already happened.\r
 \r
 **/\r
 VOID\r
@@ -959,9 +961,21 @@ PlatformBdsEnterFrontPage (
   IN BOOLEAN                      ConnectAllHappened\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-\r
-  PERF_START (0, "BdsTimeOut", "BDS", 0);\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
   // Indicate if we need connect all in the platform setup\r
   //\r
@@ -969,8 +983,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
@@ -978,15 +1083,51 @@ 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
+  //\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
@@ -996,15 +1137,15 @@ 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
-    // it will lauch configuration utilities.\r
+    // it will launch configuration utilities.\r
     // 2 = set language\r
     // 3 = boot manager\r
     // 4 = device manager\r
-    // 5 = boot maintainenance manager\r
+    // 5 = boot maintenance manager\r
     //\r
     if (gCallbackKey != 0) {\r
       REPORT_STATUS_CODE (\r
@@ -1036,10 +1177,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
@@ -1047,7 +1198,7 @@ PlatformBdsEnterFrontPage (
       // Display the Device Manager\r
       //\r
       do {\r
-        CallDeviceManager();\r
+        CallDeviceManager ();\r
       } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
       break;\r
 \r
@@ -1061,16 +1212,241 @@ 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
   // Note: The following lines of code only execute when Auto boot\r
   // takes affect\r
   //\r
-  PERF_END (0, "BdsTimeOut", "BDS", 0);\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