]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
OvmfPkg/PlatformBootManagerLib: hoist PciAcpiInitialization()
[mirror_edk2.git] / OvmfPkg / Library / PlatformBootManagerLib / BdsPlatform.c
index ea0ae1ecd70ff02ed09bf65b6b599f331b30b581..b624b8f2253545171ee04a176091a8032da31108 100644 (file)
@@ -2,19 +2,20 @@
   Platform BDS customizations.\r
 \r
   Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
+  This program and the accompanying materials are licensed and made available\r
+  under the terms and conditions of the BSD License which accompanies this\r
+  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
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
 #include "BdsPlatform.h"\r
+#include <Guid/XenInfo.h>\r
 #include <Guid/RootBridgesConnectedEventGroup.h>\r
-#include <Library/QemuBootOrderLib.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
 \r
 \r
 //\r
@@ -36,11 +37,6 @@ CONST UINT8 PciHostIrqs[] = {
   0x0a, 0x0a, 0x0b, 0x0b\r
 };\r
 \r
-//\r
-// Array Size macro\r
-//\r
-#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))\r
-\r
 //\r
 // Type definitions\r
 //\r
@@ -88,6 +84,233 @@ InstallDevicePathCallback (
   VOID\r
   );\r
 \r
+VOID\r
+PlatformRegisterFvBootOption (\r
+  EFI_GUID                         *FileGuid,\r
+  CHAR16                           *Description,\r
+  UINT32                           Attributes\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  INTN                              OptionIndex;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;\r
+  UINTN                             BootOptionCount;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
+  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  gImageHandle,\r
+                  &gEfiLoadedImageProtocolGuid,\r
+                  (VOID **) &LoadedImage\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
+  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);\r
+  ASSERT (DevicePath != NULL);\r
+  DevicePath = AppendDevicePathNode (\r
+                 DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
+                 );\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  Status = EfiBootManagerInitializeLoadOption (\r
+             &NewOption,\r
+             LoadOptionNumberUnassigned,\r
+             LoadOptionTypeBoot,\r
+             Attributes,\r
+             Description,\r
+             DevicePath,\r
+             NULL,\r
+             0\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+  FreePool (DevicePath);\r
+\r
+  BootOptions = EfiBootManagerGetLoadOptions (\r
+                  &BootOptionCount, LoadOptionTypeBoot\r
+                  );\r
+\r
+  OptionIndex = EfiBootManagerFindLoadOption (\r
+                  &NewOption, BootOptions, BootOptionCount\r
+                  );\r
+\r
+  if (OptionIndex == -1) {\r
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  EfiBootManagerFreeLoadOption (&NewOption);\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+}\r
+\r
+/**\r
+  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options\r
+  whose device paths do not resolve exactly to an FvFile in the system.\r
+\r
+  This removes any boot options that point to binaries built into the firmware\r
+  and have become stale due to any of the following:\r
+  - DXEFV's base address or size changed (historical),\r
+  - DXEFV's FvNameGuid changed,\r
+  - the FILE_GUID of the pointed-to binary changed,\r
+  - the referenced binary is no longer built into the firmware.\r
+\r
+  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only\r
+  avoids exact duplicates.\r
+**/\r
+VOID\r
+RemoveStaleFvFileOptions (\r
+  VOID\r
+  )\r
+{\r
+  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
+  UINTN                        BootOptionCount;\r
+  UINTN                        Index;\r
+\r
+  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,\r
+                  LoadOptionTypeBoot);\r
+\r
+  for (Index = 0; Index < BootOptionCount; ++Index) {\r
+    EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;\r
+    EFI_STATUS               Status;\r
+    EFI_HANDLE               FvHandle;\r
+\r
+    //\r
+    // If the device path starts with neither MemoryMapped(...) nor Fv(...),\r
+    // then keep the boot option.\r
+    //\r
+    Node1 = BootOptions[Index].FilePath;\r
+    if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&\r
+          DevicePathSubType (Node1) == HW_MEMMAP_DP) &&\r
+        !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&\r
+          DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // If the second device path node is not FvFile(...), then keep the boot\r
+    // option.\r
+    //\r
+    Node2 = NextDevicePathNode (Node1);\r
+    if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||\r
+        DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Locate the Firmware Volume2 protocol instance that is denoted by the\r
+    // boot option. If this lookup fails (i.e., the boot option references a\r
+    // firmware volume that doesn't exist), then we'll proceed to delete the\r
+    // boot option.\r
+    //\r
+    SearchNode = Node1;\r
+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,\r
+                    &SearchNode, &FvHandle);\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // The firmware volume was found; now let's see if it contains the FvFile\r
+      // identified by GUID.\r
+      //\r
+      EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol;\r
+      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;\r
+      UINTN                             BufferSize;\r
+      EFI_FV_FILETYPE                   FoundType;\r
+      EFI_FV_FILE_ATTRIBUTES            FileAttributes;\r
+      UINT32                            AuthenticationStatus;\r
+\r
+      Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,\r
+                      (VOID **)&FvProtocol);\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;\r
+      //\r
+      // Buffer==NULL means we request metadata only: BufferSize, FoundType,\r
+      // FileAttributes.\r
+      //\r
+      Status = FvProtocol->ReadFile (\r
+                             FvProtocol,\r
+                             &FvFileNode->FvFileName, // NameGuid\r
+                             NULL,                    // Buffer\r
+                             &BufferSize,\r
+                             &FoundType,\r
+                             &FileAttributes,\r
+                             &AuthenticationStatus\r
+                             );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // The FvFile was found. Keep the boot option.\r
+        //\r
+        continue;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Delete the boot option.\r
+    //\r
+    Status = EfiBootManagerDeleteLoadOptionVariable (\r
+               BootOptions[Index].OptionNumber, LoadOptionTypeBoot);\r
+    DEBUG_CODE (\r
+      CHAR16 *DevicePathString;\r
+\r
+      DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,\r
+                           FALSE, FALSE);\r
+      DEBUG ((\r
+        EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,\r
+        "%a: removing stale Boot#%04x %s: %r\n",\r
+        __FUNCTION__,\r
+        (UINT32)BootOptions[Index].OptionNumber,\r
+        DevicePathString == NULL ? L"<unavailable>" : DevicePathString,\r
+        Status\r
+        ));\r
+      if (DevicePathString != NULL) {\r
+        FreePool (DevicePathString);\r
+      }\r
+      );\r
+  }\r
+\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+}\r
+\r
+VOID\r
+PlatformRegisterOptionsAndKeys (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_INPUT_KEY                Enter;\r
+  EFI_INPUT_KEY                F2;\r
+  EFI_INPUT_KEY                Esc;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
+\r
+  //\r
+  // Register ENTER as CONTINUE key\r
+  //\r
+  Enter.ScanCode    = SCAN_NULL;\r
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
+  Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Map F2 to Boot Manager Menu\r
+  //\r
+  F2.ScanCode     = SCAN_F2;\r
+  F2.UnicodeChar  = CHAR_NULL;\r
+  Esc.ScanCode    = SCAN_ESC;\r
+  Esc.UnicodeChar = CHAR_NULL;\r
+  Status = EfiBootManagerGetBootManagerMenu (&BootOption);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = EfiBootManagerAddKeyOptionVariable (\r
+             NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL\r
+             );\r
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
+  Status = EfiBootManagerAddKeyOptionVariable (\r
+             NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL\r
+             );\r
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 ConnectRootBridge (\r
@@ -105,28 +328,28 @@ SaveS3BootScript (
 //\r
 // BDS Platform Functions\r
 //\r
+/**\r
+  Do the platform init, can be customized by OEM/IBV\r
+\r
+  Possible things that can be done in PlatformBootManagerBeforeConsole:\r
+\r
+  > Update console variable: 1. include hot-plug devices;\r
+  >                          2. Clear ConIn and add SOL for AMT\r
+  > Register new Driver#### or Boot####\r
+  > Register new Key####: e.g.: F12\r
+  > Signal ReadyToLock event\r
+  > Authentication action: 1. connect Auth devices;\r
+  >                        2. Identify auto logon user.\r
+**/\r
 VOID\r
 EFIAPI\r
 PlatformBootManagerBeforeConsole (\r
   VOID\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Platform Bds init. Incude the platform firmware vendor, revision\r
-  and so crc check.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
 {\r
-  EFI_HANDLE Handle;\r
-  EFI_STATUS Status;\r
+  EFI_HANDLE    Handle;\r
+  EFI_STATUS    Status;\r
+  RETURN_STATUS PcdStatus;\r
 \r
   DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));\r
   InstallDevicePathCallback ();\r
@@ -164,6 +387,19 @@ Returns:
                   &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,\r
                   NULL);\r
   ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Dispatch deferred images after EndOfDxe event and ReadyToLock\r
+  // installation.\r
+  //\r
+  EfiBootManagerDispatchDeferredImages ();\r
+\r
+  PlatformInitializeConsole (gPlatformConsole);\r
+  PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,\r
+                GetFrontPageTimeoutFromQemu ());\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+  PlatformRegisterOptionsAndKeys ();\r
 }\r
 \r
 \r
@@ -192,28 +428,21 @@ ConnectRootBridge (
 }\r
 \r
 \r
+/**\r
+  Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.\r
+\r
+  @param[in] DeviceHandle  Handle of the LPC Bridge device.\r
+\r
+  @retval EFI_SUCCESS  Console devices on the LPC bridge have been added to\r
+                       ConOut, ConIn, and ErrOut.\r
+\r
+  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
+                       from DeviceHandle.\r
+**/\r
 EFI_STATUS\r
 PrepareLpcBridgeDevicePath (\r
   IN EFI_HANDLE                DeviceHandle\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Add IsaKeyboard to ConIn,\r
-  add IsaSerial to ConOut, ConIn, ErrOut.\r
-  LPC Bridge: 06 01 00\r
-\r
-Arguments:\r
-\r
-  DeviceHandle            - Handle of PCIIO protocol.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS             - LPC bridge is added to ConOut, ConIn, and ErrOut.\r
-  EFI_STATUS              - No LPC bridge is added.\r
-\r
---*/\r
 {\r
   EFI_STATUS                Status;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
@@ -234,7 +463,8 @@ Returns:
   //\r
   // Register Keyboard\r
   //\r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
 \r
   EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
 \r
@@ -244,14 +474,17 @@ Returns:
   DevicePath = TempDevicePath;\r
   gPnp16550ComPortDeviceNode.UID = 0;\r
 \r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
 \r
   //\r
   // Print Device Path\r
   //\r
-  DevPathStr = DevicePathToStr(DevicePath);\r
+  DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
   if (DevPathStr != NULL) {\r
     DEBUG((\r
       EFI_D_INFO,\r
@@ -273,14 +506,17 @@ Returns:
   DevicePath = TempDevicePath;\r
   gPnp16550ComPortDeviceNode.UID = 1;\r
 \r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
 \r
   //\r
   // Print Device Path\r
   //\r
-  DevPathStr = DevicePathToStr(DevicePath);\r
+  DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
   if (DevPathStr != NULL) {\r
     DEBUG((\r
       EFI_D_INFO,\r
@@ -333,7 +569,7 @@ GetGopDevicePath (
   }\r
 \r
   //\r
-  // Try to connect this handle, so that GOP dirver could start on this\r
+  // Try to connect this handle, so that GOP driver 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
@@ -352,7 +588,8 @@ GetGopDevicePath (
     // Add all the child handles as possible Console Device\r
     //\r
     for (Index = 0; Index < GopHandleCount; Index++) {\r
-      Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
+      Status = gBS->HandleProtocol (GopHandleBuffer[Index],\r
+                      &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
       if (EFI_ERROR (Status)) {\r
         continue;\r
       }\r
@@ -365,14 +602,14 @@ GetGopDevicePath (
         // 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
+        // In future, we could select all child handles to be console device\r
         //\r
 \r
         *GopDevicePath = TempDevicePath;\r
 \r
         //\r
-        // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
-        // Add the integrity GOP device path.\r
+        // Delete the PCI device's path that added by\r
+        // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.\r
         //\r
         EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);\r
         EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);\r
@@ -384,27 +621,20 @@ GetGopDevicePath (
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-PreparePciVgaDevicePath (\r
-  IN EFI_HANDLE                DeviceHandle\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Add PCI VGA to ConOut.\r
-  PCI VGA: 03 00 00\r
-\r
-Arguments:\r
-\r
-  DeviceHandle            - Handle of PCIIO protocol.\r
+/**\r
+  Add PCI display to ConOut.\r
 \r
-Returns:\r
+  @param[in] DeviceHandle  Handle of the PCI display device.\r
 \r
-  EFI_SUCCESS             - PCI VGA is added to ConOut.\r
-  EFI_STATUS              - No PCI VGA device is added.\r
+  @retval EFI_SUCCESS  The PCI display device has been added to ConOut.\r
 \r
---*/\r
+  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
+                       from DeviceHandle.\r
+**/\r
+EFI_STATUS\r
+PreparePciDisplayDevicePath (\r
+  IN EFI_HANDLE                DeviceHandle\r
+  )\r
 {\r
   EFI_STATUS                Status;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
@@ -429,27 +659,21 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-PreparePciSerialDevicePath (\r
-  IN EFI_HANDLE                DeviceHandle\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Add PCI Serial to ConOut, ConIn, ErrOut.\r
-  PCI Serial: 07 00 02\r
-\r
-Arguments:\r
 \r
-  DeviceHandle            - Handle of PCIIO protocol.\r
+  @param[in] DeviceHandle  Handle of the PCI serial device.\r
 \r
-Returns:\r
+  @retval EFI_SUCCESS  The PCI serial device has been added to ConOut, ConIn,\r
+                       ErrOut.\r
 \r
-  EFI_SUCCESS             - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
-  EFI_STATUS              - No PCI Serial device is added.\r
-\r
---*/\r
+  @return              Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
+                       from DeviceHandle.\r
+**/\r
+EFI_STATUS\r
+PreparePciSerialDevicePath (\r
+  IN EFI_HANDLE                DeviceHandle\r
+  )\r
 {\r
   EFI_STATUS                Status;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
@@ -464,8 +688,10 @@ Returns:
     return Status;\r
   }\r
 \r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
-  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
 \r
   EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
   EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
@@ -581,7 +807,8 @@ VisitAllPciInstances (
   @param[in]  PciIo - PCI IO protocol instance\r
   @param[in]  Pci - PCI Header register block\r
 \r
-  @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+  @retval EFI_SUCCESS - PCI Device check and Console variable update\r
+                        successfully.\r
   @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
 \r
 **/\r
@@ -635,14 +862,14 @@ DetectAndPreparePlatformPciDevicePath (
   }\r
 \r
   //\r
-  // Here we decide which VGA device to enable in PCI bus\r
+  // Here we decide which display device to enable in PCI bus\r
   //\r
-  if (IS_PCI_VGA (Pci)) {\r
+  if (IS_PCI_DISPLAY (Pci)) {\r
     //\r
     // Add them to ConOut.\r
     //\r
-    DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
-    PreparePciVgaDevicePath (Handle);\r
+    DEBUG ((EFI_D_INFO, "Found PCI display device\n"));\r
+    PreparePciDisplayDevicePath (Handle);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -655,7 +882,8 @@ DetectAndPreparePlatformPciDevicePath (
 \r
   @param[in]  DetectVgaOnly - Only detect VGA device if it's TRUE.\r
 \r
-  @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+  @retval EFI_SUCCESS - PCI Device check and Console variable update\r
+                        successfully.\r
   @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
 \r
 **/\r
@@ -669,61 +897,39 @@ DetectAndPreparePlatformPciDevicePaths (
 }\r
 \r
 \r
-EFI_STATUS\r
-PlatformBdsConnectConsole (\r
-  IN BDS_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Connect the predefined platform default console device. Always try to find\r
-  and enable the vga device if have.\r
-\r
-Arguments:\r
-\r
-  PlatformConsole         - Predfined platform default console device array.\r
-\r
-Returns:\r
-\r
-  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
+  Connect the predefined platform default console device.\r
 \r
-  EFI_STATUS              - Return the status of\r
-                            BdsLibConnectAllDefaultConsoles ()\r
+  Always try to find and enable PCI display devices.\r
 \r
---*/\r
+  @param[in] PlatformConsole  Predefined platform default console device array.\r
+**/\r
+VOID\r
+PlatformInitializeConsole (\r
+  IN PLATFORM_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
   // Connect RootBridge\r
   //\r
-  VarConout = BdsLibGetVariableAndSize (\r
-                VarConsoleOut,\r
-                &gEfiGlobalVariableGuid,\r
-                &DevicePathSize\r
-                );\r
-  VarConin = BdsLibGetVariableAndSize (\r
-               VarConsoleInp,\r
-               &gEfiGlobalVariableGuid,\r
-               &DevicePathSize\r
-               );\r
+  GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout,\r
+    NULL);\r
+  GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);\r
 \r
   if (VarConout == NULL || VarConin == NULL) {\r
     //\r
-    // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
+    // Do platform specific PCI Device check and add them to ConOut, ConIn,\r
+    // ErrOut\r
     //\r
     DetectAndPreparePlatformPciDevicePaths (FALSE);\r
 \r
     //\r
     // Have chance to connect the platform default console,\r
-    // the platform default console is the minimue device group\r
+    // the platform default console is the minimum device group\r
     // the platform should support\r
     //\r
     for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
@@ -731,13 +937,16 @@ Returns:
       // Update the console variable with the connect type\r
       //\r
       if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
-        EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL);\r
+        EfiBootManagerUpdateConsoleVariable (ConIn,\r
+          PlatformConsole[Index].DevicePath, NULL);\r
       }\r
       if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
-        EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL);\r
+        EfiBootManagerUpdateConsoleVariable (ConOut,\r
+          PlatformConsole[Index].DevicePath, NULL);\r
       }\r
       if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
-        EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL);\r
+        EfiBootManagerUpdateConsoleVariable (ErrOut,\r
+          PlatformConsole[Index].DevicePath, NULL);\r
       }\r
     }\r
   } else {\r
@@ -746,16 +955,6 @@ Returns:
     //\r
     DetectAndPreparePlatformPciDevicePaths (TRUE);\r
   }\r
-\r
-  //\r
-  // Connect the all the default console with current cosole variable\r
-  //\r
-  Status = BdsLibConnectAllDefaultConsoles ();\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
 }\r
 \r
 \r
@@ -964,6 +1163,37 @@ PciAcpiInitialization (
   IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
 }\r
 \r
+/**\r
+  This function detects if OVMF is running on Xen.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+XenDetected (\r
+  VOID\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE         *GuidHob;\r
+  STATIC INTN               FoundHob = -1;\r
+\r
+  if (FoundHob == 0) {\r
+    return FALSE;\r
+  } else if (FoundHob == 1) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // See if a XenInfo HOB is available\r
+  //\r
+  GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);\r
+  if (GuidHob == NULL) {\r
+    FoundHob = 0;\r
+    return FALSE;\r
+  }\r
+\r
+  FoundHob = 1;\r
+  return TRUE;\r
+}\r
 \r
 EFI_STATUS\r
 EFIAPI\r
@@ -977,7 +1207,11 @@ ConnectRecursivelyIfPciMassStorage (
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
   CHAR16                    *DevPathStr;\r
 \r
-  if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
+  //\r
+  // Recognize PCI Mass Storage, and Xen PCI devices\r
+  //\r
+  if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ||\r
+      (XenDetected() && IS_CLASS2 (PciHeader, 0xFF, 0x80))) {\r
     DevicePath = NULL;\r
     Status = gBS->HandleProtocol (\r
                     Handle,\r
@@ -991,11 +1225,15 @@ ConnectRecursivelyIfPciMassStorage (
     //\r
     // Print Device Path\r
     //\r
-    DevPathStr = DevicePathToStr (DevicePath);\r
+    DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
     if (DevPathStr != NULL) {\r
       DEBUG((\r
         EFI_D_INFO,\r
-        "Found Mass Storage device: %s\n",\r
+        "Found %s device: %s\n",\r
+        (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?\r
+         L"Mass Storage" :\r
+         L"Xen"\r
+         ),\r
         DevPathStr\r
         ));\r
       FreePool(DevPathStr);\r
@@ -1016,8 +1254,8 @@ ConnectRecursivelyIfPciMassStorage (
   This notification function is invoked when the\r
   EMU Variable FVB has been changed.\r
 \r
-  @param  Event                 The event that occured\r
-  @param  Context               For EFI compatiblity.  Not used.\r
+  @param  Event                 The event that occurred\r
+  @param  Context               For EFI compatibility.  Not used.\r
 \r
 **/\r
 VOID\r
@@ -1042,6 +1280,7 @@ VisitingFileSystemInstance (
 {\r
   EFI_STATUS      Status;\r
   STATIC BOOLEAN  ConnectedToFileSystem = FALSE;\r
+  RETURN_STATUS   PcdStatus;\r
 \r
   if (ConnectedToFileSystem) {\r
     return EFI_ALREADY_STARTED;\r
@@ -1061,7 +1300,9 @@ VisitingFileSystemInstance (
       NULL,\r
       &mEmuVariableEventReg\r
       );\r
-  PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
+  PcdStatus = PcdSet64S (PcdEmuVariableEvent,\r
+                (UINT64)(UINTN) mEmuVariableEvent);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1080,29 +1321,18 @@ PlatformBdsRestoreNvVarsFromHardDisk (
 \r
 }\r
 \r
+/**\r
+  Connect with predefined platform connect sequence.\r
 \r
+  The OEM/IBV can customize with their own connect sequence.\r
+**/\r
 VOID\r
 PlatformBdsConnectSequence (\r
   VOID\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Connect with predeined platform connect sequence,\r
-  the OEM/IBV can customize with their own connect sequence.\r
-\r
-Arguments:\r
-\r
-  None.\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
 {\r
-  UINTN Index;\r
+  UINTN         Index;\r
+  RETURN_STATUS Status;\r
 \r
   DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
 \r
@@ -1117,104 +1347,20 @@ Returns:
     //\r
     // Build the platform boot option\r
     //\r
-    BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
+    EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);\r
     Index++;\r
   }\r
 \r
-  //\r
-  // Just use the simple policy to connect all devices\r
-  //\r
-  BdsLibConnectAll ();\r
-\r
-  PciAcpiInitialization ();\r
-\r
-  //\r
-  // Clear the logo after all devices are connected.\r
-  //\r
-  gST->ConOut->ClearScreen (gST->ConOut);\r
-}\r
-\r
-VOID\r
-PlatformBdsGetDriverOption (\r
-  IN OUT LIST_ENTRY              *BdsDriverLists\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Load the predefined driver option, OEM/IBV can customize this\r
-  to load their own drivers\r
-\r
-Arguments:\r
-\r
-  BdsDriverLists  - The header of the driver option link list.\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
-{\r
-  DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));\r
-  return;\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
-\r
-Routine Description:\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
-Arguments:\r
-\r
-  MemoryTestLevel  - The memory test intensive level\r
-\r
-  QuietBoot        - Indicate if need to enable the quiet boot\r
-\r
-  BaseMemoryTest   - A pointer to BaseMemoryTest()\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\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
+  Status = ConnectDevicesFromQemu ();\r
+  if (RETURN_ERROR (Status)) {\r
     //\r
-    // Perform system diagnostic\r
+    // Just use the simple policy to connect all devices\r
     //\r
-    Status = BaseMemoryTest (MemoryTestLevel);\r
-    if (EFI_ERROR (Status)) {\r
-      DisableQuietBoot ();\r
-    }\r
-\r
-    return ;\r
+    DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n"));\r
+    EfiBootManagerConnectAll ();\r
   }\r
-  //\r
-  // Perform system diagnostic\r
-  //\r
-  Status = BaseMemoryTest (MemoryTestLevel);\r
 }\r
 \r
-\r
 /**\r
   Save the S3 boot script.\r
 \r
@@ -1247,22 +1393,25 @@ SaveS3BootScript (
 }\r
 \r
 \r
+/**\r
+  Do the platform specific action after the console is ready\r
+\r
+  Possible things that can be done in PlatformBootManagerAfterConsole:\r
+\r
+  > Console post action:\r
+    > Dynamically switch output mode from 100x31 to 80x25 for certain senarino\r
+    > Signal console ready platform customized event\r
+  > Run diagnostics like memory testing\r
+  > Connect certain devices\r
+  > Dispatch aditional option roms\r
+  > Special boot: e.g.: USB boot, enter UI\r
+**/\r
 VOID\r
 EFIAPI\r
 PlatformBootManagerAfterConsole (\r
   VOID\r
   )\r
-/*++\r
-\r
-Routine Description:\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
---*/\r
 {\r
-  EFI_STATUS                         Status;\r
   EFI_BOOT_MODE                      BootMode;\r
 \r
   DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));\r
@@ -1278,37 +1427,27 @@ Routine Description:
     PlatformBdsRestoreNvVarsFromHardDisk ();\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
-  Status = BdsLibGetBootMode (&BootMode);\r
-  DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
+  BootMode = GetBootModeHob ();\r
+  DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode));\r
 \r
   //\r
   // Go the different platform policy with different boot mode\r
   // Notes: this part code can be change with the table policy\r
   //\r
   ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
+\r
   //\r
-  // Connect platform console\r
+  // Logo show\r
   //\r
-  Status = PlatformBdsConnectConsole (gPlatformConsole);\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // Here OEM/IBV can customize with defined action\r
-    //\r
-    PlatformBdsNoConsoleAction ();\r
-  }\r
+  BootLogoEnableLogo ();\r
 \r
   //\r
-  // Memory test and Logo show\r
+  // Set PCI Interrupt Line registers and ACPI SCI_EN\r
   //\r
-  PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
+  PciAcpiInitialization ();\r
 \r
   //\r
   // Perform some platform specific connect sequence\r
@@ -1320,145 +1459,25 @@ Routine Description:
   //\r
   TryRunningQemuKernel ();\r
 \r
-  DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
-  BdsLibConnectAll ();\r
-  BdsLibEnumerateAllBootOption (BootOptionList);\r
-\r
-  SetBootOrderFromQemu (BootOptionList);\r
-  //\r
-  // The BootOrder variable may have changed, reload the in-memory list with\r
-  // it.\r
-  //\r
-  BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
-\r
-  PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE);\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-PlatformBdsBootSuccess (\r
-  IN  BDS_COMMON_OPTION   *Option\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Hook point after a boot attempt succeeds. We don't expect a boot option to\r
-  return, so the EFI 1.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
-Arguments:\r
-\r
-  Option - Pointer to Boot Option that succeeded to boot.\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
-{\r
-  CHAR16  *TmpStr;\r
-\r
-  DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\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
-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
-\r
-Routine Description:\r
-\r
-  Hook point after a boot attempt fails.\r
-\r
-Arguments:\r
-\r
-  Option - Pointer to Boot Option that failed to boot.\r
-\r
-  Status - Status returned from failed boot.\r
-\r
-  ExitData - Exit data returned from failed boot.\r
-\r
-  ExitDataSize - Exit data size returned from failed boot.\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
-{\r
-  CHAR16  *TmpStr;\r
-\r
-  DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
+  EfiBootManagerRefreshAllBootOption ();\r
 \r
   //\r
-  // If Boot returned with failed status then we need to pop up a UI and wait\r
-  // for user input.\r
+  // Register UEFI Shell\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
-EFI_STATUS\r
-PlatformBdsNoConsoleAction (\r
-  VOID\r
-  )\r
-/*++\r
-\r
-Routine Description:\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
-Arguments:\r
-\r
-  None.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS      - Direct return success now.\r
+  PlatformRegisterFvBootOption (\r
+    PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE\r
+    );\r
 \r
---*/\r
-{\r
-  DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
-  return EFI_SUCCESS;\r
+  RemoveStaleFvFileOptions ();\r
+  SetBootOrderFromQemu ();\r
 }\r
 \r
-VOID\r
-EFIAPI\r
-PlatformBdsLockNonUpdatableFlash (\r
-  VOID\r
-  )\r
-{\r
-  DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
-  return;\r
-}\r
-\r
-\r
 /**\r
   This notification function is invoked when an instance of the\r
   EFI_DEVICE_PATH_PROTOCOL is produced.\r
 \r
-  @param  Event                 The event that occured\r
-  @param  Context               For EFI compatiblity.  Not used.\r
+  @param  Event                 The event that occurred\r
+  @param  Context               For EFI compatibility.  Not used.\r
 \r
 **/\r
 VOID\r
@@ -1504,7 +1523,8 @@ NotifyDevPath (
     //\r
     // Get the DevicePath protocol on that handle\r
     //\r
-    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,\r
+                    (VOID **)&DevPathNode);\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     while (!IsDevicePathEnd (DevPathNode)) {\r
@@ -1554,7 +1574,8 @@ InstallDevicePathCallback (
 }\r
 \r
 /**\r
-  This function is called each second during the boot manager waits the timeout.\r
+  This function is called each second during the boot manager waits the\r
+  timeout.\r
 \r
   @param TimeoutRemain  The remaining timeout.\r
 **/\r
@@ -1564,25 +1585,22 @@ PlatformBootManagerWaitCallback (
   UINT16          TimeoutRemain\r
   )\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
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
+  UINT16                              Timeout;\r
+\r
+  Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
+\r
+  Black.Raw = 0x00000000;\r
+  White.Raw = 0x00FFFFFF;\r
+\r
+  BootLogoUpdateProgress (\r
+    White.Pixel,\r
+    Black.Pixel,\r
+    L"Start boot option",\r
+    White.Pixel,\r
+    (Timeout - TimeoutRemain) * 100 / Timeout,\r
+    0\r
+    );\r
 }\r
 \r