]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkUnixPkg/Dxe/PlatformBds/Generic/FrontPage.c
Unix version of EFI emulator
[mirror_edk2.git] / EdkUnixPkg / Dxe / PlatformBds / Generic / FrontPage.c
diff --git a/EdkUnixPkg/Dxe/PlatformBds/Generic/FrontPage.c b/EdkUnixPkg/Dxe/PlatformBds/Generic/FrontPage.c
new file mode 100644 (file)
index 0000000..a31e8a9
--- /dev/null
@@ -0,0 +1,901 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \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
+\r
+Module Name:\r
+\r
+  FrontPage.c\r
+\r
+Abstract:\r
+\r
+  FrontPage routines to handle the callbacks and browser calls\r
+  \r
+--*/\r
+\r
+#include "Bds.h"\r
+#include "BdsPlatform.h"\r
+#include "FrontPage.h"\r
+#include "String.h"\r
+\r
+EFI_GUID                    mProcessorSubClass  = EFI_PROCESSOR_SUBCLASS_GUID;\r
+EFI_GUID                    mMemorySubClass     = EFI_MEMORY_SUBCLASS_GUID;\r
+EFI_GUID                    mMiscSubClass       = EFI_MISC_SUBCLASS_GUID;\r
+\r
+UINT16                      mLastSelection;\r
+EFI_HII_HANDLE              gFrontPageHandle;\r
+EFI_HANDLE                  FrontPageCallbackHandle;\r
+EFI_FORM_CALLBACK_PROTOCOL  FrontPageCallback;\r
+EFI_FORM_BROWSER_PROTOCOL   *gBrowser;\r
+UINTN                       gCallbackKey;\r
+BOOLEAN                     gConnectAllHappened = FALSE;\r
+\r
+extern EFI_HII_HANDLE       gFrontPageHandle;\r
+extern EFI_GUID             gBdsStringPackGuid;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FrontPageCallbackRoutine (\r
+  IN EFI_FORM_CALLBACK_PROTOCOL       *This,\r
+  IN UINT16                           KeyValue,\r
+  IN EFI_IFR_DATA_ARRAY               *DataArray,\r
+  OUT EFI_HII_CALLBACK_PACKET         **Packet\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the function that is called to provide results data to the driver.  This data\r
+  consists of a unique key which is used to identify what data is either being passed back\r
+  or being asked for. \r
+\r
+Arguments:\r
+\r
+  KeyValue -        A unique value which is sent to the original exporting driver so that it\r
+                    can identify the type of data to expect.  The format of the data tends to\r
+                    vary based on the op-code that geerated the callback.\r
+\r
+  Data -            A pointer to the data being sent to the original exporting driver.\r
+\r
+Returns: \r
+\r
+--*/\r
+{\r
+  CHAR16        *LanguageString;\r
+  UINTN         Count;\r
+  CHAR16        UnicodeLang[3];\r
+  CHAR8         Lang[3];\r
+  EFI_STATUS    Status;\r
+  UINTN         Index;\r
+  CHAR16        *TmpStr;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;\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
+\r
+  Count = 0;\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 (KeyValue) {\r
+  case 0x0001:\r
+    //\r
+    // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
+    //\r
+    gCallbackKey = 1;\r
+    break;\r
+\r
+  case 0x1234:\r
+    //\r
+    // Collect the languages from what our current Language support is based on our VFR\r
+    //\r
+    Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);\r
+\r
+    //\r
+    // Based on the DataArray->Data->Data value, we can determine\r
+    // which language was chosen by the user\r
+    //\r
+    for (Index = 0; Count != (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray + 1))->Data); Index += 3) {\r
+      Count++;\r
+    }\r
+    //\r
+    // Preserve the choice the user made\r
+    //\r
+    mLastSelection = (UINT16) Count;\r
+\r
+    //\r
+    // The Language (in Unicode format) the user chose\r
+    //\r
+    CopyMem (UnicodeLang, &LanguageString[Index], 6);\r
+\r
+    //\r
+    // Convert Unicode to ASCII (Since the ISO standard assumes ASCII equivalent abbreviations\r
+    // we can be safe in converting this Unicode stream to ASCII without any loss in meaning.\r
+    //\r
+    for (Index = 0; Index < 3; Index++) {\r
+      Lang[Index] = (CHAR8) UnicodeLang[Index];\r
+    }\r
+\r
+    Status = gRT->SetVariable (\r
+                    L"Lang",\r
+                    &gEfiGlobalVariableGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+                    3,\r
+                    Lang\r
+                    );\r
+\r
+    gBS->FreePool (LanguageString);\r
+    gCallbackKey = 2;\r
+    break;\r
+\r
+  case 0x1064:\r
+    //\r
+    // Boot Manager\r
+    //\r
+    gCallbackKey = 3;\r
+    break;\r
+\r
+  case 0x8567:\r
+    //\r
+    // Device Manager\r
+    //\r
+    gCallbackKey = 4;\r
+    break;\r
+\r
+  case 0x9876:\r
+    //\r
+    // Boot Maintenance Manager\r
+    //\r
+    gCallbackKey = 5;\r
+    break;\r
+\r
+  case 0xFFFE:\r
+\r
+    break;\r
+\r
+  case 0xFFFF:\r
+    //\r
+    // FrontPage TimeOut Callback\r
+    //\r
+    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));\r
+    if (TmpStr != NULL) {\r
+      PlatformBdsShowProgress (\r
+        Foreground,\r
+        Background,\r
+        TmpStr,\r
+        Color,\r
+        (UINTN) (((EFI_IFR_DATA_ENTRY *) (DataArray+1))->Data),\r
+        0\r
+        );\r
+      gBS->FreePool (TmpStr);\r
+    }\r
+    break;\r
+\r
+  default:\r
+    gCallbackKey = 0;\r
+    break;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+InitializeFrontPage (\r
+  BOOLEAN                         ReInitializeStrings\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Initialize HII information for the FrontPage\r
+\r
+Arguments:\r
+  None\r
+            \r
+Returns:\r
+  EFI_SUCCESS       - The operation is successful.\r
+  EFI_DEVICE_ERROR  - If the dynamic opcode creation failed.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_HII_PACKAGES    *PackageList;\r
+  EFI_HII_UPDATE_DATA *UpdateData;\r
+  IFR_OPTION          *OptionList;\r
+  CHAR16              *LanguageString;\r
+  UINTN               OptionCount;\r
+  UINTN               Index;\r
+  STRING_REF          Token;\r
+  UINT16              Key;\r
+  CHAR8               AsciiLang[4];\r
+  CHAR16              UnicodeLang[4];\r
+  CHAR16              Lang[4];\r
+  CHAR16              *StringBuffer;\r
+  UINTN               BufferSize;\r
+  UINT8               *TempBuffer;\r
+\r
+  UpdateData  = NULL;\r
+  OptionList  = NULL;\r
+\r
+  if (ReInitializeStrings) {\r
+    //\r
+    // BugBug: Dont' use a goto\r
+    //\r
+    goto ReInitStrings;\r
+  }\r
+  //\r
+  // Go ahead and initialize the Device Manager\r
+  //\r
+  InitializeDeviceManager ();\r
+\r
+  //\r
+  // BugBug: if FrontPageVfrBin is generated by a tool, why are we patching it here\r
+  //\r
+  TempBuffer    = (UINT8 *) FrontPageVfrBin;\r
+  TempBuffer    = TempBuffer + sizeof (EFI_HII_PACK_HEADER);\r
+  TempBuffer    = (UINT8 *) &((EFI_IFR_FORM_SET *) TempBuffer)->NvDataSize;\r
+  *TempBuffer   = 1;\r
+\r
+  gCallbackKey  = 0;\r
+\r
+  PackageList   = PreparePackages (1, &gBdsStringPackGuid, FrontPageVfrBin);\r
+\r
+  Status        = Hii->NewPack (Hii, PackageList, &gFrontPageHandle);\r
+\r
+  gBS->FreePool (PackageList);\r
+\r
+  //\r
+  // There will be only one FormConfig in the system\r
+  // If there is another out there, someone is trying to install us\r
+  // again.  Fail that scenario.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiFormBrowserProtocolGuid,\r
+                  NULL,\r
+                  &gBrowser\r
+                  );\r
+\r
+  //\r
+  // This example does not implement worker functions\r
+  // for the NV accessor functions.  Only a callback evaluator\r
+  //\r
+  FrontPageCallback.NvRead    = NULL;\r
+  FrontPageCallback.NvWrite   = NULL;\r
+  FrontPageCallback.Callback  = FrontPageCallbackRoutine;\r
+\r
+  //\r
+  // Install protocol interface\r
+  //\r
+  FrontPageCallbackHandle = NULL;\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &FrontPageCallbackHandle,\r
+                  &gEfiFormCallbackProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &FrontPageCallback\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+ReInitStrings:\r
+  //\r
+  // BugBug: This logic is in BdsInitLanguage. It should not be in two places!\r
+  //\r
+  BufferSize = 4;\r
+  Status = gRT->GetVariable (\r
+                  L"Lang",\r
+                  &gEfiGlobalVariableGuid,\r
+                  NULL,\r
+                  &BufferSize,\r
+                  AsciiLang\r
+                  );\r
+\r
+  for (Index = 0; Index < 3; Index++) {\r
+    UnicodeLang[Index] = (CHAR16) AsciiLang[Index];\r
+  }\r
+\r
+  UnicodeLang[3] = 0;\r
+\r
+  //\r
+  // Allocate space for creation of UpdateData Buffer\r
+  //\r
+  UpdateData = AllocateZeroPool (0x1000);\r
+  ASSERT (UpdateData != NULL);\r
+\r
+  OptionList = AllocateZeroPool (0x1000);\r
+  ASSERT (OptionList != NULL);\r
+\r
+  //\r
+  // Flag update pending in FormSet\r
+  //\r
+  UpdateData->FormSetUpdate = TRUE;\r
+  //\r
+  // Register CallbackHandle data for FormSet\r
+  //\r
+  UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) FrontPageCallbackHandle;\r
+  UpdateData->FormUpdate  = FALSE;\r
+  UpdateData->FormTitle   = 0;\r
+  UpdateData->DataCount   = 1;\r
+\r
+  //\r
+  // Collect the languages from what our current Language support is based on our VFR\r
+  //\r
+  Hii->GetPrimaryLanguages (Hii, gFrontPageHandle, &LanguageString);\r
+\r
+  OptionCount = 0;\r
+\r
+  //\r
+  // Try for a 512 byte Buffer\r
+  //\r
+  BufferSize = 0x200;\r
+\r
+  //\r
+  // Allocate memory for our Form binary\r
+  //\r
+  StringBuffer = AllocateZeroPool (BufferSize);\r
+  ASSERT (StringBuffer != NULL);\r
+\r
+  for (Index = 0; LanguageString[Index] != 0; Index += 3) {\r
+    Token = 0;\r
+    CopyMem (Lang, &LanguageString[Index], 6);\r
+    Lang[3] = 0;\r
+\r
+    if (!StrCmp (Lang, UnicodeLang)) {\r
+      mLastSelection = (UINT16) OptionCount;\r
+    }\r
+\r
+    Status = Hii->GetString (Hii, gStringPackHandle, 1, TRUE, Lang, &BufferSize, StringBuffer);\r
+    Hii->NewString (Hii, NULL, gStringPackHandle, &Token, StringBuffer);\r
+    CopyMem (&OptionList[OptionCount].StringToken, &Token, sizeof (UINT16));\r
+    CopyMem (&OptionList[OptionCount].Value, &OptionCount, sizeof (UINT16));\r
+    Key = 0x1234;\r
+    CopyMem (&OptionList[OptionCount].Key, &Key, sizeof (UINT16));\r
+    OptionList[OptionCount].Flags = EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS;\r
+    OptionCount++;\r
+  }\r
+\r
+  gBS->FreePool (LanguageString);\r
+\r
+  if (ReInitializeStrings) {\r
+    gBS->FreePool (StringBuffer);\r
+    gBS->FreePool (OptionList);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = CreateOneOfOpCode (\r
+            FRONT_PAGE_QUESTION_ID,                               // Question ID\r
+            FRONT_PAGE_DATA_WIDTH,                                // Data Width\r
+            (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT),      // Prompt Token\r
+            (STRING_REF) STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), // Help Token\r
+            OptionList,       // List of Options\r
+            OptionCount,      // Number of Options\r
+            &UpdateData->Data // Data Buffer\r
+            );\r
+\r
+  //\r
+  // Assign the number of options and the oneof and endoneof op-codes to count\r
+  //\r
+  UpdateData->DataCount = (UINT8) (OptionCount + 2);\r
+\r
+  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0x0002, TRUE, UpdateData);\r
+\r
+  gBS->FreePool (UpdateData);\r
+  //\r
+  // gBS->FreePool (OptionList);\r
+  //\r
+  gBS->FreePool (StringBuffer);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CallFrontPage (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Call the browser and display the front page\r
+\r
+Arguments:\r
+  \r
+  None\r
+  \r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       FakeNvRamMap[1];\r
+  BOOLEAN     FrontPageMenuResetRequired;\r
+\r
+  //\r
+  // Begin waiting for USER INPUT\r
+  //\r
+  REPORT_STATUS_CODE (\r
+        EFI_PROGRESS_CODE,\r
+        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)\r
+        );\r
+\r
+  FakeNvRamMap[0] = (UINT8) mLastSelection;\r
+  FrontPageMenuResetRequired = FALSE;\r
+  Status = gBrowser->SendForm (\r
+                      gBrowser,\r
+                      TRUE,                     // Use the database\r
+                      &gFrontPageHandle,        // The HII Handle\r
+                      1,\r
+                      NULL,\r
+                      FrontPageCallbackHandle,  // This is the handle that the interface to the callback was installed on\r
+                      FakeNvRamMap,\r
+                      NULL,\r
+                      &FrontPageMenuResetRequired\r
+                      );\r
+  //\r
+  // Check whether user change any option setting which needs a reset to be effective\r
+  //                      \r
+  if (FrontPageMenuResetRequired) {\r
+    EnableResetRequired ();\r
+  }\r
+\r
+  Hii->ResetStrings (Hii, gFrontPageHandle);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+GetStringFromToken (\r
+  IN      EFI_GUID                  *ProducerGuid,\r
+  IN      STRING_REF                Token,\r
+  OUT     CHAR16                    **String\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Acquire the string associated with the ProducerGuid and return it.\r
+\r
+Arguments:\r
+  \r
+  ProducerGuid - The Guid to search the HII database for\r
+  Token - The token value of the string to extract\r
+  String - The string that is extracted\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS - The function returns EFI_SUCCESS always.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS      Status;\r
+  UINT16          HandleBufferLength;\r
+  EFI_HII_HANDLE  *HiiHandleBuffer;\r
+  UINTN           StringBufferLength;\r
+  UINTN           NumberOfHiiHandles;\r
+  UINTN           Index;\r
+  UINT16          Length;\r
+  EFI_GUID        HiiGuid;\r
+\r
+  HandleBufferLength  = 0x1000;\r
+  HiiHandleBuffer     = NULL;\r
+\r
+  //\r
+  // Get all the Hii handles\r
+  //\r
+  HiiHandleBuffer = AllocateZeroPool (HandleBufferLength);\r
+\r
+  Status          = Hii->FindHandles (Hii, &HandleBufferLength, HiiHandleBuffer);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Get the Hii Handle that matches the StructureNode->ProducerName\r
+  //\r
+  NumberOfHiiHandles = HandleBufferLength / sizeof (EFI_HII_HANDLE);\r
+  for (Index = 0; Index < NumberOfHiiHandles; Index++) {\r
+    Length = 0;\r
+    Status = ExtractDataFromHiiHandle (\r
+              HiiHandleBuffer[Index],\r
+              &Length,\r
+              NULL,\r
+              &HiiGuid\r
+              );\r
+    if (CompareGuid (ProducerGuid, &HiiGuid)) {\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // Find the string based on the current language\r
+  //\r
+  StringBufferLength  = 0x100;\r
+  *String             = AllocateZeroPool (0x100);\r
+  Status = Hii->GetString (\r
+                  Hii,\r
+                  HiiHandleBuffer[Index],\r
+                  Token,\r
+                  FALSE,\r
+                  NULL,\r
+                  &StringBufferLength,\r
+                  *String\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (*String);\r
+    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));\r
+  }\r
+\r
+  gBS->FreePool (HiiHandleBuffer);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+ConvertProcessorToString (\r
+  IN  EFI_PROCESSOR_CORE_FREQUENCY_DATA *ProcessorFrequency,\r
+  OUT CHAR16                            **String\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Convert Processor Frequency Data to a string\r
+\r
+Arguments:\r
+  \r
+  ProcessorFrequency - The frequency data to process\r
+  String - The string that is created\r
+  \r
+Returns:\r
+\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
+      FreqMhz *= 10;\r
+    }\r
+  } else {\r
+    FreqMhz = 0;\r
+  }\r
+\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
+  *String = (CHAR16 *) StringBuffer;\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+ConvertMemorySizeToString (\r
+  IN  UINT32          MemorySize,\r
+  OUT CHAR16          **String\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Convert Memory Size to a string\r
+\r
+Arguments:\r
+  \r
+  MemorySize - The size of the memory to process\r
+  String - The string that is created\r
+  \r
+Returns:\r
+\r
+--*/\r
+{\r
+  CHAR16  *StringBuffer;\r
+\r
+  StringBuffer = AllocateZeroPool (0x20);\r
+  ASSERT (StringBuffer != NULL);\r
+  UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 6);\r
+  StrCat (StringBuffer, L" MB RAM");\r
+\r
+  *String = (CHAR16 *) StringBuffer;\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+UpdateFrontPageStrings (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Update the banner information for the Front Page based on DataHub information\r
+\r
+Arguments:\r
+  \r
+  None\r
+  \r
+Returns:\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                        Status;\r
+  STRING_REF                        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
+  CHAR8                             LangCode[3];\r
+  CHAR16                            Lang[3];\r
+  UINTN                             Size;\r
+  UINTN                             Index;\r
+  BOOLEAN                           Find[5];\r
+\r
+  ZeroMem (Find, sizeof (Find));\r
+\r
+  //\r
+  // Update Front Page strings\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDataHubProtocolGuid,\r
+                  NULL,\r
+                  &DataHub\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Size = 3;\r
+\r
+  Status = gRT->GetVariable (\r
+                  L"Lang",\r
+                  &gEfiGlobalVariableGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  LangCode\r
+                  );\r
+\r
+  for (Index = 0; Index < 3; Index++) {\r
+    Lang[Index] = (CHAR16) LangCode[Index];\r
+  }\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, &mMiscSubClass) &&\r
+          (DataHeader->RecordType == EFI_MISC_BIOS_VENDOR_RECORD_NUMBER)\r
+          ) {\r
+        BiosVendor = (EFI_MISC_BIOS_VENDOR_DATA *) (DataHeader + 1);\r
+        GetStringFromToken (&Record->ProducerName, BiosVendor->BiosVersion, &NewString);\r
+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_BIOS_VERSION;\r
+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
+        gBS->FreePool (NewString);\r
+        Find[0] = TRUE;\r
+      }\r
+\r
+      if (CompareGuid (&Record->DataRecordGuid, &mMiscSubClass) &&\r
+          (DataHeader->RecordType == EFI_MISC_SYSTEM_MANUFACTURER_RECORD_NUMBER)\r
+          ) {\r
+        SystemManufacturer = (EFI_MISC_SYSTEM_MANUFACTURER_DATA *) (DataHeader + 1);\r
+        GetStringFromToken (&Record->ProducerName, SystemManufacturer->SystemProductName, &NewString);\r
+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_COMPUTER_MODEL;\r
+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
+        gBS->FreePool (NewString);\r
+        Find[1] = TRUE;\r
+      }\r
+\r
+      if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&\r
+          (DataHeader->RecordType == ProcessorVersionRecordType)\r
+          ) {\r
+        ProcessorVersion = (EFI_PROCESSOR_VERSION_DATA *) (DataHeader + 1);\r
+        GetStringFromToken (&Record->ProducerName, *ProcessorVersion, &NewString);\r
+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_MODEL;\r
+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
+        gBS->FreePool (NewString);\r
+        Find[2] = TRUE;\r
+      }\r
+\r
+      if (CompareGuid (&Record->DataRecordGuid, &mProcessorSubClass) &&\r
+          (DataHeader->RecordType == ProcessorCoreFrequencyRecordType)\r
+          ) {\r
+        ProcessorFrequency = (EFI_PROCESSOR_CORE_FREQUENCY_DATA *) (DataHeader + 1);\r
+        ConvertProcessorToString (ProcessorFrequency, &NewString);\r
+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_CPU_SPEED;\r
+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
+        gBS->FreePool (NewString);\r
+        Find[3] = TRUE;\r
+      }\r
+\r
+      if (CompareGuid (&Record->DataRecordGuid, &mMemorySubClass) &&\r
+          (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)\r
+          ) {\r
+        MemoryArray = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) (DataHeader + 1);\r
+        ConvertMemorySizeToString((UINT32)(RShiftU64((MemoryArray->MemoryArrayEndAddress - \r
+                                  MemoryArray->MemoryArrayStartAddress + 1), 20)),\r
+                                  &NewString);\r
+        TokenToUpdate = (STRING_REF) STR_FRONT_PAGE_MEMORY_SIZE;\r
+        Hii->NewString (Hii, Lang, gFrontPageHandle, &TokenToUpdate, NewString);\r
+        gBS->FreePool (NewString);\r
+        Find[4] = TRUE;\r
+      }\r
+    }\r
+  } while (!EFI_ERROR (Status) && (MonotonicCount != 0) && !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+PlatformBdsEnterFrontPage (\r
+  IN UINT16                       TimeoutDefault,\r
+  IN BOOLEAN                      ConnectAllHappened\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  This function is the main entry of the platform setup entry.\r
+  The function will present the main menu of the system setup, \r
+  this is the platform reference part and can be customize.\r
+  \r
+Arguments:\r
+  TimeoutDefault     - The fault time out value before the system\r
+                       continue to boot.\r
+  ConnectAllHappened - The indicater to check if the connect all have\r
+                       already happended.\r
+  \r
+Returns:\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HII_UPDATE_DATA           *UpdateData;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+\r
+  //\r
+  // Indicate if we need connect all in the platform setup\r
+  //\r
+  if (ConnectAllHappened) {\r
+    gConnectAllHappened = TRUE;\r
+  }\r
+  //\r
+  // Allocate space for creation of Buffer\r
+  //\r
+  UpdateData = AllocateZeroPool (0x1000);\r
+  ASSERT (UpdateData != NULL);\r
+\r
+  UpdateData->FormSetUpdate       = FALSE;\r
+  UpdateData->FormCallbackHandle  = 0;\r
+  UpdateData->FormUpdate          = FALSE;\r
+  UpdateData->FormTitle           = 0;\r
+  UpdateData->DataCount           = 1;\r
+\r
+  //\r
+  // Remove Banner Op-code if any at this label\r
+  //\r
+  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, FALSE, UpdateData);\r
+\r
+  //\r
+  // Create Banner Op-code which reflects correct timeout value\r
+  //\r
+  CreateBannerOpCode (\r
+    STRING_TOKEN (STR_TIME_OUT_PROMPT),\r
+    TimeoutDefault,\r
+    (UINT8) EFI_IFR_BANNER_TIMEOUT,\r
+    &UpdateData->Data\r
+    );\r
+\r
+  //\r
+  // Add Banner Op-code at this label\r
+  //\r
+  Hii->UpdateForm (Hii, gFrontPageHandle, (EFI_FORM_LABEL) 0xFFFF, TRUE, UpdateData);\r
+\r
+  do {\r
+\r
+    InitializeFrontPage (TRUE);\r
+\r
+    //\r
+    // Update Front Page strings\r
+    //\r
+    UpdateFrontPageStrings ();\r
+\r
+    gCallbackKey = 0;\r
+    PERF_START (0, "BdsTimeOut", "BDS", 0);\r
+    Status = CallFrontPage ();\r
+    PERF_END (0, "BdsTimeOut", "BDS", 0);\r
+\r
+    //\r
+    // If gCallbackKey is greater than 1 and less or equal to 5,\r
+    // it will lauch configuration utilities.\r
+    // 2 = set language\r
+    // 3 = boot manager\r
+    // 4 = device manager\r
+    // 5 = boot maintainenance manager\r
+    //\r
+    if ((gCallbackKey > 0x0001) && (gCallbackKey <= 0x0005)) {\r
+      REPORT_STATUS_CODE (\r
+            EFI_PROGRESS_CODE,\r
+            (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
+            );\r
+    }\r
+    //\r
+    // Based on the key that was set, we can determine what to do\r
+    //\r
+    switch (gCallbackKey) {\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
+    // These entries consist of the Continue, Select language, Boot Manager, and Device Manager\r
+    //\r
+    case 0x0001:\r
+      //\r
+      // User hit continue\r
+      //\r
+      break;\r
+\r
+    case 0x0002:\r
+      //\r
+      // User made a language setting change - display front page again\r
+      //\r
+      break;\r
+\r
+    case 0x0003:\r
+      //\r
+      // User chose to run the Boot Manager\r
+      //\r
+      CallBootManager ();\r
+      break;\r
+\r
+    case 0x0004:\r
+      //\r
+      // Display the Device Manager\r
+      //\r
+      do {\r
+        CallDeviceManager();\r
+      } while (gCallbackKey == 4);\r
+      break;\r
+\r
+    case 0x0005:\r
+      //\r
+      // Display the Boot Maintenance Manager\r
+      //\r
+      BdsStartBootMaint ();\r
+      break;\r
+    }\r
+\r
+  } while ((Status == EFI_SUCCESS) && (gCallbackKey != 1));\r
+\r
+  //\r
+  //Will leave browser, check any reset required change is applied? if yes, reset system\r
+  //\r
+  SetupResetReminder ();\r
+  \r
+  //\r
+  // Automatically load current entry\r
+  // Note: The following lines of code only execute when Auto boot\r
+  // takes affect\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl);\r
+  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
+\r
+}\r