]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / PlatformBdsLib / BdsPlatform.c
diff --git a/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c b/Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c
new file mode 100644 (file)
index 0000000..b0ada79
--- /dev/null
@@ -0,0 +1,2399 @@
+/** @file\r
+\r
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>\r
+                                                                                   \r\r
+  This program and the accompanying materials are licensed and made available under\r\r
+  the terms and conditions of the BSD License that accompanies this distribution.  \r\r
+  The full text of the license may be found at                                     \r\r
+  http://opensource.org/licenses/bsd-license.php.                                  \r\r
+                                                                                   \r\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            \r\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    \r\r
+                                                                                   \r\r
+\r
+\r
+Module Name:\r
+\r
+  BdsPlatform.c\r
+\r
+Abstract:\r
+\r
+  This file include all platform action which can be customized\r
+  by IBV/OEM.\r
+\r
+--*/\r
+\r
+#include "BdsPlatform.h"\r
+#include "SetupMode.h"\r
+#include <Guid/SetupVariable.h>\r
+#include <Library/TcgPhysicalPresenceLib.h>\r
+#include <Library/TrEEPhysicalPresenceLib.h>\r
+#include <Protocol/I2cMasterMcg.h>\r
+#include <TianoApi.h>\r
+#include <PlatformBaseAddresses.h>\r
+#include <Protocol/GlobalNvsArea.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <PchRegs/PchRegsPcu.h>\r
+#include <Library/S3BootScriptLib.h>\r
+#include "PchAccess.h"\r
+#include "PchRegs/PchRegsSata.h"\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+\r
+EFI_GUID *ConnectDriverTable[] = {\r
+  &gEfiMmioDeviceProtocolGuid,\r
+  &gEfiI2cMasterProtocolGuid,\r
+  &gEfiI2cHostProtocolGuid\r
+};\r
+\r
+#define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \\r
+  { \\r
+    0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \\r
+  }\r
+VOID               *mShellImageCallbackReg = NULL;\r
+\r
+\r
+\r
+EFI_USER_PROFILE_HANDLE                           mCurrentUser = NULL;\r
+EFI_EVENT                                         mHotKeyTimerEvent = NULL;\r
+EFI_EVENT                                         mHitHotkeyEvent = NULL;\r
+EFI_EVENT                                         mUsbKeyboardConnectEvent = NULL;\r
+BOOLEAN                                           mHotKeyPressed = FALSE;\r
+VOID                                              *mHitHotkeyRegistration;\r
+#define KEYBOARD_TIMER_INTERVAL                   20000 // 0.02s\r
+\r
+VOID\r
+ConnectUSBController (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+PlatformBdsConnectSimpleConsole (\r
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
+);\r
+\r
+VOID \r
+BootIntoFirmwareInterface(\r
+  VOID\r
+  );\r
+  \r
+VOID\r
+EFIAPI\r
+PlatformBdsInitHotKeyEvent (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+DisableAhciCtlr (\r
+  IN EFI_EVENT                          Event,\r
+  IN VOID                               *Context\r
+  )\r
+{\r
+  UINT32                    PmcDisableAddress;\r
+  UINT8                     SataStorageAmount;\r
+  UINT32                    SataBase;\r
+  UINT16                    SataPortStatus;\r
+\r
+\r
+  DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n"));\r
+  SataStorageAmount = 0;\r
+  SataBase = *(UINT32*) Context;\r
+\r
+  //\r
+  // BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status)\r
+  //\r
+  SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS);\r
+\r
+  //\r
+  // Bit 8 EN: Port 0 Present\r
+  //\r
+  if ((SataPortStatus & 0x100) == 0x100) {\r
+    SataStorageAmount++;\r
+  }\r
+\r
+  //\r
+  // Bit 9 EN: Port 1 Present\r
+  //\r
+  if ((SataPortStatus & 0x200) == 0x200) {\r
+    SataStorageAmount++;\r
+  }\r
+\r
+  //\r
+  // Disable SATA controller when it sets to AHCI mode without carrying any devices\r
+  // in order to prevent AHCI yellow bang under Win device manager.\r
+  //\r
+  if (SataStorageAmount == 0) {\r
+    PmcDisableAddress = (MmioRead32 ((PCH_PCI_EXPRESS_BASE_ADDRESS + (UINT32) (31 << 15)) + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR) + R_PCH_PMC_FUNC_DIS;\r
+    MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA);\r
+    S3BootScriptSaveMemWrite (\r
+      EfiBootScriptWidthUint32,\r
+      (UINTN) PmcDisableAddress,\r
+      1,\r
+      (VOID *) (UINTN) PmcDisableAddress\r
+      );\r
+  }\r
+}\r
+\r
+VOID\r
+InstallReadyToLock (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_HANDLE                Handle;\r
+  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;\r
+  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;\r
+\r
+  //\r
+  // Install DxeSmmReadyToLock protocol prior to the processing of boot options\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiSmmAccess2ProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &SmmAccess\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+\r
+    //\r
+    // Prepare S3 information, this MUST be done before DxeSmmReadyToLock\r
+    //\r
+    Status = gBS->LocateProtocol (\r
+                    &gEfiAcpiS3SaveProtocolGuid,\r
+                    NULL,\r
+                    (VOID **)&AcpiS3Save\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      AcpiS3Save->S3Save (AcpiS3Save, NULL);\r
+    }\r
+\r
+    Handle = NULL;\r
+    Status = gBS->InstallProtocolInterface (\r
+                    &Handle,\r
+                    &gExitPmAuthProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    NULL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    Handle = NULL;\r
+    Status = gBS->InstallProtocolInterface (\r
+                    &Handle,\r
+                    &gEfiDxeSmmReadyToLockProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    NULL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+ShellImageCallback (\r
+  IN EFI_EVENT                          Event,\r
+  IN VOID                               *Context\r
+  )\r
+{\r
+ BdsSetConsoleMode (TRUE);\r
+ DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));\r
+}\r
+\r
+//\r
+// BDS Platform Functions\r
+//\r
+/**\r
+  Platform Bds init. Incude the platform firmware vendor, revision\r
+  and so crc check.\r
+\r
+  @param VOID\r
+\r
+  @retval  None.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBdsInit (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_EVENT   ShellImageEvent;\r
+  EFI_GUID    ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL;\r
+\r
+  #ifdef __GNUC__\r
+  SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19);\r
+  #else\r
+  SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14);\r
+  #endif\r
+  BdsLibSaveMemoryTypeInformation ();\r
+\r
+  //\r
+  // Before user authentication, the user identification devices need be connected\r
+  // from the platform customized device paths\r
+  //\r
+  PlatformBdsConnectAuthDevice ();\r
+\r
+  //\r
+  // As console is not ready, the auto logon user will be identified.\r
+  //\r
+  BdsLibUserIdentify (&mCurrentUser);\r
+\r
+  //\r
+  // Change Gop mode when boot into Shell\r
+  //\r
+  if (mShellImageCallbackReg == NULL) {\r
+    Status = gBS->CreateEvent (\r
+                    EFI_EVENT_NOTIFY_SIGNAL,\r
+                    EFI_TPL_CALLBACK,\r
+                    ShellImageCallback,\r
+                    NULL,\r
+                    &ShellImageEvent\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gBS->RegisterProtocolNotify (\r
+                      &ShellEnvProtocol,\r
+                      ShellImageEvent,\r
+                      &mShellImageCallbackReg\r
+                      );\r
+\r
+      DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n"));\r
+    }\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+GetGopDevicePath (\r
+   IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
+   OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
+   )\r
+{\r
+  UINTN                           Index;\r
+  EFI_STATUS                      Status;\r
+  EFI_HANDLE                      PciDeviceHandle;\r
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;\r
+  UINTN                           GopHandleCount;\r
+  EFI_HANDLE                      *GopHandleBuffer;\r
+\r
+  UINTN                                 VarSize;\r
+  SYSTEM_CONFIGURATION  mSystemConfiguration;\r
+\r
+  if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Initialize the GopDevicePath to be PciDevicePath\r
+  //\r
+  *GopDevicePath    = PciDevicePath;\r
+  TempPciDevicePath = PciDevicePath;\r
+\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &TempPciDevicePath,\r
+                  &PciDeviceHandle\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Try to connect this handle, so that GOP dirver could start on this\r
+  // device and create child handles with GraphicsOutput Protocol installed\r
+  // on them, then we get device paths of these child handles and select\r
+  // them as possible console device.\r
+  //\r
+\r
+  //\r
+  // Select display devices\r
+  //\r
+  VarSize = sizeof(SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable(\r
+                  L"Setup",\r
+                  &gEfiNormalSetupGuid,\r
+                  NULL,\r
+                  &VarSize,\r
+                  &mSystemConfiguration\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  if(mSystemConfiguration.BootDisplayDevice != 0x0)\r
+  {\r
+    ACPI_ADR_DEVICE_PATH         AcpiAdr;\r
+    EFI_DEVICE_PATH_PROTOCOL  *MyDevicePath = NULL;\r
+\r
+    AcpiAdr.Header.Type     = ACPI_DEVICE_PATH;\r
+    AcpiAdr.Header.SubType  = ACPI_ADR_DP;\r
+\r
+    switch (mSystemConfiguration.BootDisplayDevice) {\r
+    case 1:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);    //CRT Device\r
+      break;\r
+    case 2:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0);  //HDMI Device Port B\r
+      break;\r
+    case 3:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0);    //DP PortB\r
+      break;\r
+    case 4:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0);    //DP PortC\r
+      break;\r
+    case 5:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0);    //eDP Port C\r
+      break;\r
+    case 6:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0);  //DSI Port A\r
+      break;\r
+    case 7:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0);  //DSI Port C\r
+      break;\r
+    default:\r
+      AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0);\r
+      break;\r
+    }\r
+\r
+    SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
+\r
+    MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr);\r
+\r
+    gBS->ConnectController (\r
+           PciDeviceHandle,\r
+           NULL,\r
+           MyDevicePath,\r
+           FALSE\r
+           );\r
+\r
+    FreePool(MyDevicePath);\r
+  }\r
+  else\r
+  {\r
+    gBS->ConnectController (\r
+           PciDeviceHandle,\r
+           NULL,\r
+           NULL,\r
+           FALSE\r
+           );\r
+  }\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  NULL,\r
+                  &GopHandleCount,\r
+                  &GopHandleBuffer\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Add all the child handles as possible Console Device\r
+    //\r
+    for (Index = 0; Index < GopHandleCount; Index++) {\r
+      Status = gBS->HandleProtocol (\r
+                      GopHandleBuffer[Index],\r
+                      &gEfiDevicePathProtocolGuid,\r
+                      (VOID**)&TempDevicePath\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+      if (CompareMem (\r
+            PciDevicePath,\r
+            TempDevicePath,\r
+            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
+            ) == 0) {\r
+        //\r
+        // In current implementation, we only enable one of the child handles\r
+        // as console device, i.e. sotre one of the child handle's device\r
+        // path to variable "ConOut"\r
+        // In futhure, we could select all child handles to be console device\r
+        //\r
+        *GopDevicePath = TempDevicePath;\r
+      }\r
+    }\r
+    gBS->FreePool (GopHandleBuffer);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Search out all the platform pci or agp video device. The function may will\r
+  find multiple video device, and return all enabled device path.\r
+\r
+  @param PlugInPciVgaDevicePath    Return the platform plug in pci video device\r
+                                   path if the system have plug in pci video device.\r
+  @param OnboardPciVgaDevicePath   Return the platform active agp video device path\r
+                                   if the system have plug in agp video device or on\r
+                                   chip agp device.\r
+\r
+  @retval EFI_SUCCSS               Get all platform active video device path.\r
+  @retval EFI_STATUS               Return the status of gBS->LocateDevicePath (),\r
+                                   gBS->ConnectController (),\r
+                                   and gBS->LocateHandleBuffer ().\r
+\r
+**/\r
+EFI_STATUS\r
+GetPlugInPciVgaDevicePath (\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **PlugInPciVgaDevicePath,\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL     **OnboardPciVgaDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_HANDLE                RootHandle;\r
+  UINTN                     HandleCount;\r
+  EFI_HANDLE                *HandleBuffer;\r
+  UINTN                     Index;\r
+  UINTN                     Index1;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  BOOLEAN                   PlugInPciVga;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  PCI_TYPE00                Pci;\r
+\r
+  DevicePath = NULL;\r
+  PlugInPciVga = TRUE;\r
+  HandleCount = 0;\r
+  HandleBuffer = NULL;\r
+\r
+  //\r
+  // Make all the PCI_IO protocols on PCI Seg 0 show up\r
+  //\r
+  BdsLibConnectDevicePath (gPlatformRootBridges[0]);\r
+\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &gPlatformRootBridges[0],\r
+                  &RootHandle\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = gBS->ConnectController (\r
+                  RootHandle,\r
+                  NULL,\r
+                  NULL,\r
+                  FALSE\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Start to check all the pci io to find all possible VGA device\r
+  //\r
+  HandleCount = 0;\r
+  HandleBuffer = NULL;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = gBS->HandleProtocol (\r
+                    HandleBuffer[Index],\r
+                    &gEfiPciIoProtocolGuid,\r
+                    (VOID**)&PciIo\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+\r
+      //\r
+      // Check for all VGA device\r
+      //\r
+      Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint32,\r
+                        0,\r
+                        sizeof (Pci) / sizeof (UINT32),\r
+                        &Pci\r
+                        );\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Here we decide which VGA device to enable in PCI bus\r
+      //\r
+      // The first plugin PCI VGA card device will be present as PCI VGA\r
+      // The onchip AGP or AGP card will be present as AGP VGA\r
+      //\r
+      if (!IS_PCI_VGA (&Pci)) {\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Set the device as the possible console out device,\r
+      //\r
+      // Below code will make every VGA device to be one\r
+      // of the possibe console out device\r
+      //\r
+      PlugInPciVga = TRUE;\r
+      gBS->HandleProtocol (\r
+             HandleBuffer[Index],\r
+             &gEfiDevicePathProtocolGuid,\r
+             (VOID**)&DevicePath\r
+             );\r
+\r
+      Index1 = 0;\r
+\r
+      while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) {\r
+        if (CompareMem (\r
+              DevicePath,\r
+              gPlatformAllPossiblePciVgaConsole[Index1],\r
+              GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1])\r
+              ) == 0) {\r
+\r
+          //\r
+          // This device is an AGP device\r
+          //\r
+          *OnboardPciVgaDevicePath = DevicePath;\r
+          PlugInPciVga = FALSE;\r
+          break;\r
+        }\r
+\r
+        Index1 ++;\r
+      }\r
+\r
+      if (PlugInPciVga) {\r
+        *PlugInPciVgaDevicePath = DevicePath;\r
+      }\r
+    }\r
+  }\r
+\r
+  FreePool (HandleBuffer);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Find the platform  active vga, and base on the policy to enable the vga as\r
+  the console out device. The policy is driven by one setup variable "VBIOS".\r
+\r
+  None.\r
+\r
+  @param EFI_UNSUPPORTED         There is no active vga device\r
+\r
+  @retval EFI_STATUS             Return the status of BdsLibGetVariableAndSize ()\r
+\r
+**/\r
+EFI_STATUS\r
+PlatformBdsForceActiveVga (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *PlugInPciVgaDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *OnboardPciVgaDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathFirst;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathSecond;\r
+  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;\r
+  UINTN                VarSize;\r
+  SYSTEM_CONFIGURATION  mSystemConfiguration;\r
+\r
+  Status = EFI_SUCCESS;\r
+  PlugInPciVgaDevicePath = NULL;\r
+  OnboardPciVgaDevicePath = NULL;\r
+\r
+  //\r
+  // Check the policy which is the first enabled VGA\r
+  //\r
+  GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);\r
+\r
+  if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  VarSize = sizeof(SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable(\r
+                  L"Setup",\r
+                  &gEfiNormalSetupGuid,\r
+                  NULL,\r
+                  &VarSize,\r
+                  &mSystemConfiguration\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL) ) {\r
+    DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n"));\r
+    DevicePathFirst  = OnboardPciVgaDevicePath;\r
+    DevicePathSecond = PlugInPciVgaDevicePath;\r
+    goto UpdateConOut;\r
+  }\r
+  if(OnboardPciVgaDevicePath != NULL && mSystemConfiguration.PrimaryVideoAdaptor == 0) {\r
+    DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set primary!!!...\n"));\r
+    DevicePathFirst  = OnboardPciVgaDevicePath;\r
+    DevicePathSecond = PlugInPciVgaDevicePath;\r
+    goto UpdateConOut;\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n"));\r
+  DevicePathFirst  = PlugInPciVgaDevicePath;\r
+  DevicePathSecond = OnboardPciVgaDevicePath;\r
+\r
+UpdateConOut:\r
+  GetGopDevicePath (DevicePathFirst, &GopDevicePath);\r
+  DevicePathFirst = GopDevicePath;\r
+\r
+  Status = BdsLibUpdateConsoleVariable (\r
+             L"ConOut",\r
+             DevicePathFirst,\r
+             DevicePathSecond\r
+             );\r
+\r
+  return Status;\r
+}\r
+\r
+VOID\r
+UpdateConsoleResolution(\r
+  VOID\r
+  )\r
+{\r
+  UINT32                 HorizontalResolution;\r
+  UINT32                 VerticalResolution;\r
+  SYSTEM_CONFIGURATION   SystemConfiguration;\r
+  UINTN                  VarSize;\r
+  EFI_STATUS             Status;\r
+\r
+\r
+  HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);\r
+  VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);\r
+\r
+  VarSize = sizeof(SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable(\r
+                  L"Setup",\r
+                  &gEfiNormalSetupGuid,\r
+                  NULL,\r
+                  &VarSize,\r
+                  &SystemConfiguration\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  switch (SystemConfiguration.IgdFlatPanel) {\r
+\r
+  case 0:\r
+    //\r
+    // Use the detault PCD values.\r
+    //\r
+    break;\r
+\r
+  case 1:\r
+    HorizontalResolution = 640;\r
+    VerticalResolution = 480;\r
+    break;\r
+\r
+  case 2:\r
+    HorizontalResolution = 800;\r
+    VerticalResolution = 600;\r
+    break;\r
+\r
+  case 3:\r
+    HorizontalResolution = 1024;\r
+    VerticalResolution = 768;\r
+    break;\r
+\r
+  case 4:\r
+  HorizontalResolution = 1280;\r
+  VerticalResolution = 1024;\r
+  break;\r
+\r
+  case 5:\r
+  HorizontalResolution = 1366;\r
+  VerticalResolution = 768;\r
+  break;\r
+\r
+  case 6:\r
+  HorizontalResolution = 1680;\r
+  VerticalResolution = 1050;\r
+  break;\r
+\r
+  case 7:\r
+  HorizontalResolution = 1920;\r
+  VerticalResolution = 1200;\r
+  break;\r
+\r
+  case 8:\r
+  HorizontalResolution = 1280;\r
+  VerticalResolution = 800;\r
+  break;\r
+  }\r
+\r
+  PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution);\r
+  PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution);\r
+  DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution, VerticalResolution));\r
+\r
+  return;\r
+}\r
+\r
+/**\r
+  Connect the predefined platform default console device. Always try to find\r
+  and enable the vga device if have.\r
+\r
+  @param PlatformConsole    Predfined platform default console device array.\r
+\r
+  @retval EFI_SUCCESS       Success connect at least one ConIn and ConOut\r
+                            device, there must have one ConOut device is\r
+                            active vga device.\r
+\r
+  @retval EFI_STATUS        Return the status of\r
+                            BdsLibConnectAllDefaultConsoles ()\r
+\r
+**/\r
+EFI_STATUS\r
+PlatformBdsConnectConsole (\r
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
+)\r
+{\r
+  EFI_STATUS                         Status;\r
+  UINTN                              Index;\r
+  EFI_DEVICE_PATH_PROTOCOL           *VarConout;\r
+  EFI_DEVICE_PATH_PROTOCOL           *VarConin;\r
+  UINTN                              DevicePathSize;\r
+\r
+  UpdateConsoleResolution();\r
+\r
+  Index = 0;\r
+  Status = EFI_SUCCESS;\r
+  DevicePathSize = 0;\r
+  VarConout = BdsLibGetVariableAndSize (\r
+                L"ConOut",\r
+                &gEfiGlobalVariableGuid,\r
+                &DevicePathSize\r
+                );\r
+  VarConin = BdsLibGetVariableAndSize (\r
+               L"ConIn",\r
+               &gEfiGlobalVariableGuid,\r
+               &DevicePathSize\r
+               );\r
+  if (VarConout == NULL || VarConin == NULL) {\r
+    //\r
+    // Have chance to connect the platform default console,\r
+    // the platform default console is the minimue device group\r
+    // the platform should support\r
+    //\r
+    while (PlatformConsole[Index].DevicePath != NULL) {\r
+\r
+      //\r
+      // Update the console variable with the connect type\r
+      //\r
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
+        BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);\r
+      }\r
+\r
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
+        BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);\r
+      }\r
+\r
+      if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
+        BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);\r
+      }\r
+\r
+      Index ++;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Make sure we have at least one active VGA, and have the right\r
+  // active VGA in console variable\r
+  //\r
+  Status = PlatformBdsForceActiveVga ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));\r
+\r
+  //\r
+  // Connect the all the default console with current console variable\r
+  //\r
+  Status = BdsLibConnectAllDefaultConsoles ();\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Connect with predeined platform connect sequence,\r
+  the OEM/IBV can customize with their own connect sequence.\r
+\r
+  @param None.\r
+\r
+  @retval None.\r
+\r
+**/\r
+VOID\r
+PlatformBdsConnectSequence (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                     Index;\r
+\r
+  Index = 0;\r
+\r
+  //\r
+  // Here we can get the customized platform connect sequence\r
+  // Notes: we can connect with new variable which record the\r
+  // last time boots connect device path sequence\r
+  //\r
+  while (gPlatformConnectSequence[Index] != NULL) {\r
+\r
+    //\r
+    // Build the platform boot option\r
+    //\r
+    BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
+    Index ++;\r
+  }\r
+\r
+  //\r
+  // Just use the simple policy to connect all devices\r
+  // There should be no difference between debug tip and release tip, or it will be extremely hard to debug.\r
+  //\r
+  // There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save.\r
+  // It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled.\r
+  //\r
+  // So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock().\r
+  // We may also consider to connect SataController only later if needed.\r
+  //\r
+  BdsLibConnectAll ();\r
+}\r
+\r
+/**\r
+\r
+  Load the predefined driver option, OEM/IBV can customize this\r
+  to load their own drivers\r
+\r
+  @param BdsDriverLists  The header of the driver option link list.\r
+\r
+  @retval None.\r
+\r
+**/\r
+VOID\r
+PlatformBdsGetDriverOption (\r
+  IN OUT LIST_ENTRY                  *BdsDriverLists\r
+  )\r
+{\r
+  UINTN                              Index;\r
+\r
+  Index = 0;\r
+\r
+  //\r
+  // Here we can get the customized platform driver option\r
+  //\r
+  while (gPlatformDriverOption[Index] != NULL) {\r
+\r
+    //\r
+    // Build the platform boot option\r
+    //\r
+    BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");\r
+    Index ++;\r
+  }\r
+\r
+}\r
+\r
+/**\r
+  This function is used for some critical time if the the system\r
+  have no any boot option, and there is no time out for user to add\r
+  the new boot option. This can also treat as the platform default\r
+  boot option.\r
+\r
+  @param BdsBootOptionList   The header of the boot option link list.\r
+\r
+  @retval None.\r
+\r
+**/\r
+VOID\r
+PlatformBdsPredictBootOption (\r
+  IN OUT LIST_ENTRY                  *BdsBootOptionList\r
+  )\r
+{\r
+  UINTN                              Index;\r
+\r
+  Index = 0;\r
+\r
+  //\r
+  // Here give chance to get platform boot option data\r
+  //\r
+  while (gPlatformBootOption[Index] != NULL) {\r
+\r
+    //\r
+    // Build the platform boot option\r
+    //\r
+    BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder");\r
+    Index ++;\r
+  }\r
+}\r
+\r
+/**\r
+  Perform the platform diagnostic, such like test memory. OEM/IBV also\r
+  can customize this fuction to support specific platform diagnostic.\r
+\r
+  @param MemoryTestLevel   The memory test intensive level\r
+  @param QuietBoot         Indicate if need to enable the quiet boot\r
+  @param BaseMemoryTest    A pointer to BdsMemoryTest()\r
+\r
+  @retval  None.\r
+\r
+**/\r
+VOID\r
+PlatformBdsDiagnostics (\r
+  IN EXTENDMEM_COVERAGE_LEVEL    MemoryTestLevel,\r
+  IN BOOLEAN                     QuietBoot,\r
+  IN BASEM_MEMORY_TEST           BaseMemoryTest\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+\r
+  //\r
+  // Here we can decide if we need to show\r
+  // the diagnostics screen\r
+  // Notes: this quiet boot code should be remove\r
+  // from the graphic lib\r
+  //\r
+  if (QuietBoot) {\r
+    EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
+\r
+    //\r
+    // Perform system diagnostic\r
+    //\r
+    Status = BaseMemoryTest (MemoryTestLevel);\r
+    if (EFI_ERROR (Status)) {\r
+      DisableQuietBoot ();\r
+    }\r
+\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Perform system diagnostic\r
+  //\r
+  Status = BaseMemoryTest (MemoryTestLevel);\r
+}\r
+\r
+\r
+/**\r
+\r
+  The function will excute with as the platform policy, current policy\r
+  is driven by boot mode. IBV/OEM can customize this code for their specific\r
+  policy action.\r
+\r
+  @param DriverOptionList - The header of the driver option link list\r
+  @param  BootOptionList   - The header of the boot option link list\r
+  @param ProcessCapsules  - A pointer to ProcessCapsules()\r
+  @param BaseMemoryTest   - A pointer to BaseMemoryTest()\r
+\r
+  @retval None.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBdsPolicyBehavior (\r
+  IN OUT LIST_ENTRY                  *DriverOptionList,\r
+  IN OUT LIST_ENTRY                  *BootOptionList,\r
+  IN PROCESS_CAPSULES                ProcessCapsules,\r
+  IN BASEM_MEMORY_TEST               BaseMemoryTest\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  UINT16                             Timeout;\r
+  EFI_BOOT_MODE                      BootMode;\r
+  BOOLEAN                            DeferredImageExist;\r
+  UINTN                              Index;\r
+  CHAR16                             CapsuleVarName[36];\r
+  CHAR16                             *TempVarName;\r
+  SYSTEM_CONFIGURATION               SystemConfiguration;\r
+  UINTN                              VarSize;\r
+  BOOLEAN                            SetVariableFlag;\r
+  PLATFORM_PCI_DEVICE_PATH           *EmmcBootDevPath;\r
+  EFI_GLOBAL_NVS_AREA_PROTOCOL       *GlobalNvsArea;\r
+  EFI_HANDLE                         FvProtocolHandle;\r
+  UINTN                              HandleCount;\r
+  EFI_HANDLE                         *HandleBuffer;\r
+  UINTN                              Index1;\r
+  UINTN                              SataPciRegBase = 0;\r
+  UINT16                             SataModeSelect = 0;\r
+  VOID                               *RegistrationExitPmAuth = NULL;\r
+  EFI_EVENT                          Event;\r
+  BOOLEAN                            IsFirstBoot;\r
+  UINT16                             *BootOrder;\r
+  UINTN                              BootOrderSize;\r
+\r
+  Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
+  VarSize = sizeof(SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable(\r
+                  NORMAL_SETUP_NAME,\r
+                  &gEfiNormalSetupGuid,\r
+                  NULL,\r
+                  &VarSize,\r
+                  &SystemConfiguration\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Load the driver option as the driver option list\r
+  //\r
+  PlatformBdsGetDriverOption (DriverOptionList);\r
+\r
+  //\r
+  // Get current Boot Mode\r
+  //\r
+  BootMode = GetBootModeHob();\r
+\r
+  //\r
+  // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...\r
+  // as early as possible which will avoid the next time boot after the capsule update\r
+  // will still into the capsule loop\r
+  //\r
+  StrCpy (CapsuleVarName, EFI_CAPSULE_VARIABLE_NAME);\r
+  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
+  Index = 0;\r
+  SetVariableFlag = TRUE;\r
+  while (SetVariableFlag) {\r
+    if (Index > 0) {\r
+      UnicodeValueToString (TempVarName, 0, Index, 0);\r
+    }\r
+    Status = gRT->SetVariable (\r
+                    CapsuleVarName,\r
+                    &gEfiCapsuleVendorGuid,\r
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS |\r
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
+                    0,\r
+                    (VOID *)NULL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // There is no capsule variables, quit\r
+      //\r
+      SetVariableFlag = FALSE;\r
+      continue;\r
+    }\r
+    Index++;\r
+  }\r
+\r
+  //\r
+  // No deferred images exist by default\r
+  //\r
+  DeferredImageExist = FALSE;\r
+  if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (PcdGet32(PcdFlashFvShellSize) > 0)){\r
+    gDS->ProcessFirmwareVolume (\r
+           (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),\r
+           PcdGet32(PcdFlashFvShellSize),\r
+           &FvProtocolHandle\r
+           );\r
+  }\r
+\r
+  if (SystemConfiguration.FastBoot == 1) {\r
+    BootOrder = BdsLibGetVariableAndSize (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  &BootOrderSize\r
+                  );\r
+    if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) {\r
+      //\r
+      // BootOrder exist, it means system has boot before. We can do fast boot.\r
+      //\r
+      BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;\r
+    }\r
+  }\r
+\r
+\r
+  //\r
+  // Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected,\r
+  // SATA AHCI CTLR device will show yellow bang, implement this solution to solve it.\r
+  //\r
+  SataPciRegBase  = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, 0, 0);\r
+  SataModeSelect  = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;\r
+  Status          = EFI_SUCCESS;\r
+  if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {\r
+    Status = gBS->CreateEvent (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_CALLBACK,\r
+                    DisableAhciCtlr,\r
+                    &SataPciRegBase,\r
+                    &Event\r
+                     );\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gBS->RegisterProtocolNotify (\r
+                      &gExitPmAuthProtocolGuid,\r
+                      Event,\r
+                      &RegistrationExitPmAuth\r
+                      );\r
+    }\r
+  }\r
+\r
+  switch (BootMode) {\r
+\r
+  case BOOT_WITH_MINIMAL_CONFIGURATION:\r
+    PlatformBdsInitHotKeyEvent ();\r
+    PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole);\r
+\r
+\r
+    //\r
+    // Check to see if it's needed to dispatch more DXE drivers.\r
+    //\r
+    for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) {\r
+      Status = gBS->LocateHandleBuffer (\r
+                      ByProtocol,\r
+                      ConnectDriverTable[Index],\r
+                      NULL,\r
+                      &HandleCount,\r
+                      &HandleBuffer\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        for (Index1 = 0; Index1 < HandleCount; Index1++) {\r
+          gBS->ConnectController (\r
+                 HandleBuffer[Index1],\r
+                 NULL,\r
+                 NULL,\r
+                 TRUE\r
+                 );\r
+        }\r
+      }\r
+\r
+      if (HandleBuffer != NULL) {\r
+        FreePool (HandleBuffer);\r
+      }\r
+\r
+      gDS->Dispatch ();\r
+    }\r
+\r
+    //\r
+    //  Locate the Global NVS Protocol.\r
+    //\r
+    Status = gBS->LocateProtocol (\r
+                    &gEfiGlobalNvsAreaProtocolGuid,\r
+                    NULL,\r
+                    (void **)&GlobalNvsArea\r
+                    );\r
+    if (GlobalNvsArea->Area->emmcVersion == 0){\r
+      EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0];\r
+      EmmcBootDevPath->PciDevice.Device = 0x10;\r
+    }\r
+\r
+    //\r
+    // Connect boot device here to give time to read keyboard.\r
+    //\r
+    BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]);\r
+\r
+    //\r
+    // This is a workround for dectecting hotkey from USB keyboard.\r
+    //\r
+    gBS->Stall(KEYBOARD_TIMER_INTERVAL);\r
+\r
+    if (mHotKeyTimerEvent != NULL) {\r
+      gBS->SetTimer (\r
+             mHotKeyTimerEvent,\r
+             TimerCancel,\r
+             0\r
+             );\r
+      gBS->CloseEvent (mHotKeyTimerEvent);\r
+      mHotKeyTimerEvent = NULL;\r
+    }\r
+    if (mHotKeyPressed) {\r
+      //\r
+      // Skip show progress count down\r
+      //\r
+      Timeout = 0xFFFF;\r
+      goto FULL_CONFIGURATION;\r
+    }\r
+\r
+    if (SystemConfiguration.QuietBoot) {\r
+      EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
+    } else {\r
+      PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);\r
+    }\r
+\r
+\r
+#ifdef TPM_ENABLED\r
+       TcgPhysicalPresenceLibProcessRequest();\r
+#endif\r
+\r
+    //\r
+    // Close boot script and install ready to lock\r
+    //\r
+    InstallReadyToLock ();\r
+\r
+    //\r
+    // Give one chance to enter the setup if we \r
+    // select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled.\r
+    //\r
+    BootIntoFirmwareInterface();\r
+    break;\r
+\r
+  case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
+\r
+    //\r
+    // In no-configuration boot mode, we can connect the\r
+    // console directly.\r
+    //\r
+    BdsLibConnectAllDefaultConsoles ();\r
+    PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
+\r
+    //\r
+    // Perform some platform specific connect sequence\r
+    //\r
+    PlatformBdsConnectSequence ();\r
+\r
+    //\r
+    // As console is ready, perform user identification again.\r
+    //\r
+    if (mCurrentUser == NULL) {\r
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);\r
+      if (DeferredImageExist) {\r
+        //\r
+        // After user authentication, the deferred drivers was loaded again.\r
+        // Here, need to ensure the deferred images are connected.\r
+        //\r
+        BdsLibConnectAllDefaultConsoles ();\r
+        PlatformBdsConnectSequence ();\r
+      }\r
+    }\r
+\r
+    //\r
+    // Close boot script and install ready to lock\r
+    //\r
+    InstallReadyToLock ();\r
+\r
+    //\r
+    // Notes: current time out = 0 can not enter the\r
+    // front page\r
+    //\r
+    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);\r
+\r
+    //\r
+    // Check the boot option with the boot option list\r
+    //\r
+    BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
+    break;\r
+\r
+  case BOOT_ON_FLASH_UPDATE:\r
+\r
+    //\r
+    // Boot with the specific configuration\r
+    //\r
+    PlatformBdsConnectConsole (gPlatformConsole);\r
+    PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);\r
+    BdsLibConnectAll ();\r
+\r
+    //\r
+    // Perform user identification\r
+    //\r
+    if (mCurrentUser == NULL) {\r
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);\r
+      if (DeferredImageExist) {\r
+        //\r
+        // After user authentication, the deferred drivers was loaded again.\r
+        // Here, need to ensure the deferred images are connected.\r
+        //\r
+        BdsLibConnectAll ();\r
+      }\r
+    }\r
+\r
+    //\r
+    // Close boot script and install ready to lock\r
+    //\r
+    InstallReadyToLock ();\r
+\r
+    ProcessCapsules (BOOT_ON_FLASH_UPDATE);\r
+    break;\r
+\r
+  case BOOT_IN_RECOVERY_MODE:\r
+\r
+    //\r
+    // In recovery mode, just connect platform console\r
+    // and show up the front page\r
+    //\r
+    PlatformBdsConnectConsole (gPlatformConsole);\r
+    PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);\r
+    BdsLibConnectAll ();\r
+\r
+    //\r
+    // Perform user identification\r
+    //\r
+    if (mCurrentUser == NULL) {\r
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);\r
+      if (DeferredImageExist) {\r
+        //\r
+        // After user authentication, the deferred drivers was loaded again.\r
+        // Here, need to ensure the deferred drivers are connected.\r
+        //\r
+        BdsLibConnectAll ();\r
+      }\r
+    }\r
+\r
+    //\r
+    // Close boot script and install ready to lock\r
+    //\r
+    InstallReadyToLock ();\r
+\r
+    //\r
+    // In recovery boot mode, we still enter to the\r
+    // frong page now\r
+    //\r
+    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);\r
+    break;\r
+\r
+FULL_CONFIGURATION:\r
+  case BOOT_WITH_FULL_CONFIGURATION:\r
+  case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:\r
+  case BOOT_WITH_DEFAULT_SETTINGS:\r
+  default:\r
+\r
+    //\r
+    // Connect platform console\r
+    //\r
+    Status = PlatformBdsConnectConsole (gPlatformConsole);\r
+    if (EFI_ERROR (Status)) {\r
+\r
+      //\r
+      // Here OEM/IBV can customize with defined action\r
+      //\r
+      PlatformBdsNoConsoleAction ();\r
+    }\r
+\r
+    //\r
+    // Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard,\r
+    // Need to root cause this issue.\r
+    //\r
+    DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n"));\r
+    BdsLibDisconnectAllEfi();\r
+    BdsLibConnectAll ();\r
+    DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n"));\r
+\r
+    //\r
+    // Perform some platform specific connect sequence\r
+    //\r
+    PlatformBdsConnectSequence ();\r
+    if (SystemConfiguration.QuietBoot) {\r
+        EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
+    } else {\r
+        PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest);\r
+    }\r
+\r
+    //\r
+    // Do a pre-delay so Hard Disk can spin up and see more logo.\r
+    //\r
+    gBS->Stall(SystemConfiguration.HddPredelay * 1000000);\r
+\r
+    //\r
+    // Perform user identification\r
+    //\r
+    if (mCurrentUser == NULL) {\r
+      PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist);\r
+      if (DeferredImageExist) {\r
+        //\r
+        // After user authentication, the deferred drivers was loaded again.\r
+        // Here, need to ensure the deferred drivers are connected.\r
+        //\r
+        Status = PlatformBdsConnectConsole (gPlatformConsole);\r
+        if (EFI_ERROR (Status)) {\r
+          PlatformBdsNoConsoleAction ();\r
+        }\r
+        PlatformBdsConnectSequence ();\r
+      }\r
+    }\r
+#ifdef TPM_ENABLED\r
+   TcgPhysicalPresenceLibProcessRequest();\r
+#endif\r
+\r
+    //\r
+    // Close boot script and install ready to lock\r
+    //\r
+    InstallReadyToLock ();\r
+\r
+    //\r
+    // Give one chance to enter the setup if we\r
+    // have the time out\r
+    //\r
+    PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);\r
+\r
+       //\r
+       // Give one chance to enter the setup if we \r
+       // select Gummiboot "Reboot Into Firmware Interface"\r
+       //\r
+       BootIntoFirmwareInterface();\r
+\r
+    //\r
+    // In default boot mode, always find all boot\r
+    // option and do enumerate all the default boot option\r
+    //\r
+    if (Timeout == 0) {\r
+      BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
+      if (IsListEmpty(BootOptionList)) {\r
+        PlatformBdsPredictBootOption (BootOptionList);\r
+      }\r
+\r
+      return;\r
+    }\r
+\r
+    //\r
+    // Here we have enough time to do the enumeration of boot device\r
+    //\r
+    BdsLibEnumerateAllBootOption (BootOptionList);\r
+    break;\r
+  }\r
+\r
+\r
+  IsFirstBoot = PcdGetBool(PcdBootState);\r
+  if (IsFirstBoot) {\r
+    PcdSetBool(PcdBootState, FALSE);\r
+  }\r
+  return;\r
+\r
+}\r
+\r
+/**\r
+  Hook point after a boot attempt succeeds. We don't expect a boot option to\r
+  return, so the UEFI 2.0 specification defines that you will default to an\r
+  interactive mode and stop processing the BootOrder list in this case. This\r
+  is alos a platform implementation and can be customized by IBV/OEM.\r
+\r
+  @param Option  Pointer to Boot Option that succeeded to boot.\r
+\r
+  @retval None.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBdsBootSuccess (\r
+  IN  BDS_COMMON_OPTION *Option\r
+  )\r
+{\r
+  CHAR16  *TmpStr;\r
+\r
+  //\r
+  // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
+  // select loop then we need to pop up a UI and wait for user input.\r
+  //\r
+  TmpStr =  Option->StatusString;\r
+  if (TmpStr != NULL) {\r
+    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
+    FreePool(TmpStr);\r
+  }\r
+}\r
+\r
+/**\r
+  Hook point after a boot attempt fails.\r
+\r
+  @param Option - Pointer to Boot Option that failed to boot.\r
+  @param Status - Status returned from failed boot.\r
+  @param ExitData - Exit data returned from failed boot.\r
+  @param ExitDataSize - Exit data size returned from failed boot.\r
+\r
+  @retval None.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBdsBootFail (\r
+  IN  BDS_COMMON_OPTION  *Option,\r
+  IN  EFI_STATUS         Status,\r
+  IN  CHAR16             *ExitData,\r
+  IN  UINTN              ExitDataSize\r
+  )\r
+{\r
+  CHAR16          *TmpStr;\r
+  EFI_HANDLE      FvProtocolHandle;\r
+\r
+  //\r
+  // If Boot returned with failed status then we need to pop up a UI and wait\r
+  // for user input.\r
+  //\r
+  TmpStr = Option->StatusString;\r
+  if (TmpStr != NULL) {\r
+    BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
+    FreePool(TmpStr);\r
+  }\r
+  if (PcdGet32(PcdFlashFvShellSize) > 0){\r
+    gDS->ProcessFirmwareVolume (\r
+           (VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase),\r
+           PcdGet32(PcdFlashFvShellSize),\r
+           &FvProtocolHandle\r
+           );\r
+  }\r
+  PlatformBdsConnectSequence ();\r
+}\r
+\r
+/**\r
+  This function is remained for IBV/OEM to do some platform action,\r
+  if there no console device can be connected.\r
+\r
+  @param  None.\r
+\r
+  @retval EFI_SUCCESS       Direct return success now.\r
+\r
+**/\r
+EFI_STATUS\r
+PlatformBdsNoConsoleAction (\r
+  VOID\r
+  )\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function locks the block\r
+\r
+  @param Base            The base address flash region to be locked.\r
+\r
+**/\r
+VOID\r
+BdsLockFv (\r
+  IN EFI_PHYSICAL_ADDRESS  Base\r
+  )\r
+{\r
+  EFI_FV_BLOCK_MAP_ENTRY      *BlockMap;\r
+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;\r
+  EFI_PHYSICAL_ADDRESS        BaseAddress;\r
+  UINT8                       Data;\r
+  UINT32                      BlockLength;\r
+  UINTN                       Index;\r
+\r
+  BaseAddress = Base - 0x400000 + 2;\r
+  FvHeader    = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));\r
+  BlockMap    = &(FvHeader->BlockMap[0]);\r
+\r
+  while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {\r
+    BlockLength = BlockMap->Length;\r
+    for (Index = 0; Index < BlockMap->NumBlocks; Index++) {\r
+      Data = MmioOr8 ((UINTN) BaseAddress, 0x03);\r
+      BaseAddress += BlockLength;\r
+    }\r
+    BlockMap++;\r
+  }\r
+}\r
+\r
+VOID\r
+EFIAPI\r
+PlatformBdsLockNonUpdatableFlash (\r
+  VOID\r
+  )\r
+{\r
+  EFI_PHYSICAL_ADDRESS  Base;\r
+\r
+  Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase);\r
+  if (Base > 0) {\r
+    BdsLockFv (Base);\r
+  }\r
+\r
+  Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase);\r
+  if (Base > 0) {\r
+    BdsLockFv (Base);\r
+  }\r
+}\r
+\r
+/**\r
+  Lock the ConsoleIn device in system table. All key\r
+  presses will be ignored until the Password is typed in. The only way to\r
+  disable the password is to type it in to a ConIn device.\r
+\r
+  @param  Password        Password used to lock ConIn device.\r
+\r
+  @retval EFI_SUCCESS     lock the Console In Spliter virtual handle successfully.\r
+  @retval EFI_UNSUPPORTED Password not found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LockKeyboards (\r
+  IN  CHAR16    *Password\r
+  )\r
+{\r
+    return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Connect the predefined platform default authentication devices.\r
+\r
+  This function connects the predefined device path for authentication device,\r
+  and if the predefined device path has child device path, the child handle will\r
+  be connected too. But the child handle of the child will not be connected.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBdsConnectAuthDevice (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  UINTN                        Index;\r
+  UINTN                        HandleIndex;\r
+  UINTN                        HandleCount;\r
+  EFI_HANDLE                   *HandleBuffer;\r
+  EFI_DEVICE_PATH_PROTOCOL     *ChildDevicePath;\r
+  EFI_USER_MANAGER_PROTOCOL    *Manager;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiUserManagerProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &Manager\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // As user manager protocol is not installed, the authentication devices\r
+    // should not be connected.\r
+    //\r
+    return ;\r
+  }\r
+\r
+  Index = 0;\r
+  while (gUserAuthenticationDevice[Index] != NULL) {\r
+    //\r
+    // Connect the platform customized device paths\r
+    //\r
+    BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]);\r
+    Index++;\r
+  }\r
+\r
+  //\r
+  // Find and connect the child device paths of the platform customized device paths\r
+  //\r
+  HandleBuffer = NULL;\r
+  for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) {\r
+    HandleCount = 0;\r
+    Status = gBS->LocateHandleBuffer (\r
+                    AllHandles,\r
+                    NULL,\r
+                    NULL,\r
+                    &HandleCount,\r
+                    &HandleBuffer\r
+                    );\r
+    ASSERT (!EFI_ERROR (Status));\r
+\r
+    //\r
+    // Find and connect the child device paths of gUserIdentificationDevice[Index]\r
+    //\r
+    for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
+      ChildDevicePath = NULL;\r
+      Status = gBS->HandleProtocol (\r
+                      HandleBuffer[HandleIndex],\r
+                      &gEfiDevicePathProtocolGuid,\r
+                      (VOID **) &ChildDevicePath\r
+                      );\r
+      if (EFI_ERROR (Status) || ChildDevicePath == NULL) {\r
+        continue;\r
+      }\r
+\r
+      if (CompareMem (\r
+            ChildDevicePath,\r
+            gUserAuthenticationDevice[Index],\r
+            (GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL))\r
+            ) != 0) {\r
+        continue;\r
+      }\r
+      gBS->ConnectController (\r
+             HandleBuffer[HandleIndex],\r
+             NULL,\r
+             NULL,\r
+             TRUE\r
+             );\r
+    }\r
+  }\r
+\r
+  if (HandleBuffer != NULL) {\r
+    FreePool (HandleBuffer);\r
+  }\r
+}\r
+\r
+/**\r
+  This function is to identify a user, and return whether deferred images exist.\r
+\r
+  @param[out]  User               Point to user profile handle.\r
+  @param[out]  DeferredImageExist On return, points to TRUE if the deferred image\r
+                                  exist or FALSE if it did not exist.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBdsUserIdentify (\r
+  OUT EFI_USER_PROFILE_HANDLE        *User,\r
+  OUT BOOLEAN                        *DeferredImageExist\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_DEFERRED_IMAGE_LOAD_PROTOCOL   *DeferredImage;\r
+  UINTN                              HandleCount;\r
+  EFI_HANDLE                         *HandleBuf;\r
+  UINTN                              Index;\r
+  UINTN                              DriverIndex;\r
+  EFI_DEVICE_PATH_PROTOCOL           *ImageDevicePath;\r
+  VOID                               *DriverImage;\r
+  UINTN                              ImageSize;\r
+  BOOLEAN                            BootOption;\r
+\r
+  //\r
+  // Perform user identification\r
+  //\r
+  do {\r
+    Status = BdsLibUserIdentify (User);\r
+  } while (EFI_ERROR (Status));\r
+\r
+  //\r
+  // After user authentication now, try to find whether deferred image exists\r
+  //\r
+  HandleCount = 0;\r
+  HandleBuf   = NULL;\r
+  *DeferredImageExist = FALSE;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiDeferredImageLoadProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuf\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = gBS->HandleProtocol (\r
+                    HandleBuf[Index],\r
+                    &gEfiDeferredImageLoadProtocolGuid,\r
+                    (VOID **) &DeferredImage\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Find whether deferred image exists in this instance.\r
+      //\r
+      DriverIndex = 0;\r
+      Status = DeferredImage->GetImageInfo(\r
+                                DeferredImage,\r
+                                DriverIndex,\r
+                                &ImageDevicePath,\r
+                                (VOID **) &DriverImage,\r
+                                &ImageSize,\r
+                                &BootOption\r
+                                );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // The deferred image is found.\r
+        //\r
+        FreePool (HandleBuf);\r
+        *DeferredImageExist = TRUE;\r
+        return ;\r
+      }\r
+    }\r
+  }\r
+\r
+  FreePool (HandleBuf);\r
+}\r
+\r
+UINTN gHotKey = 0;\r
+\r
+\r
+EFI_STATUS\r
+ShowProgressHotKey (\r
+  IN UINT16                       TimeoutDefault\r
+  )\r
+{\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
+  UINT32                        GpioValue;\r
+\r
+  if (TimeoutDefault == 0) {\r
+    return EFI_TIMEOUT;\r
+  }\r
+\r
+  if (DebugAssertEnabled())\r
+  {\r
+    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it, or press <F2> or <DEL> to enter setup page! ...Zzz....\n"));\r
+  }\r
+  else\r
+  {  \r
+    #ifdef __GNUC__\r
+    SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76);\r
+    #else\r
+    SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71);\r
+    #endif\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
+  //\r
+  // Clear the progress status bar first\r
+  //\r
+  TmpStr = L"Start boot option, Press <F2> or <DEL> to enter setup page.";\r
+  PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);\r
+\r
+  TimeoutRemain = TimeoutDefault;\r
+  while (TimeoutRemain != 0) {\r
+    if (DebugAssertEnabled())\r
+    {\r
+    DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));\r
+    }\r
+    else\r
+    {  \r
+    SerialPortWrite ((UINT8 *)".", 1);\r
+    }\r
+    Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);\r
+    if (Status != EFI_TIMEOUT) {\r
+      break;\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
+    }\r
+  }\r
+\r
+  //\r
+  // Timeout expired\r
+  //\r
+  if (TimeoutRemain == 0) {\r
+    if (DebugAssertEnabled())\r
+       {\r
+       }\r
+    else\r
+    {  \r
+    SerialPortWrite ((UINT8 *)"\r\n", 2);\r
+    }\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
+\r
+  //\r
+  // Check Volume Up Key to enter Setup\r
+  //\r
+  GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668);  // The value of GPIOC_5\r
+  if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) {\r
+    gHotKey = 0;\r
+    return EFI_SUCCESS;\r
+  }\r
+\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
+  //F2 --  Front Page\r
+  //F5 --  Device Manager\r
+  //F7 --  Boot Manager\r
+  // do not use F8. generally people assume it is windows safe mode key.\r
+  //F9 --  Boot order\r
+  //\r
+  DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode));\r
+  switch(Key.ScanCode) {\r
+      case SCAN_F2:\r
+          gHotKey = 0;\r
+          break;\r
+\r
+      case SCAN_DELETE:\r
+          gHotKey = 0;\r
+          break;\r
+\r
+      case SCAN_F5:\r
+          gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;\r
+          break;\r
+\r
+      case SCAN_F7:\r
+          gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;\r
+          break;\r
+\r
+      case SCAN_F9:\r
+          gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;\r
+          break;\r
+\r
+      default:\r
+          //set gHotKey to continue so that flow will not go into CallFrontPage\r
+          gHotKey = FRONT_PAGE_KEY_CONTINUE;\r
+          return EFI_TIMEOUT;\r
+          break;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\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
+\r
+  @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 happened.\r
+\r
+**/\r
+VOID\r
+PlatformBdsEnterFrontPageWithHotKey (\r
+  IN UINT16                       TimeoutDefault,\r
+  IN BOOLEAN                      ConnectAllHappened\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL       *GraphicsOutput;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *SimpleTextOut;\r
+  UINTN                              BootTextColumn;\r
+  UINTN                              BootTextRow;\r
+\r
+  GraphicsOutput = NULL;\r
+  SimpleTextOut = NULL;\r
+\r
+  PERF_START (NULL, "BdsTimeOut", "BDS", 0);\r
+\r
+  //\r
+  // Indicate if we need connect all in the platform setup\r
+  //\r
+  if (ConnectAllHappened) {\r
+    gConnectAllHappened = TRUE;\r
+  }\r
+\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
+  if (TimeoutDefault != 0xffff) {\r
+    Status = ShowProgressHotKey (TimeoutDefault);\r
+\r
+    //\r
+    // Ensure screen is clear when switch Console from Graphics mode to Text mode\r
+    //\r
+    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
+    }\r
+  }\r
+\r
+  do {\r
+\r
+    BdsSetConsoleMode (TRUE);\r
+\r
+    InitializeFrontPage (FALSE);\r
+\r
+    //\r
+    // Update Front Page strings\r
+    //\r
+    UpdateFrontPageStrings ();\r
+\r
+    Status = EFI_SUCCESS;\r
+    gCallbackKey = 0;\r
+    if (gHotKey == 0) {\r
+      Status = CallFrontPage ();\r
+    } else {\r
+      gCallbackKey = gHotKey;\r
+      gHotKey = 0;\r
+    }\r
+\r
+    //\r
+    // If gCallbackKey is greater than 1 and less or equal to 5,\r
+    // it will launch configuration utilities.\r
+    // 2 = set language\r
+    // 3 = boot manager\r
+    // 4 = device manager\r
+    // 5 = boot maintenance manager\r
+    //\r
+    if (gCallbackKey != 0) {\r
+      REPORT_STATUS_CODE (\r
+        EFI_PROGRESS_CODE,\r
+        (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)\r
+        );\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 FRONT_PAGE_KEY_CONTINUE:\r
+\r
+      //\r
+      // User hit continue\r
+      //\r
+      break;\r
+\r
+    case FRONT_PAGE_KEY_LANGUAGE:\r
+\r
+      //\r
+      // User made a language setting change - display front page again\r
+      //\r
+      break;\r
+\r
+    case FRONT_PAGE_KEY_BOOT_MANAGER:\r
+\r
+      //\r
+      // User chose to run the Boot Manager\r
+      //\r
+      CallBootManager ();\r
+      break;\r
+\r
+    case FRONT_PAGE_KEY_DEVICE_MANAGER:\r
+\r
+      //\r
+      // Display the Device Manager\r
+      //\r
+      do {\r
+        CallDeviceManager ();\r
+      } while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER);\r
+      break;\r
+\r
+    case FRONT_PAGE_KEY_BOOT_MAINTAIN:\r
+\r
+      //\r
+      // Display the Boot Maintenance Manager\r
+      //\r
+      BdsStartBootMaint ();\r
+      break;\r
+    }\r
+\r
+  } while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE);\r
+\r
+  //\r
+  //Will leave browser, check any reset required change is applied? if yes, reset system\r
+  //\r
+  SetupResetReminder ();\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 (NULL, "BdsTimeOut", "BDS", 0);\r
+}\r
+\r
+\r
+VOID \r
+BootIntoFirmwareInterface(\r
+VOID\r
+)\r
+{\r
+  EFI_STATUS        Status;\r
+  UINTN             DataSize;\r
+  UINT16            Timeout;    \r
+  UINT64            OsIndication;\r
+\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
+  DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication));\r
+  //\r
+  //Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted.\r
+  //  \r
+  if (!EFI_ERROR(Status) && (OsIndication != 0)) {                               \r
+   Timeout = 0xffff;\r
+   PlatformBdsEnterFrontPage (Timeout, FALSE);\r
+   }\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PlatformBdsConnectSimpleConsole (\r
+  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
+)\r
+{\r
+  EFI_STATUS                         Status;\r
+  UINTN                              Index;\r
+  EFI_DEVICE_PATH_PROTOCOL           *VarConout;\r
+  EFI_DEVICE_PATH_PROTOCOL           *VarConin;\r
+  UINTN                              DevicePathSize;\r
+\r
+\r
+  Index = 0;\r
+  Status = EFI_SUCCESS;\r
+  DevicePathSize = 0;\r
+  VarConout = BdsLibGetVariableAndSize (\r
+                L"ConOut",\r
+                &gEfiGlobalVariableGuid,\r
+                &DevicePathSize\r
+                );\r
+  VarConin = BdsLibGetVariableAndSize (\r
+               L"ConIn",\r
+               &gEfiGlobalVariableGuid,\r
+               &DevicePathSize\r
+               );\r
+  if (VarConout == NULL || VarConin == NULL) {\r
+    //\r
+    // Have chance to connect the platform default console,\r
+    // the platform default console is the minimue device group\r
+    // the platform should support\r
+    //\r
+    while (PlatformConsole[Index].DevicePath != NULL) {\r
+\r
+      //\r
+      // Update the console variable with the connect type\r
+      //\r
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
+        BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);\r
+      }\r
+\r
+      if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
+        BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);\r
+      }\r
+\r
+      if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
+        BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);\r
+      }\r
+\r
+      Index ++;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Connect ConIn first to give keyboard time to parse hot key event.\r
+  //\r
+  Status = BdsLibConnectConsoleVariable (L"ConIn");\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Make sure we have at least one active VGA, and have the right\r
+  // active VGA in console variable\r
+  //\r
+  Status = PlatformBdsForceActiveVga ();\r
+\r
+  //\r
+  // It seems impossible not to have any ConOut device on platform,\r
+  // so we check the status here.\r
+  //\r
+  Status = BdsLibConnectConsoleVariable (L"ConOut");\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Timer handler to convert the key from USB.\r
+\r
+  @param  Event                    Indicates the event that invoke this function.\r
+  @param  Context                  Indicates the calling context.\r
+**/\r
+VOID\r
+EFIAPI\r
+HotKeyTimerHandler (\r
+  IN  EFI_EVENT                 Event,\r
+  IN  VOID                      *Context\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_INPUT_KEY                 Key;\r
+\r
+  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  switch(Key.ScanCode) {\r
+  case SCAN_F2:\r
+    gHotKey = 0;\r
+    mHotKeyPressed = TRUE;\r
+    break;\r
+\r
+  case SCAN_F5:\r
+    gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER;\r
+    mHotKeyPressed = TRUE;\r
+    break;\r
+\r
+  case SCAN_F7:\r
+    gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER;\r
+    mHotKeyPressed = TRUE;\r
+    break;\r
+\r
+  case SCAN_F9:\r
+    gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN;\r
+    mHotKeyPressed = TRUE;\r
+    break;\r
+  }\r
+\r
+  if (mHotKeyPressed) {\r
+    gBS->SetTimer (\r
+           mHotKeyTimerEvent,\r
+           TimerCancel,\r
+           0\r
+           );\r
+    gBS->CloseEvent (mHotKeyTimerEvent);\r
+    mHotKeyTimerEvent = NULL;\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+\r
+/**\r
+  Callback function for SimpleTextInEx protocol install events\r
+\r
+  @param Event           the event that is signaled.\r
+  @param Context         not used here.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+HitHotkeyEvent (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+\r
+  Status = gBS->CloseEvent(mHitHotkeyEvent);\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+  Status = gBS->CreateEvent (\r
+                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  HotKeyTimerHandler,\r
+                  NULL,\r
+                  &mHotKeyTimerEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+  Status = gBS->SetTimer (\r
+                  mHotKeyTimerEvent,\r
+                  TimerPeriodic,\r
+                  KEYBOARD_TIMER_INTERVAL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+PlatformBdsInitHotKeyEvent (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+\r
+  //\r
+  // Register Protocol notify for Hotkey service\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  HitHotkeyEvent,\r
+                  NULL,\r
+                  &mHitHotkeyEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Register for protocol notifications on this event\r
+  //\r
+  Status = gBS->RegisterProtocolNotify (\r
+                  &gEfiSimpleTextInputExProtocolGuid,\r
+                  mHitHotkeyEvent,\r
+                  &mHitHotkeyRegistration\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r