diff mbox series

[Linaro-uefi,8/9] Platforms/Hisilicon/HiKey: add platform boot manager

Message ID 1486185234-23675-9-git-send-email-haojian.zhuang@linaro.org
State Superseded
Headers show
Series enable Android Fastboot App on HiKey | expand

Commit Message

Haojian Zhuang Feb. 4, 2017, 5:13 a.m. UTC
Add the platform boot manager to boot Android Fastboot.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 OpenPlatformPkg.dec                                |   1 +
 .../Library/PlatformBootManagerLib/PlatformBm.c    | 485 +++++++++++++++
 .../Library/PlatformBootManagerLib/PlatformBm.h    |  59 ++
 .../PlatformBootManagerLib.inf                     |  88 +++
 .../Library/PlatformBootManagerLib/QuietBoot.c     | 680 +++++++++++++++++++++
 5 files changed, 1313 insertions(+)
 create mode 100644 Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c
 create mode 100644 Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.h
 create mode 100644 Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platforms/Hisilicon/Library/PlatformBootManagerLib/QuietBoot.c
diff mbox series

Patch

diff --git a/OpenPlatformPkg.dec b/OpenPlatformPkg.dec
index 2db143d..e82b4d4 100644
--- a/OpenPlatformPkg.dec
+++ b/OpenPlatformPkg.dec
@@ -39,5 +39,6 @@ 
 [PcdsFixedAtBuild]
   ## Indicates the size in MB for RAM disk.
   gOpenPlatformTokenSpaceGuid.PcdRamDiskMaxSize|0|UINT32|0x00000001
+  gOpenPlatformTokenSpaceGuid.PcdAndroidFastbootFile|{ 0x2a, 0x50, 0x88, 0x95, 0x70, 0x53, 0xe3, 0x11, 0x86, 0x31, 0xd7, 0xc5, 0x95, 0x13, 0x64, 0xc8 }|VOID*|0x00000002
 
 [PcdsFeatureFlag]
diff --git a/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c b/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c
new file mode 100644
index 0000000..03b764d
--- /dev/null
+++ b/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.c
@@ -0,0 +1,485 @@ 
+/** @file
+  Implementation for PlatformBootManagerLib library class interfaces.
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016-2017, Linaro Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution. The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/LoadedImage.h>
+#include <Guid/EventGroup.h>
+#include <Guid/TtyTerm.h>
+
+#include "PlatformBm.h"
+
+#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) }
+
+
+#pragma pack (1)
+typedef struct {
+  VENDOR_DEVICE_PATH         SerialDxe;
+  UART_DEVICE_PATH           Uart;
+  VENDOR_DEFINED_DEVICE_PATH TermType;
+  EFI_DEVICE_PATH_PROTOCOL   End;
+} PLATFORM_SERIAL_CONSOLE;
+#pragma pack ()
+
+#define SERIAL_DXE_FILE_GUID { \
+          0xD3987D4B, 0x971A, 0x435F, \
+          { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } \
+          }
+
+STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = {
+  //
+  // VENDOR_DEVICE_PATH SerialDxe
+  //
+  {
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) },
+    SERIAL_DXE_FILE_GUID
+  },
+
+  //
+  // UART_DEVICE_PATH Uart
+  //
+  {
+    { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) },
+    0,                                      // Reserved
+    FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate
+    FixedPcdGet8 (PcdUartDefaultDataBits),  // DataBits
+    FixedPcdGet8 (PcdUartDefaultParity),    // Parity
+    FixedPcdGet8 (PcdUartDefaultStopBits)   // StopBits
+  },
+
+  //
+  // VENDOR_DEFINED_DEVICE_PATH TermType
+  //
+  {
+    {
+      MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,
+      DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)
+    }
+    //
+    // Guid to be filled in dynamically
+    //
+  },
+
+  //
+  // EFI_DEVICE_PATH_PROTOCOL End
+  //
+  {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
+  }
+};
+
+
+#pragma pack (1)
+typedef struct {
+  USB_CLASS_DEVICE_PATH    Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_USB_KEYBOARD;
+#pragma pack ()
+
+STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
+  //
+  // USB_CLASS_DEVICE_PATH Keyboard
+  //
+  {
+    {
+      MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,
+      DP_NODE_LEN (USB_CLASS_DEVICE_PATH)
+    },
+    0xFFFF, // VendorId: any
+    0xFFFF, // ProductId: any
+    3,      // DeviceClass: HID
+    1,      // DeviceSubClass: boot
+    1       // DeviceProtocol: keyboard
+  },
+
+  //
+  // EFI_DEVICE_PATH_PROTOCOL End
+  //
+  {
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
+  }
+};
+
+
+/**
+  Check if the handle satisfies a particular condition.
+
+  @param[in] Handle      The handle to check.
+  @param[in] ReportText  A caller-allocated string passed in for reporting
+                         purposes. It must never be NULL.
+
+  @retval TRUE   The condition is satisfied.
+  @retval FALSE  Otherwise. This includes the case when the condition could not
+                 be fully evaluated due to an error.
+**/
+typedef
+BOOLEAN
+(EFIAPI *FILTER_FUNCTION) (
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  );
+
+
+/**
+  Process a handle.
+
+  @param[in] Handle      The handle to process.
+  @param[in] ReportText  A caller-allocated string passed in for reporting
+                         purposes. It must never be NULL.
+**/
+typedef
+VOID
+(EFIAPI *CALLBACK_FUNCTION)  (
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  );
+
+/**
+  Locate all handles that carry the specified protocol, filter them with a
+  callback function, and pass each handle that passes the filter to another
+  callback.
+
+  @param[in] ProtocolGuid  The protocol to look for.
+
+  @param[in] Filter        The filter function to pass each handle to. If this
+                           parameter is NULL, then all handles are processed.
+
+  @param[in] Process       The callback function to pass each handle to that
+                           clears the filter.
+**/
+STATIC
+VOID
+FilterAndProcess (
+  IN EFI_GUID          *ProtocolGuid,
+  IN FILTER_FUNCTION   Filter         OPTIONAL,
+  IN CALLBACK_FUNCTION Process
+  )
+{
+  EFI_STATUS Status;
+  EFI_HANDLE *Handles;
+  UINTN      NoHandles;
+  UINTN      Idx;
+
+  Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid,
+                  NULL /* SearchKey */, &NoHandles, &Handles);
+  if (EFI_ERROR (Status)) {
+    //
+    // This is not an error, just an informative condition.
+    //
+    DEBUG ((DEBUG_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid,
+      Status));
+    return;
+  }
+
+  ASSERT (NoHandles > 0);
+  for (Idx = 0; Idx < NoHandles; ++Idx) {
+    CHAR16        *DevicePathText;
+    STATIC CHAR16 Fallback[] = L"<device path unavailable>";
+
+    //
+    // The ConvertDevicePathToText() function handles NULL input transparently.
+    //
+    DevicePathText = ConvertDevicePathToText (
+                       DevicePathFromHandle (Handles[Idx]),
+                       FALSE, // DisplayOnly
+                       FALSE  // AllowShortcuts
+                       );
+    if (DevicePathText == NULL) {
+      DevicePathText = Fallback;
+    }
+
+    if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) {
+      Process (Handles[Idx], DevicePathText);
+    }
+
+    if (DevicePathText != Fallback) {
+      FreePool (DevicePathText);
+    }
+  }
+  gBS->FreePool (Handles);
+}
+
+
+/**
+  This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the
+  handle, and adds it to ConOut and ErrOut.
+**/
+STATIC
+VOID
+EFIAPI
+AddOutput (
+  IN EFI_HANDLE   Handle,
+  IN CONST CHAR16 *ReportText
+  )
+{
+  EFI_STATUS               Status;
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+  DevicePath = DevicePathFromHandle (Handle);
+  if (DevicePath == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: %s: handle %p: device path not found\n",
+      __FUNCTION__, ReportText, Handle));
+    return;
+  }
+
+  Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__,
+      ReportText, Status));
+    return;
+  }
+
+  Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__,
+      ReportText, Status));
+    return;
+  }
+
+  DEBUG ((DEBUG_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__,
+    ReportText));
+}
+
+STATIC
+VOID
+PlatformRegisterFvBootOption (
+  EFI_GUID                         *FileGuid,
+  CHAR16                           *Description,
+  UINT32                           Attributes
+  )
+{
+  EFI_STATUS                        Status;
+  INTN                              OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
+  UINTN                             BootOptionCount;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+
+  Status = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **) &LoadedImage
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+  ASSERT (DevicePath != NULL);
+  DevicePath = AppendDevicePathNode (
+                 DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                 );
+  ASSERT (DevicePath != NULL);
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  ASSERT_EFI_ERROR (Status);
+  FreePool (DevicePath);
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount, LoadOptionTypeBoot
+                  );
+
+  OptionIndex = EfiBootManagerFindLoadOption (
+                  &NewOption, BootOptions, BootOptionCount
+                  );
+
+  if (OptionIndex == -1) {
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+    ASSERT_EFI_ERROR (Status);
+  }
+  EfiBootManagerFreeLoadOption (&NewOption);
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+
+STATIC
+VOID
+PlatformRegisterOptionsAndKeys (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_INPUT_KEY                Enter;
+  EFI_INPUT_KEY                F2;
+  EFI_INPUT_KEY                Esc;
+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+  //
+  // Register ENTER as CONTINUE key
+  //
+  Enter.ScanCode    = SCAN_NULL;
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+  Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Map F2 and ESC to Boot Manager Menu
+  //
+  F2.ScanCode     = SCAN_F2;
+  F2.UnicodeChar  = CHAR_NULL;
+  Esc.ScanCode    = SCAN_ESC;
+  Esc.UnicodeChar = CHAR_NULL;
+  Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+  ASSERT_EFI_ERROR (Status);
+  Status = EfiBootManagerAddKeyOptionVariable (
+             NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL
+             );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+  Status = EfiBootManagerAddKeyOptionVariable (
+             NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
+             );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+}
+
+
+//
+// BDS Platform Functions
+//
+/**
+  Do the platform init, can be customized by OEM/IBV
+  Possible things that can be done in PlatformBootManagerBeforeConsole:
+  > Update console variable: 1. include hot-plug devices;
+  >                          2. Clear ConIn and add SOL for AMT
+  > Register new Driver#### or Boot####
+  > Register new Key####: e.g.: F12
+  > Signal ReadyToLock event
+  > Authentication action: 1. connect Auth devices;
+  >                        2. Identify auto logon user.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  //
+  // Signal EndOfDxe PI Event
+  //
+  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+
+  //
+  // Now add the device path of all handles with GOP on them to ConOut and
+  // ErrOut.
+  //
+  FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
+
+  //
+  // Add the hardcoded short-form USB keyboard device path to ConIn.
+  //
+  EfiBootManagerUpdateConsoleVariable (ConIn,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL);
+
+  //
+  // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
+  //
+  ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4);
+  CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
+
+  EfiBootManagerUpdateConsoleVariable (ConIn,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
+  EfiBootManagerUpdateConsoleVariable (ConOut,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
+  EfiBootManagerUpdateConsoleVariable (ErrOut,
+    (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
+
+  //
+  // Register platform-specific boot options and keyboard shortcuts.
+  //
+  PlatformRegisterOptionsAndKeys ();
+}
+
+/**
+  Do the platform specific action after the console is ready
+  Possible things that can be done in PlatformBootManagerAfterConsole:
+  > Console post action:
+    > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
+    > Signal console ready platform customized event
+  > Run diagnostics like memory testing
+  > Connect certain devices
+  > Dispatch aditional option roms
+  > Special boot: e.g.: USB boot, enter UI
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  Print (L"Press ESCAPE for boot options ");
+
+  //
+  // Show the splash screen.
+  //
+  EnableQuietBoot (PcdGetPtr (PcdLogoFile));
+
+  //
+  // Connect the rest of the devices.
+  //
+  EfiBootManagerConnectAll ();
+
+  //
+  // Enumerate all possible boot options.
+  //
+  EfiBootManagerRefreshAllBootOption ();
+
+  //
+  // Register UEFI Shell
+  //
+  PlatformRegisterFvBootOption (
+    PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE
+    );
+
+  //
+  // Register Android Fastboot
+  //
+  PlatformRegisterFvBootOption (
+    PcdGetPtr (PcdAndroidFastbootFile), L"Android Fastboot", LOAD_OPTION_ACTIVE
+    );
+}
+
+/**
+  This function is called each second during the boot manager waits the
+  timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16          TimeoutRemain
+  )
+{
+  Print (L".");
+}
diff --git a/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.h b/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.h
new file mode 100644
index 0000000..0a3c626
--- /dev/null
+++ b/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBm.h
@@ -0,0 +1,59 @@ 
+/** @file
+  Head file for BDS Platform specific code
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution. The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PLATFORM_BM_H_
+#define _PLATFORM_BM_H_
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+/**
+  Use SystemTable Conout to stop video based Simple Text Out consoles from
+  going to the video device. Put up LogoFile on every video device that is a
+  console.
+
+  @param[in]  LogoFile   File name of logo to display on the center of the
+                         screen.
+
+  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and logo
+                          displayed.
+  @retval EFI_UNSUPPORTED Logo not found
+**/
+EFI_STATUS
+EnableQuietBoot (
+  IN  EFI_GUID  *LogoFile
+  );
+
+/**
+  Use SystemTable Conout to turn on video based Simple Text Out consoles. The
+  Simple Text Out screens will now be synced up with all non video output
+  devices
+
+  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
+**/
+EFI_STATUS
+DisableQuietBoot (
+  VOID
+  );
+
+#endif // _PLATFORM_BM_H_
diff --git a/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000..3256758
--- /dev/null
+++ b/Platforms/Hisilicon/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,88 @@ 
+## @file
+#  Implementation for PlatformBootManagerLib library class interfaces.
+#
+#  Copyright (C) 2015-2016, Red Hat, Inc.
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2016-2017, Linaro Ltd. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformBootManagerLib
+  FILE_GUID                      = a5a1ecfc-7c11-427a-8803-012869067095
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ARM AARCH64
+#
+
+[Sources]
+  PlatformBm.c
+  QuietBoot.c
+
+[Packages]
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OpenPlatformPkg/OpenPlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  DxeServicesLib
+  MemoryAllocationLib
+  PcdLib
+  PrintLib
+  UefiBootManagerLib
+  UefiBootServicesTableLib
+  UefiLib
+
+[FeaturePcd]
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootlogoOnlyEnable
+  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport
+
+[FixedPcd]
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gOpenPlatformTokenSpaceGuid.PcdAndroidFastbootFile
+
+[Guids]
+  gEfiFileInfoGuid
+  gEfiFileSystemInfoGuid
+  gEfiFileSystemVolumeLabelInfoIdGuid
+  gEfiEndOfDxeEventGroupGuid
+  gEfiTtyTermGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  gEfiLoadedImageProtocolGuid
+  gEfiOEMBadgingProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
diff --git a/Platforms/Hisilicon/Library/PlatformBootManagerLib/QuietBoot.c b/Platforms/Hisilicon/Library/PlatformBootManagerLib/QuietBoot.c
new file mode 100644
index 0000000..687bda0
--- /dev/null
+++ b/Platforms/Hisilicon/Library/PlatformBootManagerLib/QuietBoot.c
@@ -0,0 +1,680 @@ 
+/** @file
+  Platform BDS function for quiet boot support.
+
+Copyright (C) 2016, Red Hat, Inc.
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <IndustryStandard/Bmp.h>
+#include <Library/DxeServicesLib.h>
+#include <Protocol/BootLogo.h>
+#include <Protocol/OEMBadging.h>
+#include <Protocol/UgaDraw.h>
+
+#include "PlatformBm.h"
+
+/**
+  Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer
+  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
+  buffer is passed in it will be used if it is big enough.
+
+  @param  BmpImage      Pointer to BMP file
+  @param  BmpImageSize  Number of bytes in BmpImage
+  @param  GopBlt        Buffer containing GOP version of BmpImage.
+  @param  GopBltSize    Size of GopBlt in bytes.
+  @param  PixelHeight   Height of GopBlt/BmpImage in pixels
+  @param  PixelWidth    Width of GopBlt/BmpImage in pixels
+
+  @retval EFI_SUCCESS           GopBlt and GopBltSize are returned.
+  @retval EFI_UNSUPPORTED       BmpImage is not a valid *.BMP image
+  @retval EFI_BUFFER_TOO_SMALL  The passed in GopBlt buffer is not big enough.
+                                GopBltSize will contain the required size.
+  @retval EFI_OUT_OF_RESOURCES  No enough buffer to allocate.
+
+**/
+STATIC
+EFI_STATUS
+ConvertBmpToGopBlt (
+  IN     VOID      *BmpImage,
+  IN     UINTN     BmpImageSize,
+  IN OUT VOID      **GopBlt,
+  IN OUT UINTN     *GopBltSize,
+     OUT UINTN     *PixelHeight,
+     OUT UINTN     *PixelWidth
+  )
+{
+  UINT8                         *Image;
+  UINT8                         *ImageHeader;
+  BMP_IMAGE_HEADER              *BmpHeader;
+  BMP_COLOR_MAP                 *BmpColorMap;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+  UINT64                        BltBufferSize;
+  UINTN                         Index;
+  UINTN                         Height;
+  UINTN                         Width;
+  UINTN                         ImageIndex;
+  UINT32                        DataSizePerLine;
+  BOOLEAN                       IsAllocated;
+  UINT32                        ColorMapNum;
+
+  if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
+
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Doesn't support compress.
+  //
+  if (BmpHeader->CompressionType != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Only support BITMAPINFOHEADER format.
+  // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER
+  //
+  if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // The data size in each line must be 4 byte alignment.
+  //
+  DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3);
+  BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight);
+  if (BltBufferSize > (UINT32) ~0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((BmpHeader->Size != BmpImageSize) ||
+      (BmpHeader->Size < BmpHeader->ImageOffset) ||
+      (BmpHeader->Size - BmpHeader->ImageOffset !=  BmpHeader->PixelHeight * DataSizePerLine)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Calculate Color Map offset in the image.
+  //
+  Image       = BmpImage;
+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));
+  if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) {
+    switch (BmpHeader->BitPerPixel) {
+      case 1:
+        ColorMapNum = 2;
+        break;
+      case 4:
+        ColorMapNum = 16;
+        break;
+      case 8:
+        ColorMapNum = 256;
+        break;
+      default:
+        ColorMapNum = 0;
+        break;
+      }
+    //
+    // BMP file may has padding data between the bmp header section and the bmp data section.
+    //
+    if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Calculate graphics image data address in the image
+  //
+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
+  ImageHeader   = Image;
+
+  //
+  // Calculate the BltBuffer needed size.
+  //
+  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
+  //
+  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+  //
+  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    return EFI_UNSUPPORTED;
+  }
+  BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+  IsAllocated   = FALSE;
+  if (*GopBlt == NULL) {
+    //
+    // GopBlt is not allocated by caller.
+    //
+    *GopBltSize = (UINTN) BltBufferSize;
+    *GopBlt     = AllocatePool (*GopBltSize);
+    IsAllocated = TRUE;
+    if (*GopBlt == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  } else {
+    //
+    // GopBlt has been allocated by caller.
+    //
+    if (*GopBltSize < (UINTN) BltBufferSize) {
+      *GopBltSize = (UINTN) BltBufferSize;
+      return EFI_BUFFER_TOO_SMALL;
+    }
+  }
+
+  *PixelWidth   = BmpHeader->PixelWidth;
+  *PixelHeight  = BmpHeader->PixelHeight;
+
+  //
+  // Convert image from BMP to Blt buffer format
+  //
+  BltBuffer = *GopBlt;
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
+      switch (BmpHeader->BitPerPixel) {
+      case 1:
+        //
+        // Convert 1-bit (2 colors) BMP to 24-bit color
+        //
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
+          Blt++;
+          Width++;
+        }
+
+        Blt--;
+        Width--;
+        break;
+
+      case 4:
+        //
+        // Convert 4-bit (16 colors) BMP Palette to 24-bit color
+        //
+        Index       = (*Image) >> 4;
+        Blt->Red    = BmpColorMap[Index].Red;
+        Blt->Green  = BmpColorMap[Index].Green;
+        Blt->Blue   = BmpColorMap[Index].Blue;
+        if (Width < (BmpHeader->PixelWidth - 1)) {
+          Blt++;
+          Width++;
+          Index       = (*Image) & 0x0f;
+          Blt->Red    = BmpColorMap[Index].Red;
+          Blt->Green  = BmpColorMap[Index].Green;
+          Blt->Blue   = BmpColorMap[Index].Blue;
+        }
+        break;
+
+      case 8:
+        //
+        // Convert 8-bit (256 colors) BMP Palette to 24-bit color
+        //
+        Blt->Red    = BmpColorMap[*Image].Red;
+        Blt->Green  = BmpColorMap[*Image].Green;
+        Blt->Blue   = BmpColorMap[*Image].Blue;
+        break;
+
+      case 24:
+        //
+        // It is 24-bit BMP.
+        //
+        Blt->Blue   = *Image++;
+        Blt->Green  = *Image++;
+        Blt->Red    = *Image;
+        break;
+
+      default:
+        //
+        // Other bit format BMP is not supported.
+        //
+        if (IsAllocated) {
+          FreePool (*GopBlt);
+          *GopBlt = NULL;
+        }
+        return EFI_UNSUPPORTED;
+      };
+
+    }
+
+    ImageIndex = (UINTN) (Image - ImageHeader);
+    if ((ImageIndex % 4) != 0) {
+      //
+      // Bmp Image starts each row on a 32-bit boundary!
+      //
+      Image = Image + (4 - (ImageIndex % 4));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Use SystemTable Conout to stop video based Simple Text Out consoles from going
+  to the video device. Put up LogoFile on every video device that is a console.
+
+  @param[in]  LogoFile   File name of logo to display on the center of the screen.
+
+  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and logo displayed.
+  @retval EFI_UNSUPPORTED Logo not found
+
+**/
+EFI_STATUS
+EnableQuietBoot (
+  IN  EFI_GUID  *LogoFile
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_OEM_BADGING_PROTOCOL      *Badging;
+  UINT32                        SizeOfX;
+  UINT32                        SizeOfY;
+  INTN                          DestX;
+  INTN                          DestY;
+  UINT8                         *ImageData;
+  UINTN                         ImageSize;
+  UINTN                         BltSize;
+  UINT32                        Instance;
+  EFI_BADGING_FORMAT            Format;
+  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+  UINTN                         CoordinateX;
+  UINTN                         CoordinateY;
+  UINTN                         Height;
+  UINTN                         Width;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;
+  UINT32                        ColorDepth;
+  UINT32                        RefreshRate;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
+  EFI_BOOT_LOGO_PROTOCOL        *BootLogo;
+  UINTN                         NumberOfLogos;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
+  UINTN                         LogoDestX;
+  UINTN                         LogoDestY;
+  UINTN                         LogoHeight;
+  UINTN                         LogoWidth;
+  UINTN                         NewDestX;
+  UINTN                         NewDestY;
+  UINTN                         NewHeight;
+  UINTN                         NewWidth;
+  UINT64                        BufferSize;
+
+  UgaDraw = NULL;
+  //
+  // Try to open GOP first
+  //
+  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
+    GraphicsOutput = NULL;
+    //
+    // Open GOP failed, try to open UGA
+    //
+    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
+  }
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Try to open Boot Logo Protocol.
+  //
+  BootLogo = NULL;
+  gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
+
+  //
+  // Erase Cursor from screen
+  //
+  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+
+  Badging = NULL;
+  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);
+
+  if (GraphicsOutput != NULL) {
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+
+  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  Blt = NULL;
+  NumberOfLogos = 0;
+  LogoDestX = 0;
+  LogoDestY = 0;
+  LogoHeight = 0;
+  LogoWidth = 0;
+  NewDestX = 0;
+  NewDestY = 0;
+  NewHeight = 0;
+  NewWidth = 0;
+  Instance = 0;
+  Height = 0;
+  Width = 0;
+  while (1) {
+    ImageData = NULL;
+    ImageSize = 0;
+
+    if (Badging != NULL) {
+      //
+      // Get image from OEMBadging protocol.
+      //
+      Status = Badging->GetImage (
+                          Badging,
+                          &Instance,
+                          &Format,
+                          &ImageData,
+                          &ImageSize,
+                          &Attribute,
+                          &CoordinateX,
+                          &CoordinateY
+                          );
+      if (EFI_ERROR (Status)) {
+        goto Done;
+      }
+
+      //
+      // Currently only support BMP format.
+      //
+      if (Format != EfiBadgingFormatBMP) {
+        if (ImageData != NULL) {
+          FreePool (ImageData);
+        }
+        continue;
+      }
+    } else {
+      //
+      // Get the specified image from FV.
+      //
+      Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
+      if (EFI_ERROR (Status)) {
+        return EFI_UNSUPPORTED;
+      }
+
+      CoordinateX = 0;
+      CoordinateY = 0;
+      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
+        Attribute   = EfiBadgingDisplayAttributeCenter;
+      } else {
+        Attribute   = EfiBadgingDisplayAttributeCustomized;
+      }
+    }
+
+    if (Blt != NULL) {
+      FreePool (Blt);
+    }
+    Blt = NULL;
+    Status = ConvertBmpToGopBlt (
+              ImageData,
+              ImageSize,
+              (VOID **) &Blt,
+              &BltSize,
+              &Height,
+              &Width
+              );
+    if (EFI_ERROR (Status)) {
+      FreePool (ImageData);
+
+      if (Badging == NULL) {
+        return Status;
+      } else {
+        continue;
+      }
+    }
+
+    //
+    // Calculate the display position according to Attribute.
+    //
+    switch (Attribute) {
+    case EfiBadgingDisplayAttributeLeftTop:
+      DestX = CoordinateX;
+      DestY = CoordinateY;
+      break;
+
+    case EfiBadgingDisplayAttributeCenterTop:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = CoordinateY;
+      break;
+
+    case EfiBadgingDisplayAttributeRightTop:
+      DestX = (SizeOfX - Width - CoordinateX);
+      DestY = CoordinateY;;
+      break;
+
+    case EfiBadgingDisplayAttributeCenterRight:
+      DestX = (SizeOfX - Width - CoordinateX);
+      DestY = (SizeOfY - Height) / 2;
+      break;
+
+    case EfiBadgingDisplayAttributeRightBottom:
+      DestX = (SizeOfX - Width - CoordinateX);
+      DestY = (SizeOfY - Height - CoordinateY);
+      break;
+
+    case EfiBadgingDisplayAttributeCenterBottom:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = (SizeOfY - Height - CoordinateY);
+      break;
+
+    case EfiBadgingDisplayAttributeLeftBottom:
+      DestX = CoordinateX;
+      DestY = (SizeOfY - Height - CoordinateY);
+      break;
+
+    case EfiBadgingDisplayAttributeCenterLeft:
+      DestX = CoordinateX;
+      DestY = (SizeOfY - Height) / 2;
+      break;
+
+    case EfiBadgingDisplayAttributeCenter:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = (SizeOfY - Height) / 2;
+      break;
+
+    case EfiBadgingDisplayAttributeCustomized:
+      DestX = (SizeOfX - Width) / 2;
+      DestY = ((SizeOfY * 382) / 1000) - Height / 2;
+      break;
+
+    default:
+      DestX = CoordinateX;
+      DestY = CoordinateY;
+      break;
+    }
+
+    if ((DestX >= 0) && (DestY >= 0)) {
+      if (GraphicsOutput != NULL) {
+        Status = GraphicsOutput->Blt (
+                            GraphicsOutput,
+                            Blt,
+                            EfiBltBufferToVideo,
+                            0,
+                            0,
+                            (UINTN) DestX,
+                            (UINTN) DestY,
+                            Width,
+                            Height,
+                            Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                            );
+      } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+        Status = UgaDraw->Blt (
+                            UgaDraw,
+                            (EFI_UGA_PIXEL *) Blt,
+                            EfiUgaBltBufferToVideo,
+                            0,
+                            0,
+                            (UINTN) DestX,
+                            (UINTN) DestY,
+                            Width,
+                            Height,
+                            Width * sizeof (EFI_UGA_PIXEL)
+                            );
+      } else {
+        Status = EFI_UNSUPPORTED;
+      }
+
+      //
+      // Report displayed Logo information.
+      //
+      if (!EFI_ERROR (Status)) {
+        NumberOfLogos++;
+
+        if (LogoWidth == 0) {
+          //
+          // The first Logo.
+          //
+          LogoDestX = (UINTN) DestX;
+          LogoDestY = (UINTN) DestY;
+          LogoWidth = Width;
+          LogoHeight = Height;
+        } else {
+          //
+          // Merge new logo with old one.
+          //
+          NewDestX = MIN ((UINTN) DestX, LogoDestX);
+          NewDestY = MIN ((UINTN) DestY, LogoDestY);
+          NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;
+          NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;
+
+          LogoDestX = NewDestX;
+          LogoDestY = NewDestY;
+          LogoWidth = NewWidth;
+          LogoHeight = NewHeight;
+        }
+      }
+    }
+
+    FreePool (ImageData);
+
+    if (Badging == NULL) {
+      break;
+    }
+  }
+
+Done:
+  if (BootLogo == NULL || NumberOfLogos == 0) {
+    //
+    // No logo displayed.
+    //
+    if (Blt != NULL) {
+      FreePool (Blt);
+    }
+
+    return Status;
+  }
+
+  //
+  // Advertise displayed Logo information.
+  //
+  if (NumberOfLogos == 1) {
+    //
+    // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
+    //
+    LogoBlt = Blt;
+    Status = EFI_SUCCESS;
+  } else {
+    //
+    // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation.
+    //
+    if (Blt != NULL) {
+      FreePool (Blt);
+    }
+
+    //
+    // Ensure the LogoHeight * LogoWidth doesn't overflow
+    //
+    if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) {
+      return EFI_UNSUPPORTED;
+    }
+    BufferSize = MultU64x64 (LogoWidth, LogoHeight);
+
+    //
+    // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
+    //
+    if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+      return EFI_UNSUPPORTED;
+    }
+
+    LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+    if (LogoBlt == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          LogoBlt,
+                          EfiBltVideoToBltBuffer,
+                          LogoDestX,
+                          LogoDestY,
+                          0,
+                          0,
+                          LogoWidth,
+                          LogoHeight,
+                          LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
+      Status = UgaDraw->Blt (
+                          UgaDraw,
+                          (EFI_UGA_PIXEL *) LogoBlt,
+                          EfiUgaVideoToBltBuffer,
+                          LogoDestX,
+                          LogoDestY,
+                          0,
+                          0,
+                          LogoWidth,
+                          LogoHeight,
+                          LogoWidth * sizeof (EFI_UGA_PIXEL)
+                          );
+    } else {
+      Status = EFI_UNSUPPORTED;
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
+  }
+  FreePool (LogoBlt);
+
+  return Status;
+}
+
+/**
+  Use SystemTable Conout to turn on video based Simple Text Out consoles. The
+  Simple Text Out screens will now be synced up with all non video output devices
+
+  @retval EFI_SUCCESS     UGA devices are back in text mode and synced up.
+
+**/
+EFI_STATUS
+DisableQuietBoot (
+  VOID
+  )
+{
+
+  //
+  // Enable Cursor on Screen
+  //
+  gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+  return EFI_SUCCESS;
+}
+