[edk2] [Patch][edk2-platforms/devel-MinnowBoard3-UDK2017] Platform Boot Manager Library.

zwei4 posted 1 patch 6 years, 1 month ago
Failed in applying to current master (apply log)
.../PlatformBootManagerLib/PlatformBootManager.c   | 1052 ++++++++++++++++++++
.../PlatformBootManagerLib/PlatformBootManager.h   |  226 +++++
.../PlatformBootManagerLib.inf                     |  109 ++
.../PlatformBootManagerLib/PlatformBootOption.c    |  738 ++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c  |  179 ++++
5 files changed, 2304 insertions(+)
create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.h
create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootOption.c
create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformData.c
[edk2] [Patch][edk2-platforms/devel-MinnowBoard3-UDK2017] Platform Boot Manager Library.
Posted by zwei4 6 years, 1 month ago
Add library instance of PlatformBootManagerLib.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: zwei4 <david.wei@intel.com>
---
 .../PlatformBootManagerLib/PlatformBootManager.c   | 1052 ++++++++++++++++++++
 .../PlatformBootManagerLib/PlatformBootManager.h   |  226 +++++
 .../PlatformBootManagerLib.inf                     |  109 ++
 .../PlatformBootManagerLib/PlatformBootOption.c    |  738 ++++++++++++++
 .../Library/PlatformBootManagerLib/PlatformData.c  |  179 ++++
 5 files changed, 2304 insertions(+)
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootOption.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformData.c

diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.c
new file mode 100644
index 000000000..3dffe7263
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.c
@@ -0,0 +1,1052 @@
+/** @file
+  This file include all platform action at BDS stage which can be customized by IBV/OEM.
+
+  Copyright (c) 2006 - 2018, 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 "PlatformBootManager.h"
+#include <Guid/EventGroup.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/ExitPmAuth.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/VariableLock.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/TcgPhysicalPresenceLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Library/HobLib.h>
+#include <Guid/EventGroup.h>
+#include <Guid/ImageAuthentication.h>
+#include <Guid/Tcg2PhysicalPresenceData.h>
+#include <Guid/PhysicalPresenceData.h>
+#include <Guid/TpmInstance.h>
+#include <Guid/PttPTPInstanceGuid.h>
+
+#pragma optimize("g", off)
+
+#define TIMEOUT_COMMAND 100000
+#define BIOS_COLOR_CODING_BAR_HEIGHT  40
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HII_HANDLE                gPlatformBdsLibStringPackHandle;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE                 mBootMode;
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID  *mLibTerminalType[] = {
+  &gEfiPcAnsiGuid,
+  &gEfiVT100Guid,
+  &gEfiVT100PlusGuid,
+  &gEfiVTUTF8Guid
+};
+
+//
+// Internal shell mode
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32         mShellModeColumn;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32         mShellModeRow;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32         mShellHorizontalResolution;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32         mShellVerticalResolution;
+
+CHAR16  *mConsoleVar[] = {L"ConIn", L"ConOut"};
+
+extern USB_CLASS_FORMAT_DEVICE_PATH mUsbClassKeyboardDevicePath;
+extern BOOLEAN                      mAnyKeypressed;
+
+/**
+  The handle on the path we get might be not the display device.
+  We must check it.
+
+  @todo fix the parameters
+
+  @retval  TRUE         PCI class type is VGA.
+  @retval  FALSE        PCI class type isn't VGA.
+**/
+BOOLEAN
+IsVgaHandle (
+  IN EFI_HANDLE Handle
+)
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  PCI_TYPE00 Pci;
+  EFI_STATUS Status;
+
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **)&PciIo);
+
+  if (!EFI_ERROR (Status)) {
+    Status = PciIo->Pci.Read (
+                          PciIo,
+                          EfiPciIoWidthUint32,
+                          0,
+                          sizeof (Pci) / sizeof (UINT32),
+                          &Pci);
+
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "  PCI CLASS CODE    = 0x%x\n", Pci.Hdr.ClassCode [2]));
+      DEBUG ((DEBUG_ERROR, "  PCI SUBCLASS CODE = 0x%x\n", Pci.Hdr.ClassCode [1]));
+
+      if (IS_PCI_VGA (&Pci) || IS_PCI_OLD_VGA (&Pci)) {
+        DEBUG ((DEBUG_ERROR, "  \nPCI VGA Device Found\n"));
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+/**
+  This function converts an input device structure to a Unicode string.
+
+  @param DevPath                  A pointer to the device path structure.
+
+  @return A new allocated Unicode string that represents the device path.
+**/
+CHAR16 *
+DevicePathToStr (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
+  )
+{
+  EFI_STATUS                       Status;
+  CHAR16                           *ToText;
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
+
+  if (DevPath == NULL) {
+    return NULL;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiDevicePathToTextProtocolGuid,
+                  NULL,
+                  (VOID **) &DevPathToText
+                  );
+  ASSERT_EFI_ERROR (Status);
+  ToText = DevPathToText->ConvertDevicePathToText (
+                            DevPath,
+                            FALSE,
+                            TRUE
+                            );
+  ASSERT (ToText != NULL);
+  return ToText;
+}
+
+/**
+  An empty function to pass error checking of CreateEventEx ().
+
+  This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
+  checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
+
+  @param  Event                 Event whose notification function is being invoked.
+  @param  Context               The pointer to the notification function's context,
+                                which is implementation-dependent.
+**/
+VOID
+EFIAPI
+InternalBdsEmptyCallbackFuntion (
+  IN EFI_EVENT                Event,
+  IN VOID                     *Context
+  )
+{
+  return;
+}
+
+VOID
+ExitPmAuth (
+  VOID
+  )
+{
+  EFI_HANDLE                 Handle;
+  EFI_STATUS                 Status;
+  EFI_ACPI_S3_SAVE_PROTOCOL  *AcpiS3Save;
+  EFI_EVENT                  EndOfDxeEvent;
+
+  DEBUG((DEBUG_INFO,"ExitPmAuth ()- Start\n"));
+
+  //
+  // Inform the SMM infrastructure that we're entering BDS and may run 3rd party code hereafter
+  // We can NOT put it to PlatformBdsInit, because many boot script touch PCI BAR.
+  // We have to connect PCI root bridge, allocate resource, then ExitPmAuth().
+  //
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gExitPmAuthProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth.
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  InternalBdsEmptyCallbackFuntion,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  gBS->SignalEvent (EndOfDxeEvent);
+  gBS->CloseEvent (EndOfDxeEvent);
+  DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+  //
+  // Prepare S3 information, this MUST be done before ExitPmAuth/EndOfDxe.
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **)&AcpiS3Save);
+  if (!EFI_ERROR (Status)) {
+    AcpiS3Save->S3Save (AcpiS3Save, NULL);
+  }
+
+  //
+  // NOTE: We need install DxeSmmReadyToLock directly here because many boot script is added via ExitPmAuth/EndOfDxe callback.
+  // If we install them at same callback, these boot script will be rejected because BootScript Driver runs first to lock them done.
+  // So we seperate them to be 2 different events, ExitPmAuth is last chance to let platform add boot script. DxeSmmReadyToLock will
+  // make boot script save driver lock down the interface.
+  //
+  Handle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &Handle,
+                  &gEfiDxeSmmReadyToLockProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+  DEBUG((DEBUG_INFO,"ExitPmAuth ()- End\n"));
+}
+
+VOID
+ConnectRootBridge (
+  BOOLEAN Recursive
+  )
+{
+  UINTN        RootBridgeHandleCount;
+  EFI_HANDLE   *RootBridgeHandleBuffer;
+  UINTN        RootBridgeIndex;
+
+  RootBridgeHandleCount = 0;
+  gBS->LocateHandleBuffer (
+         ByProtocol,
+         &gEfiPciRootBridgeIoProtocolGuid,
+         NULL,
+         &RootBridgeHandleCount,
+         &RootBridgeHandleBuffer
+         );
+  for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
+    gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, Recursive);
+  }
+}
+
+
+BOOLEAN
+IsGopDevicePath (
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  while (!IsDevicePathEndType (DevicePath)) {
+    if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH &&
+        DevicePathSubType (DevicePath) == ACPI_ADR_DP) {
+      return TRUE;
+    }
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+  return FALSE;
+}
+
+/**
+  Connect the USB short form device path.
+
+  @param DevicePath   USB short form device path.
+
+  @retval EFI_SUCCESS           Successfully connected the USB device.
+  @retval EFI_NOT_FOUND         Cannot connect the USB device.
+  @retval EFI_INVALID_PARAMETER The device path is invalid.
+**/
+EFI_STATUS
+ConnectUsbShortFormDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              *Handles;
+  UINTN                   HandleCount;
+  UINTN                   Index;
+  EFI_PCI_IO_PROTOCOL     *PciIo;
+  UINT8                   Class[3];
+  BOOLEAN                 AtLeastOneConnected;
+
+  //
+  // Check the passed in parameters.
+  //
+  if (DevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) ||
+      ((DevicePathSubType (DevicePath) != MSG_USB_CLASS_DP) && (DevicePathSubType (DevicePath) != MSG_USB_WWID_DP))
+     ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Find the usb host controller firstly, then connect with the remaining device path.
+  //
+  
+  AtLeastOneConnected = FALSE;
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &Handles
+                  );
+                  
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    Handles[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **) &PciIo
+                    );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Check whether the Pci device is the wanted usb host controller.
+      //
+      Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
+      if (!EFI_ERROR (Status) &&
+          ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1]))
+         ) {
+        Status = gBS->ConnectController (
+                        Handles[Index],
+                        NULL,
+                        DevicePath,
+                        FALSE
+                        );
+        if (!EFI_ERROR(Status)) {
+          AtLeastOneConnected = TRUE;
+        }
+      }
+    }
+  }
+
+  return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND;
+}
+
+/**
+  Update the ConIn variable if Ps2 keyboard is connected.
+**/
+VOID
+EnumPs2Keyboard (
+  VOID
+  )
+{
+  UINTN                     DevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *VarConIn;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  BOOLEAN                   Ps2Keyboard;
+
+  Ps2Keyboard = FALSE;
+  GetEfiGlobalVariable2 (L"ConIn",    (VOID **) &VarConIn,    NULL);
+
+  //
+  // If ConIn variable is empty, need to enumerate PS/2 keyboard device path.
+  //
+  do {
+    DevicePathInstance = GetNextDevicePathInstance (
+                           &VarConIn,
+                           &DevicePathSize
+                           );
+
+    if (DevicePathInstance == NULL) {
+      //
+      // The instance is NULL, it means the VarConIn is null, escape the DO loop,
+      // and need to add PS/2 keyboard dev path.
+      //
+      break;
+    }
+
+    Next = DevicePathInstance;
+    while (!IsDevicePathEndType(Next)) {
+      //
+      // Checking the device path to see the PS/2 keyboard existance.
+      //
+      if ((Next->Type    == ACPI_DEVICE_PATH) &&
+          (Next->SubType == ACPI_DP         ) &&
+          (((ACPI_HID_DEVICE_PATH *) Next)->HID == EISA_PNP_ID (0x0303))) {
+        //
+        // PS/2 keyboard already exists.
+        //
+        DEBUG ((DEBUG_INFO, "[EnumPs2Keyboard] PS2 keyboard path exists\n"));
+        Ps2Keyboard = TRUE;
+        break;
+      }
+      Next = NextDevicePathNode (Next);
+    }
+
+    if (DevicePathInstance != NULL) {
+      FreePool (DevicePathInstance);
+    }
+  } while (VarConIn != NULL);
+
+  //
+  // PS/2 keyboard device path does not exist, so try detecting ps2 keyboard
+  // and add-in its device path.
+  //
+  if (!Ps2Keyboard) {
+    DEBUG ((DEBUG_INFO, "[EnumPs2Keyboard] Adding detected PS2 keyboard to ConIn.\n"));
+  }
+
+  if (VarConIn != NULL) {
+    FreePool (VarConIn);
+  }
+}
+
+/**
+  Update the ConIn variable with USB Keyboard device path,if its not already exists in ConIn.
+**/
+VOID
+EnumUsbKeyboard (
+  VOID
+  )
+{
+  UINTN                     DevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *VarConIn;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  BOOLEAN                   UsbKeyboard;
+
+  UsbKeyboard = FALSE;
+  GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL);
+
+  //
+  // If ConIn variable is empty, need to enumerate USB keyboard device path.
+  //
+  do {
+    DevicePathInstance = GetNextDevicePathInstance (
+                           &VarConIn,
+                           &DevicePathSize
+                           );
+
+    if (DevicePathInstance == NULL) {
+      //
+      // The instance is NULL, it means the VarConIn is null, escape the DO loop,
+      // and need to add USB keyboard dev path.
+      //
+      break;
+    }
+
+    Next = DevicePathInstance;
+    while (!IsDevicePathEndType(Next)) {
+      //
+      // Checking the device path to see the USB keyboard existance.
+      //
+      if ((Next->Type    == MESSAGING_DEVICE_PATH) &&
+          (Next->SubType == MSG_USB_CLASS_DP) &&
+          (((USB_CLASS_DEVICE_PATH *) Next)->DeviceClass == CLASS_HID) &&
+          (((USB_CLASS_DEVICE_PATH *) Next)->DeviceSubClass == SUBCLASS_BOOT) &&
+          (((USB_CLASS_DEVICE_PATH *) Next)->DeviceProtocol == PROTOCOL_KEYBOARD)) {
+          	
+        DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard] USB keyboard path exists\n"));
+        UsbKeyboard = TRUE;
+
+        break;
+      }
+      Next = NextDevicePathNode (Next);
+    }
+
+    if (DevicePathInstance != NULL) {
+      FreePool (DevicePathInstance);
+    }
+  } while (VarConIn != NULL);
+
+  //
+  //  USB keyboard device path does not exist, So add it to the ConIn.
+  //
+  if (!UsbKeyboard) {
+    DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard] Adding USB keyboard device path to ConIn.\n"));
+      EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *) &mUsbClassKeyboardDevicePath, NULL);
+   }
+
+  if (VarConIn != NULL) {
+    FreePool (VarConIn);
+  }
+}
+
+/**
+  Return whether the device is trusted console.
+
+  @param Device  The device to be tested.
+
+  @retval TRUE   The device can be trusted.
+  @retval FALSE  The device cannot be trusted.
+**/
+BOOLEAN
+IsTrustedConsole (
+  EFI_DEVICE_PATH_PROTOCOL  *Device
+  )
+{
+  if (IsGopDevicePath (Device)) {
+    return TRUE;
+  }
+
+  if (CompareMem (Device, &mKeyboardDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mKeyboardDevicePath) - END_DEVICE_PATH_LENGTH) == 0) {
+    return TRUE;
+  }
+
+  if (CompareMem (Device, &mUsbClassKeyboardDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) &mUsbClassKeyboardDevicePath) - END_DEVICE_PATH_LENGTH) == 0) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+VOID
+ProcessTcgPp (
+  VOID
+  )
+{
+  EFI_STATUS                         Status;
+  UINTN                              Tcg2PpDataSize;
+  EFI_TCG2_PHYSICAL_PRESENCE         Tcg2PpData;
+  EFI_PHYSICAL_PRESENCE              TcgPpData;
+  UINTN                              TcgPpDataSize;
+    
+  //
+  // Initialize physical presence variable.
+  //
+  if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid) ||
+    CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gTpmDeviceInstanceTpm20PttPtpGuid)) {
+    Tcg2PpDataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+    Status = gRT->GetVariable (
+                    TCG2_PHYSICAL_PRESENCE_VARIABLE,
+                    &gEfiTcg2PhysicalPresenceGuid,
+                    NULL,
+                    &Tcg2PpDataSize,
+                    &Tcg2PpData
+                    );
+
+    if (EFI_ERROR (Status)) {
+      ZeroMem ((VOID *) &Tcg2PpData, sizeof (Tcg2PpData));
+      Tcg2PpDataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+      Status = gRT->SetVariable (
+                      TCG2_PHYSICAL_PRESENCE_VARIABLE,
+                      &gEfiTcg2PhysicalPresenceGuid,
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                      Tcg2PpDataSize,
+                      &Tcg2PpData
+                      );
+    }
+  } else if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
+    TcgPpDataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+    Status = gRT->GetVariable (
+                    PHYSICAL_PRESENCE_VARIABLE,
+                    &gEfiPhysicalPresenceGuid,
+                    NULL,
+                    &TcgPpDataSize,
+                    &TcgPpData
+                    );
+
+    if (EFI_ERROR (Status)) {
+      ZeroMem ((VOID *) &TcgPpData, sizeof (TcgPpData));
+      TcgPpDataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+      Status = gRT->SetVariable (
+                      PHYSICAL_PRESENCE_VARIABLE,
+                      &gEfiPhysicalPresenceGuid,
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+                      TcgPpDataSize,
+                      &TcgPpData
+                      );
+    }
+  }
+
+  if (!EFI_ERROR (Status) && ((Tcg2PpData.PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) || (TcgPpData.PPRequest != TCG_PHYSICAL_PRESENCE_NO_ACTION))) {
+  //
+  // If it requests any action on TCG, need to connect console to display information.
+  //
+    EfiBootManagerConnectAllDefaultConsoles();
+  }
+
+  if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid) ||
+    CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gTpmDeviceInstanceTpm20PttPtpGuid)) {
+    Tcg2PhysicalPresenceLibProcessRequest (NULL);
+  } else if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
+    TcgPhysicalPresenceLibProcessRequest ();
+  }
+}
+
+/**
+  Remove all GOP device path instance from DevicePath and add the Gop to the DevicePath.
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+UpdateDevicePath (
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  EFI_DEVICE_PATH_PROTOCOL *Gop
+  )
+{
+  UINTN                    Size;
+  UINTN                    GopSize;
+  EFI_DEVICE_PATH_PROTOCOL *Temp;
+  EFI_DEVICE_PATH_PROTOCOL *Return;
+  EFI_DEVICE_PATH_PROTOCOL *Instance;
+  BOOLEAN                  Exist;
+
+  Exist = FALSE;
+  Return = NULL;
+  GopSize = GetDevicePathSize (Gop);
+  do {
+    Instance = GetNextDevicePathInstance (&DevicePath, &Size);
+    if (Instance == NULL) {
+      break;
+    }
+    if (!IsGopDevicePath (Instance) ||
+        (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0)
+       ) {
+      if (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0) {
+        Exist = TRUE;
+      }
+      Temp = Return;
+      Return = AppendDevicePathInstance (Return, Instance);
+      if (Temp != NULL) {
+        FreePool (Temp);
+      }
+    }
+    FreePool (Instance);
+  } while (DevicePath != NULL);
+
+  if (!Exist) {
+    Temp = Return;
+    Return = AppendDevicePathInstance (Return, Gop);
+    gBS->FreePool (Temp);
+  }
+  return Return;
+}
+
+#pragma optimize("g", off)
+
+/**
+  Check if current BootCurrent variable is internal shell boot option.
+
+  @retval  TRUE         BootCurrent is internal shell.
+  @retval  FALSE        BootCurrent is not internal shell.
+**/
+BOOLEAN
+BootCurrentIsInternalShell (
+  VOID
+)
+{
+  UINTN                         VarSize;
+  UINT16                        BootCurrent;
+  CHAR16                        BootOptionName[16];
+  UINT8                         *BootOption;
+  UINT8                         *Ptr;
+  EFI_DEVICE_PATH_PROTOCOL      *BootDevicePath;
+  BOOLEAN                       Result;
+  EFI_STATUS                    Status;
+  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
+  EFI_GUID                      *GuidPoint;
+
+  BootOption     = NULL;
+  BootDevicePath = NULL;
+  Result         = FALSE;
+
+  //
+  // Get BootCurrent variable
+  //
+  VarSize = sizeof (UINT16);
+  Status = gRT->GetVariable (
+              L"BootCurrent",
+              &gEfiGlobalVariableGuid,
+              NULL,
+              &VarSize,
+              &BootCurrent
+              );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  //
+  // Create boot option Bootxxxx from BootCurrent.
+  //
+  UnicodeSPrint (BootOptionName, sizeof(BootOptionName), L"Boot%04x", BootCurrent);
+
+  GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize);
+  if (BootOption == NULL || VarSize == 0) {
+    return FALSE;
+  }
+
+  Ptr = BootOption;
+  Ptr += sizeof (UINT32);
+  Ptr += sizeof (UINT16);
+  Ptr += StrSize ((CHAR16 *) Ptr);
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+  LastDeviceNode = TempDevicePath;
+  while (!IsDevicePathEnd (TempDevicePath)) {
+     LastDeviceNode = TempDevicePath;
+     TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+  GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+                (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+                );
+  if ((GuidPoint != NULL) &&
+      (CompareGuid (GuidPoint, &gUefiShellFileGuid))
+    ) {
+    //
+    // If this option is internal shell, return TRUE.
+    //
+    Result = TRUE;
+  }
+
+  if (BootOption != NULL) {
+    FreePool (BootOption);
+    BootOption = NULL;
+  }
+
+  return Result;
+}
+
+/**
+  ReadyToBoot callback to set video and text mode for internal shell boot.
+  That will not connect USB controller while CSM and FastBoot are disabled, we need to connect them
+  before booting to Shell for showing USB devices in Shell.
+
+  When FastBoot is enabled and Windows Console is the chosen Console behavior, input devices will not be connected
+  by default. Hence, when booting to EFI shell, connecting input consoles are required.
+
+  @param  Event   Pointer to this event
+  @param  Context Event hanlder private data
+
+  @retval None.
+**/
+VOID
+EFIAPI
+OnReadyToBootCallBack (
+  IN      EFI_EVENT                 Event,
+  IN      VOID                      *Context
+  )
+{
+  DEBUG ((EFI_D_INFO, "OnReadyToBootCallBack\n"));
+
+  if (BootCurrentIsInternalShell ()) {
+
+  }
+}
+
+/**
+  Platform Bds init. Incude the platform firmware vendor, revision
+  and so crc check.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  UINTN                               Index;
+  EFI_DEVICE_PATH_PROTOCOL            *VarConOut;
+  EFI_DEVICE_PATH_PROTOCOL            *VarConIn;
+  EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL            *ConsoleOut;
+  EFI_DEVICE_PATH_PROTOCOL            *Temp;
+  EFI_DEVICE_PATH_PROTOCOL            *Instance;
+  EFI_DEVICE_PATH_PROTOCOL            *Next;
+  EFI_HANDLE                          Handle;
+  EFI_EVENT                           Event;
+  EFI_GUID                            *TerminalGuid;
+  UINT8                               TerminalType;
+  UINTN                               InstanceSize;
+  
+  DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Append Usb Keyboard short form DevicePath into "ConInDev".
+  //
+  EfiBootManagerUpdateConsoleVariable (
+    ConInDev,
+    (EFI_DEVICE_PATH_PROTOCOL *) &mUsbClassKeyboardDevicePath,
+    NULL
+    );
+
+  //
+  // Get user defined text mode for internal shell only once.
+  //
+  mShellHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
+  mShellVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);
+  mShellModeColumn           = PcdGet32 (PcdSetupConOutColumn);
+  mShellModeRow              = PcdGet32 (PcdSetupConOutRow);
+
+  //
+  // Create event to set proper video resolution and text mode for internal shell.
+  //
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             OnReadyToBootCallBack,
+             NULL,
+             &Event
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created.
+  //
+  ConnectRootBridge (FALSE);
+
+  //
+  // Update ConOut variable accordign to the PrimaryDisplay setting.
+  //
+  GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConsoleOut, NULL);
+
+  //
+  // Add IGD to ConOut.
+  //
+  Handle = NULL;
+  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &mPlatformIGDDevice;
+  Status = gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &TempDevicePath, &Handle);
+  if (!EFI_ERROR (Status) &&
+    IsDevicePathEnd (TempDevicePath) &&
+    IsVgaHandle (Handle)) {
+  }
+  DEBUG ((EFI_D_INFO, "GOP Device Handle - 0x%x\n", Handle));
+
+  if (Handle != NULL) {
+    //
+    // Connect the GOP driver.
+    //
+    gBS->ConnectController (Handle, NULL, NULL, TRUE);
+
+    //
+    // Get the GOP device path.
+    // NOTE: We may get a device path that contains Controller node in it.
+    //
+    TempDevicePath = EfiBootManagerGetGopDevicePath (Handle);
+    DEBUG ((EFI_D_INFO, "GOP device path - 0x%x\n", TempDevicePath));
+    if (TempDevicePath != NULL) {
+      DEBUG ((EFI_D_INFO, "GOP device string - %S\n", DevicePathToStr ((EFI_DEVICE_PATH_PROTOCOL*)TempDevicePath) ));
+      Temp = ConsoleOut;
+      ConsoleOut = UpdateDevicePath (ConsoleOut, TempDevicePath);
+      if (Temp != NULL) {
+        FreePool (Temp);
+      }
+      FreePool (TempDevicePath);
+      Status = gRT->SetVariable (
+                      L"ConOut",
+                      &gEfiGlobalVariableGuid,
+                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                      GetDevicePathSize (ConsoleOut),
+                      ConsoleOut
+                      );
+    }
+  }
+
+  gBS->FreePool (ConsoleOut);
+
+  //
+  // Fill ConIn/ConOut in Full Configuration boot mode.
+  //
+  DEBUG ((DEBUG_ERROR, "PlatformBootManagerInit - %x\n", mBootMode));
+  if (mBootMode == BOOT_WITH_FULL_CONFIGURATION ||
+      mBootMode == BOOT_WITH_DEFAULT_SETTINGS ||
+      mBootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS ||
+      mBootMode == BOOT_IN_RECOVERY_MODE) {
+
+    GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL);   if (VarConOut != NULL) { FreePool (VarConOut); }
+    GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL);    if (VarConIn  != NULL) { FreePool (VarConIn);  }
+
+    if (VarConOut == NULL || VarConIn == NULL) {
+      //
+      // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may drop to Full Configuration boot mode in non-first boot.
+      // Update ConOutDevicePath (just in case it is wrong at build phase).
+      // To be enabled later.
+      //
+      for (Index = 0; mPlatformConsole[Index].DevicePath != NULL; Index++) {
+        //
+        // Update the console variable with the connect type.
+        //
+        if ((mPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+          EfiBootManagerUpdateConsoleVariable (ConIn, mPlatformConsole[Index].DevicePath, NULL);
+        }
+        if ((mPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+          EfiBootManagerUpdateConsoleVariable (ConOut, mPlatformConsole[Index].DevicePath, NULL);
+        }
+        if ((mPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+          EfiBootManagerUpdateConsoleVariable (ErrOut, mPlatformConsole[Index].DevicePath, NULL);
+        }
+      }
+    } else {
+      if (mBootMode == BOOT_WITH_DEFAULT_SETTINGS) {
+        //
+        // Get default Terminal Type.
+        //
+        TerminalGuid = &gEfiPcAnsiGuid;
+        TerminalType = PcdGet8 (PcdDefaultTerminalType);
+        if (TerminalType < 4) {
+          TerminalGuid = mLibTerminalType[TerminalType];
+        }
+
+        GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL);
+        Instance      = GetNextDevicePathInstance (&VarConIn, &InstanceSize);
+        InstanceSize -= END_DEVICE_PATH_LENGTH;
+
+        while (Instance != NULL) {
+          Next = Instance;
+          while (!IsDevicePathEndType (Next)) {
+            Next = NextDevicePathNode (Next);
+            if (DevicePathType (Next) == MESSAGING_DEVICE_PATH && DevicePathSubType (Next) == MSG_VENDOR_DP) {
+              //
+              // Restoring default serial device path.
+              //
+              EfiBootManagerUpdateConsoleVariable (ConIn, NULL, Instance);
+              EfiBootManagerUpdateConsoleVariable (ConOut, NULL, Instance);
+            }
+          }
+          FreePool(Instance);
+          Instance      = GetNextDevicePathInstance (&VarConIn, &InstanceSize);
+          InstanceSize -= END_DEVICE_PATH_LENGTH;
+        }
+      }
+    }
+  }
+
+  EnumPs2Keyboard ();
+  EnumUsbKeyboard ();
+
+  //
+  // Dynamically register hot key: F2/F7/Enter.
+  //
+  RegisterDefaultBootOption ();
+  RegisterStaticHotkey ();
+
+  //
+  // Connect Root Bridge to make PCI BAR resource allocated.
+  // Then exit PM auth before Legacy OPROM run.
+  //
+  ConnectRootBridge (FALSE);
+  
+  ProcessTcgPp ();
+
+  ExitPmAuth ();
+}
+
+/**
+  Connect with predeined platform connect sequence,
+  the OEM/IBV can customize with their own connect sequence.
+
+  @param[in] BootMode          Boot mode of this boot.
+**/
+VOID
+ConnectSequence (
+  IN EFI_BOOT_MODE         BootMode
+  )
+{
+  EfiBootManagerConnectAll ();
+}
+
+/**
+  The function is to consider the boot order which is not in our expectation.
+  In the case that we need to re-sort the boot option.
+
+  @retval  TRUE         Need to sort Boot Option.
+  @retval  FALSE        Don't need to sort Boot Option.
+**/
+BOOLEAN
+IsNeedSortBootOption (
+  VOID
+  )
+{
+  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptions;
+  UINTN                         BootOptionCount;
+
+  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+  //
+  // If setup is the first priority in boot option, we need to sort boot option.
+  //
+  if ((BootOptionCount > 1) &&
+      (((StrnCmp (BootOptions->Description, L"Enter Setup", StrLen (L"Enter Setup"))) == 0) ||
+       ((StrnCmp (BootOptions->Description, L"BootManagerMenuApp", StrLen (L"BootManagerMenuApp"))) == 0))) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  The function will excute with as the platform policy, current policy
+  is driven by boot mode. IBV/OEM can customize this code for their specific
+  policy action.
+
+  @param DriverOptionList - The header of the driver option link list
+  @param BootOptionList   - The header of the boot option link list
+  @param ProcessCapsules  - A pointer to ProcessCapsules()
+  @param BaseMemoryTest   - A pointer to BaseMemoryTest()
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  EFI_BOOT_MODE                 LocalBootMode;
+  
+  DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
+
+  //
+  // Get current Boot Mode.
+  //
+  LocalBootMode = mBootMode;
+  DEBUG ((DEBUG_ERROR, "Current local bootmode - %x\n", LocalBootMode));
+
+  //
+  // Go the different platform policy with different boot mode.
+  // Notes: this part code can be change with the table policy.
+  //
+  switch (LocalBootMode) {
+
+    case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+    case BOOT_WITH_MINIMAL_CONFIGURATION:
+    case BOOT_ON_S4_RESUME:
+      //
+      // Perform some platform specific connect sequence.
+      //
+      ConnectSequence (LocalBootMode);
+  
+      break;
+  
+    case BOOT_WITH_FULL_CONFIGURATION:
+    case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+    case BOOT_WITH_DEFAULT_SETTINGS:
+    default:
+      //
+      // Perform some platform specific connect sequence.
+      //
+      ConnectSequence (LocalBootMode);
+  
+      //
+      // Only in Full Configuration boot mode we do the enumeration of boot device.
+      //
+      EfiBootManagerRefreshAllBootOption ();
+  
+      break;
+  }
+  
+  if (IsNeedSortBootOption()) {
+    EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
+  }
+}
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.h
new file mode 100644
index 000000000..5ed9a4b37
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManager.h
@@ -0,0 +1,226 @@
+/** @file
+  Header file of Platform Boot Manager Lib.
+
+  Copyright (c) 2006 - 2018, 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.
+
+**/
+
+#ifndef _BDS_PLATFORM_H
+#define _BDS_PLATFORM_H
+
+#include <PiDxe.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DiskInfo.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GenericMemoryTest.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/MemoryOverwriteControl.h>
+#include <Guid/FileInfo.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformBootManagerLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/CapsuleLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <IndustryStandard/PciCodeId.h>
+
+#define CONSOLE_OUT 0x00000001
+#define STD_ERROR   0x00000002
+#define CONSOLE_IN  0x00000004
+#define CONSOLE_ALL (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)
+#define CLASS_HID           3
+#define SUBCLASS_BOOT       1
+#define PROTOCOL_KEYBOARD   1
+
+#define mPciRootBridge \
+  { \
+    ACPI_DEVICE_PATH, ACPI_DP, (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8), EISA_PNP_ID (0x0A03), 0 \
+  }
+
+#define mEndEntire \
+  { \
+    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, END_DEVICE_PATH_LENGTH, 0 \
+  }
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     ConnectType;
+} BDS_CONSOLE_CONNECT_ENTRY;
+
+//
+// Platform Root Bridge.
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Below is the platform console device path.
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IsaBridge;
+  ACPI_HID_DEVICE_PATH      Keyboard;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_KEYBOARD_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           IsaBridge;
+  ACPI_HID_DEVICE_PATH      IsaSerial;
+  UART_DEVICE_PATH          Uart;
+  VENDOR_DEVICE_PATH        TerminalType;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ISA_SERIAL_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           PciDevice;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_ONBOARD_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           Pci0Device;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_PEG_ROOT_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH      PciRootBridge;
+  PCI_DEVICE_PATH           PciBridge;
+  PCI_DEVICE_PATH           PciDevice;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} PLATFORM_PCI_CONTROLLER_DEVICE_PATH;
+
+typedef struct {
+  USB_CLASS_DEVICE_PATH           UsbClass;
+  EFI_DEVICE_PATH_PROTOCOL        End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+typedef
+VOID
+(*PROCESS_VARIABLE) (
+  VOID  **Variable,
+  UINTN *VariableSize
+  );
+
+/**
+  Generic function to update the console variable.
+  Please refer to FastBootSupport.c for how to use it.
+
+  @param VariableName    - The name of the variable to be updated
+  @param AgentGuid       - The Agent GUID
+  @param ProcessVariable - The function pointer to update the variable
+                           NULL means to restore to the original value
+**/
+VOID
+UpdateEfiGlobalVariable (
+  CHAR16           *VariableName,
+  EFI_GUID         *AgentGuid,
+  PROCESS_VARIABLE ProcessVariable
+  );
+
+VOID
+ConnectSequence (
+  IN EFI_BOOT_MODE                      BootMode
+  );
+
+INTN
+EFIAPI
+CompareBootOption (
+  CONST EFI_BOOT_MANAGER_LOAD_OPTION  *Left,
+  CONST EFI_BOOT_MANAGER_LOAD_OPTION  *Right
+  );
+
+VOID 
+PrintBootPrompt (
+  VOID
+  );
+
+VOID
+RegisterStaticHotkey (
+  VOID
+  );
+
+VOID
+RegisterDynamicHotkey (
+  VOID
+  );
+
+VOID
+RegisterDefaultBootOption (
+  VOID
+  );
+
+VOID
+BootUi (
+  VOID
+  );
+
+EFI_STATUS
+AutomaticFirmwareUpdateHandler (
+  CHAR16 *FileName
+  );
+
+EFI_STATUS
+EFIAPI
+EfiPlatformBootManagerProcessCapsules (
+  VOID
+  );
+
+VOID
+PlatformBootManagerAttemptUsbBoot (
+  VOID
+  );
+
+EFI_STATUS
+SetMorControl (
+  VOID
+  );
+  
+extern PLATFORM_ISA_SERIAL_DEVICE_PATH           mSerialDevicePath;
+extern EFI_DEVICE_PATH_PROTOCOL                  *mPlatformRootBridges[];
+extern BDS_CONSOLE_CONNECT_ENTRY                 mPlatformConsole[];
+extern PLATFORM_ONBOARD_CONTROLLER_DEVICE_PATH   mPlatformIGDDevice;
+extern PLATFORM_KEYBOARD_DEVICE_PATH             mKeyboardDevicePath;
+extern USB_CLASS_FORMAT_DEVICE_PATH              mUsbClassKeyboardDevicePath;
+extern USB_CLASS_FORMAT_DEVICE_PATH              gUsbClassMassStorageDevice;
+extern EFI_GUID                                  gUefiShellFileGuid;
+extern EFI_HII_HANDLE                            mPlatformBdsLibStringPackHandle;
+extern BDS_CONSOLE_CONNECT_ENTRY                 mPlatformConsole [];
+extern EFI_BOOT_MODE                             mBootMode;
+
+#endif
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 000000000..8e429fbf9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,109 @@
+## @file
+#  Component INF for module PlatformBootManagerLib.
+#
+#  Copyright (c) 2008 - 2018, 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.
+#
+##
+
+
+[Defines]
+  INF_VERSION = 0x00010017
+  BASE_NAME = DxePlatformBootManagerLib
+  FILE_GUID = A6BC385D-59E5-4b77-87D7-200ABAA83C15
+  VERSION_STRING = 1.0
+  MODULE_TYPE = DXE_DRIVER
+  UEFI_SPECIFICATION_VERSION = 2.10
+  LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+  #
+  # The following information is for reference only and not required by the build tools.
+  #
+  # VALID_ARCHITECTURES = IA32 X64 EBC
+  #
+  
+[Sources]
+  PlatformBootManager.c
+  PlatformData.c
+  PlatformBootOption.c
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  BroxtonPlatformPkg/PlatformPkg.dec
+  BroxtonSiPkg/BroxtonSiPkg.dec
+  
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid  
+  
+ [LibraryClasses]
+  BaseLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+  PrintLib
+  DevicePathLib
+  UefiLib
+  HobLib
+  DxeServicesLib
+  DxeServicesTableLib
+  HiiLib
+  UefiBootManagerLib
+  PerformanceLib
+  TimerLib
+  PciLib
+  Tcg2PhysicalPresenceLib
+  TcgPhysicalPresenceLib
+   
+[Protocols]
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiPciIoProtocolGuid
+  gEfiCpuIo2ProtocolGuid
+  gEfiDxeSmmReadyToLockProtocolGuid
+  gEfiGenericMemTestProtocolGuid
+  gEfiDiskInfoProtocolGuid
+  gEfiAcpiS3SaveProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
+  gEfiSimpleTextInputExProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiFormBrowser2ProtocolGuid
+  gExitPmAuthProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  
+[Guids]
+  gEfiGlobalVariableGuid
+  gEfiEndOfDxeEventGroupGuid
+  gEfiVTUTF8Guid
+  gEfiVT100Guid
+  gEfiVT100PlusGuid
+  gEfiPcAnsiGuid
+  gEfiTpmDeviceInstanceTpm20DtpmGuid
+  gTpmDeviceInstanceTpm20PttPtpGuid
+  gEfiTcg2PhysicalPresenceGuid
+  gEfiTpmDeviceInstanceTpm12Guid
+  
+[Depex.common.DXE_DRIVER]
+  gEfiVariableArchProtocolGuid
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootOption.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootOption.c
new file mode 100644
index 000000000..bed512a46
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformBootOption.c
@@ -0,0 +1,738 @@
+/** @file
+  This file include all platform action which can be customized by IBV/OEM.
+
+  Copyright (c) 2006 - 2018, 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 "PlatformBootManager.h"
+
+BOOLEAN    mContinueBoot  = FALSE;
+BOOLEAN    mUiAppBoot     = FALSE;
+BOOLEAN    mPxeBoot       = FALSE;
+BOOLEAN    mAnyKeypressed = FALSE;
+BOOLEAN    mHotKeypressed = FALSE;
+EFI_EVENT  HotKeyEvent    = NULL;
+UINTN      mUiAppOptionNumber;
+CHAR16     *TmpStr = L"Press [F2] key to enter BIOS Setup";
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
+
+EFI_GUID mUiFile = { 0x462CAA21, 0x7614, 0x4503, { 0x83, 0x6E, 0x8A, 0xB6, 0xF4, 0x66, 0x23, 0x31 } };
+EFI_GUID mBootMenuFile = { 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D }};
+EFI_GUID gUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 };
+
+#define INTERNAL_UEFI_SHELL_NAME      L"Internal UEFI Shell 2.0"
+#define UEFI_HARD_DRIVE_NAME          L"UEFI Hard Drive"
+#define UEFI_NVME_DRIVE_NAME          L"UEFI NVMe Storage"
+
+/**
+  Show progress bar with title above it. It only works in Graphics mode.
+
+  @param TitleForeground Foreground color for Title.
+  @param TitleBackground Background color for Title.
+  @param Title           Title above progress bar.
+  @param ProgressColor   Progress bar color.
+  @param Progress        Progress (0-100)
+  @param PreviousValue   The previous value of the progress.
+
+  @retval  EFI_STATUS       Success update the progress bar.
+
+**/
+EFI_STATUS
+PlatformBdsShowProgress (
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+  IN CHAR16                        *Title,
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+  IN UINTN                         Progress,
+  IN UINTN                         PreviousValue
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL   *GraphicsOutput;
+  UINT32                         SizeOfX;
+  UINT32                         SizeOfY;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL  Color;
+  UINTN                          BlockHeight;
+  UINTN                          BlockWidth;
+  UINTN                          BlockNum;
+  UINTN                          PosX;
+  UINTN                          PosY;
+  UINTN                          Index;
+
+  if (Progress > 100) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID **) &GraphicsOutput
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  SizeOfX = 0;
+  SizeOfY = 0;
+  if (GraphicsOutput != NULL) {
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  BlockWidth  = SizeOfX / 100;
+  BlockHeight = SizeOfY / 50;
+
+  BlockNum    = Progress;
+
+  PosX        = 0;
+  PosY        = SizeOfY * 48 / 50;
+
+  if (BlockNum == 0) {
+    //
+    // Clear progress area
+    //
+    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          &Color,
+                          EfiBltVideoFill,
+                          0,
+                          0,
+                          0,
+                          PosY - EFI_GLYPH_HEIGHT - 1,
+                          SizeOfX,
+                          SizeOfY - (PosY - EFI_GLYPH_HEIGHT - 1),
+                          SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else {
+      return EFI_UNSUPPORTED;
+    }
+  }
+  //
+  // Show progress by drawing blocks.
+  //
+  for (Index = PreviousValue; Index < BlockNum; Index++) {
+    PosX = Index * BlockWidth;
+    if (GraphicsOutput != NULL) {
+      Status = GraphicsOutput->Blt (
+                          GraphicsOutput,
+                          &ProgressColor,
+                          EfiBltVideoFill,
+                          0,
+                          0,
+                          PosX,
+                          PosY,
+                          BlockWidth - 1,
+                          BlockHeight,
+                          (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+                          );
+    } else {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  PrintXY (
+    (SizeOfX - StrLen (Title) * EFI_GLYPH_WIDTH) / 2,
+    PosY - EFI_GLYPH_HEIGHT - 1,
+    &TitleForeground,
+    &TitleBackground,
+    Title
+    );
+
+  return EFI_SUCCESS;
+}
+
+/*++
+
+This function will create a SHELL BootOption to boot.
+
+  @param  void
+
+  @retval EFI_STATUS
+
+--*/
+EFI_DEVICE_PATH_PROTOCOL *
+BdsCreateShellDevicePath (
+  VOID
+  )
+
+{
+  UINTN                             FvHandleCount;
+  EFI_HANDLE                        *FvHandleBuffer;
+  UINTN                             Index;
+  EFI_STATUS                        Status;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL     *Fv;
+  UINTN                             Size;
+  UINT32                            AuthenticationStatus;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+  VOID                              *Buffer;
+
+  DevicePath  = NULL;
+  Status      = EFI_SUCCESS;
+
+  DEBUG ((DEBUG_ERROR, "[FVMAIN2] BdsCreateShellDevicePath\n"));
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiFirmwareVolume2ProtocolGuid,
+        NULL,
+        &FvHandleCount,
+        &FvHandleBuffer
+        );
+
+  for (Index = 0; Index < FvHandleCount; Index++) {
+    gBS->HandleProtocol (
+          FvHandleBuffer[Index],
+          &gEfiFirmwareVolume2ProtocolGuid,
+          (VOID **) &Fv
+          );
+
+    Buffer  = NULL;
+    Size    = 0;
+    Status  = Fv->ReadSection (
+                    Fv,
+                    &gUefiShellFileGuid,
+                    EFI_SECTION_PE32,
+                    0,
+                    &Buffer,
+                    &Size,
+                    &AuthenticationStatus
+                    );
+    if (EFI_ERROR (Status)) {
+      //
+      // Skip if no shell file in the FV.
+      //
+      continue;
+    } else {
+      //
+      // Found the shell.
+      //
+      break;
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    //
+    // No shell present.
+    //
+    if (FvHandleCount) {
+      FreePool (FvHandleBuffer);
+    }
+    return NULL;
+  }
+  //
+  // Build the shell boot option.
+  //
+  DevicePath = DevicePathFromHandle (FvHandleBuffer[Index]);
+
+  if (FvHandleCount) {
+    FreePool (FvHandleBuffer);
+  }
+
+  return DevicePath;
+}
+
+EFI_STATUS
+CreateFvBootOption (
+  EFI_GUID                     *FileGuid,
+  CHAR16                       *Description,
+  EFI_BOOT_MANAGER_LOAD_OPTION *BootOption,
+  UINT32                       Attributes,
+  UINT8                        *OptionalData,    OPTIONAL
+  UINT32                       OptionalDataSize
+  )
+{
+  EFI_STATUS                         Status;
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
+  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL      *Fv;
+  UINT32                             AuthenticationStatus;
+  VOID                               *Buffer;
+  UINTN                              Size;
+
+  if ((BootOption == NULL) || (FileGuid == NULL) || (Description == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+
+  if (!CompareGuid (&gUefiShellFileGuid, FileGuid)) {
+    Status = gBS->HandleProtocol (
+                    gImageHandle,
+                    &gEfiLoadedImageProtocolGuid,
+                    (VOID **) &LoadedImage
+                    );
+    if (!EFI_ERROR (Status)) {
+      Status = gBS->HandleProtocol (
+                      LoadedImage->DeviceHandle,
+                      &gEfiFirmwareVolume2ProtocolGuid,
+                      (VOID **) &Fv
+                      );
+      if (!EFI_ERROR (Status)) {
+        Buffer  = NULL;
+        Size    = 0;
+        Status  = Fv->ReadSection (
+                        Fv,
+                        FileGuid,
+                        EFI_SECTION_PE32,
+                        0,
+                        &Buffer,
+                        &Size,
+                        &AuthenticationStatus
+                        );
+        if (Buffer != NULL) {
+          FreePool (Buffer);
+        }
+      }
+    }
+    if (EFI_ERROR (Status)) {
+      return EFI_NOT_FOUND;
+    }
+
+    DevicePath = AppendDevicePathNode (
+                   DevicePathFromHandle (LoadedImage->DeviceHandle),
+                   (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                   );
+  } else {
+    DevicePath = AppendDevicePathNode (
+                   BdsCreateShellDevicePath (),
+                   (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+                   );
+  }
+
+  Status = EfiBootManagerInitializeLoadOption (
+             BootOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             OptionalData,
+             OptionalDataSize
+             );
+  FreePool (DevicePath);
+  return Status;
+}
+
+/**
+  Return the index of the load option in the load option array.
+
+  The function consider two load options are equal when the 
+  OptionType, Attributes, Description, FilePath and OptionalData are equal.
+
+  @param Key    Pointer to the load option to be found.
+  @param Array  Pointer to the array of load options to be found.
+  @param Count  Number of entries in the Array.
+
+  @retval -1          Key wasn't found in the Array.
+  @retval 0 ~ Count-1 The index of the Key in the Array.
+**/
+INTN
+PlatformFindLoadOption (
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,
+  IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,
+  IN UINTN                              Count
+  )
+{
+  UINTN                             Index;
+
+  for (Index = 0; Index < Count; Index++) {
+    if ((Key->OptionType == Array[Index].OptionType) &&
+        (Key->Attributes == Array[Index].Attributes) &&
+        (StrCmp (Key->Description, Array[Index].Description) == 0) &&
+        (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&
+        (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&
+        (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {
+      return (INTN) Index;
+    }
+  }
+
+  return -1;
+}
+
+UINTN
+RegisterFvBootOption (
+  EFI_GUID       *FileGuid,
+  CHAR16         *Description,
+  UINTN          Position,
+  UINT32         Attributes,
+  UINT8          *OptionalData,    OPTIONAL
+  UINT32         OptionalDataSize
+  )
+{
+  EFI_STATUS                       Status;
+  UINTN                            OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION     NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION     *BootOptions;
+  UINTN                            BootOptionCount;
+
+  NewOption.OptionNumber = LoadOptionNumberUnassigned;
+  Status = CreateFvBootOption (FileGuid, Description, &NewOption, Attributes, OptionalData, OptionalDataSize);
+  if (!EFI_ERROR (Status)) {
+    BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+
+    OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);
+
+    if (OptionIndex == -1) {
+      Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position);
+      ASSERT_EFI_ERROR (Status);
+    } else {
+      NewOption.OptionNumber = BootOptions[OptionIndex].OptionNumber;
+    }
+    EfiBootManagerFreeLoadOption (&NewOption);
+    EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+  }
+
+  return NewOption.OptionNumber;
+}
+
+
+VOID
+BootUi (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+  Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+  if (!EFI_ERROR (Status)) {
+    EfiBootManagerBoot (&BootOption);
+    EfiBootManagerFreeLoadOption (&BootOption);
+  }
+}
+
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16          TimeoutRemain
+  )
+{
+  UINT16                        TimeoutDefault;
+  EFI_STATUS                    Status;
+  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *TxtInEx;
+  EFI_KEY_DATA                  KeyData;
+  BOOLEAN                       PausePressed;
+
+  TimeoutDefault = PcdGet16 (PcdPlatformBootTimeOut);
+  if (TimeoutDefault == TimeoutRemain) {
+    SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+    SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
+    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
+  }
+
+  PlatformBdsShowProgress (
+    Foreground,
+    Background,
+    TmpStr,
+    Color,
+    ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
+    0
+    );
+        
+  //
+  // Pause on PAUSE key.
+  //
+  Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TxtInEx);
+  ASSERT_EFI_ERROR (Status);
+
+  PausePressed = FALSE;
+
+  while (TRUE) {
+    Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    if (KeyData.Key.ScanCode == SCAN_PAUSE) {
+      PausePressed = TRUE;
+      break;
+    }
+  }
+
+  //
+  // Loop until non-PAUSE key pressed.
+  //
+  while (PausePressed) {
+    Status = TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData);
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_INFO, "[PauseCallback] %x/%x %x/%x\n",
+        KeyData.Key.ScanCode, KeyData.Key.UnicodeChar,
+        KeyData.KeyState.KeyShiftState, KeyData.KeyState.KeyToggleState
+        ));
+      PausePressed = (BOOLEAN) (KeyData.Key.ScanCode == SCAN_PAUSE);
+    }
+  }
+}
+
+/**
+  Check if the boot option is a EFI network boot option.
+
+  @param  Option         The boot option need to be processed.
+
+  @retval TRUE           It is a EFI network boot option.
+  @retval FALSE          It is not a EFI network boot option.
+
+**/
+BOOLEAN
+IsEfiNetWorkBootOption (
+  IN  EFI_BOOT_MANAGER_LOAD_OPTION     *Option
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL   *Node;
+
+  for (Node = Option->FilePath; !IsDevicePathEndType (Node); Node = NextDevicePathNode (Node)) {
+    if (DevicePathType (Node) == MESSAGING_DEVICE_PATH) {
+      switch (DevicePathSubType (Node)) {
+      case MSG_MAC_ADDR_DP:
+      case MSG_VLAN_DP:
+      case MSG_IPv4_DP:
+      case MSG_IPv6_DP:
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+VOID
+RegisterDefaultBootOption (
+  VOID
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
+  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  FileNode;
+  UINT16                             *ShellData;
+  UINT32                             ShellDataSize; 
+
+  //
+  // Shell.
+  //
+  if (1) {
+    ShellData = NULL;
+    ShellDataSize = 0;
+    RegisterFvBootOption (&gUefiShellFileGuid, INTERNAL_UEFI_SHELL_NAME,  (UINTN) -1, LOAD_OPTION_ACTIVE, (UINT8 *)ShellData, ShellDataSize);
+  }
+  
+  //
+  // UiApp.
+  //
+  mUiAppOptionNumber = RegisterFvBootOption (&mUiFile, L"Enter Setup",   (UINTN) -1, (LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE | LOAD_OPTION_HIDDEN), NULL, 0);
+  
+  if (mUiAppOptionNumber == LoadOptionNumberUnassigned) {
+    DEBUG ((DEBUG_ERROR, "UiAppOptionNumber (%d) should not be same to LoadOptionNumberUnassigned(%d).\n", mUiAppOptionNumber, LoadOptionNumberUnassigned));
+  }
+ 
+  //
+  // Boot Manager Menu.
+  //
+  EfiInitializeFwVolDevicepathNode (&FileNode, &mBootMenuFile);
+
+  gBS->HandleProtocol (
+         gImageHandle,
+         &gEfiLoadedImageProtocolGuid,
+         (VOID **) &LoadedImage
+         );
+  DevicePath = AppendDevicePathNode (DevicePathFromHandle (LoadedImage->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode);
+
+}
+
+VOID
+RegisterBootOptionHotkey (
+  UINT16                       OptionNumber,
+  EFI_INPUT_KEY                *Key,
+  BOOLEAN                      Add
+  )
+{
+  EFI_STATUS                   Status;
+
+  if (!Add) {
+    //
+    // No enter hotkey when force to setup or there is no boot option.
+    //
+    Status = EfiBootManagerDeleteKeyOptionVariable (NULL, 0, Key, NULL);
+    ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);
+  } else {
+    //
+    // Register enter hotkey for the first boot option.
+    //
+    Status = EfiBootManagerAddKeyOptionVariable (NULL, OptionNumber, 0, Key,NULL);
+    ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+  }
+}
+
+EFI_STATUS
+EFIAPI
+DetectKeypressCallback (
+  IN EFI_KEY_DATA     *KeyData
+)
+{
+  mHotKeypressed = TRUE;
+
+  if (HotKeyEvent != NULL) {
+    gBS->SignalEvent(HotKeyEvent);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is called after all the boot options are enumerated and ordered properly.
+**/
+VOID
+RegisterStaticHotkey (
+  VOID
+  )
+{
+
+  EFI_INPUT_KEY                 Enter;
+  EFI_KEY_DATA                  F2;
+  EFI_KEY_DATA                  F7;
+  BOOLEAN                       EnterSetup;
+  EFI_STATUS                    Status;
+  EFI_BOOT_MANAGER_LOAD_OPTION  BootOption;
+
+  EnterSetup = FALSE;
+
+  //
+  // [Enter]
+  //
+  mContinueBoot = !EnterSetup;
+  if (mContinueBoot) {
+    Enter.ScanCode    = SCAN_NULL;
+    Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+    EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+  }
+
+  //
+  // [F2]/[F7].
+  //
+  
+  F7.Key.ScanCode    = SCAN_F7;
+  F7.Key.UnicodeChar = CHAR_NULL;
+  F7.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+  F7.KeyState.KeyToggleState = 0;
+  Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+  ASSERT_EFI_ERROR (Status);
+  //
+  RegisterBootOptionHotkey ((UINT16) BootOption.OptionNumber, &F7.Key, TRUE);
+  EfiBootManagerFreeLoadOption (&BootOption);
+
+  F2.Key.ScanCode    = SCAN_F2;
+  F2.Key.UnicodeChar = CHAR_NULL;
+  F2.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+  F2.KeyState.KeyToggleState = 0;
+  mUiAppBoot  = !EnterSetup;
+  RegisterBootOptionHotkey ((UINT16) mUiAppOptionNumber, &F2.Key, mUiAppBoot);
+}
+
+UINT8
+BootOptionType (
+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL      *Node;
+  EFI_DEVICE_PATH_PROTOCOL      *NextNode;
+
+  for (Node = DevicePath; !IsDevicePathEndType (Node); Node = NextDevicePathNode (Node)) {
+    if (DevicePathType (Node) == MESSAGING_DEVICE_PATH) {
+      //
+      // Make sure the device path points to the driver device.
+      //
+      NextNode = NextDevicePathNode (Node);
+      if (DevicePathSubType(NextNode) == MSG_DEVICE_LOGICAL_UNIT_DP) {
+        //
+        // If the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN),
+        // skip it.
+        //
+        NextNode = NextDevicePathNode (NextNode);
+      }
+      if (IsDevicePathEndType (NextNode)) {
+        if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH)) {
+          return DevicePathSubType (Node);
+        } else {
+          return MSG_SATA_DP;
+        }
+      }
+    }
+  }
+
+  return (UINT8) -1;
+}
+
+/**
+  Returns the priority number.
+  
+  OptionType                 Default Priority
+  ------------------------------------
+  PXE                         5
+  DVD                         2
+  USB                         1
+  NVME                        4
+  HDD                         3
+  EFI Shell                   6
+  Others                      100
+
+  @param BootOption
+**/
+UINTN
+BootOptionPriority (
+  CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
+  )
+{
+    //
+    // EFI boot options.
+    //
+    switch (BootOptionType (BootOption->FilePath)) {
+      case MSG_MAC_ADDR_DP:
+      case MSG_VLAN_DP:
+      case MSG_IPv4_DP:
+      case MSG_IPv6_DP:
+        return 5;
+      case MSG_SATA_DP:
+      case MSG_ATAPI_DP:
+        return 2;
+      case MSG_USB_DP:
+        return 1;
+    }
+    
+    if (StrCmp (BootOption->Description, INTERNAL_UEFI_SHELL_NAME) == 0) {
+      return 6;
+    }
+    if (StrCmp (BootOption->Description, UEFI_HARD_DRIVE_NAME) == 0) {
+      return 3;
+    }
+    if (StrCmp (BootOption->Description, UEFI_NVME_DRIVE_NAME) == 0) {
+      return 4;
+    }
+    
+    return 100;
+}
+
+INTN
+EFIAPI
+CompareBootOption (
+  CONST EFI_BOOT_MANAGER_LOAD_OPTION  *Left,
+  CONST EFI_BOOT_MANAGER_LOAD_OPTION  *Right
+  )
+{
+  return BootOptionPriority (Left) - BootOptionPriority (Right);
+}
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformData.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 000000000..90b05334d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBootManagerLib/PlatformData.c
@@ -0,0 +1,179 @@
+/** @file
+  This file include all platform action which can be customized by IBV/OEM.
+
+  Copyright (c) 2006 - 2018, 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 "PlatformBootManager.h"
+
+#define PCI_DEVICE_NUMBER_PCH_LPC       31
+#define PCI_FUNCTION_NUMBER_PCH_LPC     0
+
+#define SA_IGD_DEV           0x02
+#define SA_IGD_FUN           0x00
+
+//
+// Predefined platform root bridge.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_ROOT_BRIDGE_DEVICE_PATH  gPlatformRootBridge0 = {
+  mPciRootBridge,
+  mEndEntire
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_PROTOCOL          *mPlatformRootBridges[] = {
+  (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0,
+  NULL
+};
+
+//
+// Platform specific keyboard device path.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_KEYBOARD_DEVICE_PATH     mKeyboardDevicePath = {
+  mPciRootBridge,
+  {
+    HARDWARE_DEVICE_PATH,
+    HW_PCI_DP,
+    (UINT8) (sizeof (PCI_DEVICE_PATH)),
+    (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8),
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    PCI_DEVICE_NUMBER_PCH_LPC
+  },
+  {
+    ACPI_DEVICE_PATH,
+    ACPI_DP,
+    (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+    (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8),
+    EISA_PNP_ID(0x0303),
+    0
+  },
+  mEndEntire
+};
+
+//
+// Platform specific serial device path.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_ISA_SERIAL_DEVICE_PATH   mSerialDevicePath = {
+  mPciRootBridge,
+  {
+    HARDWARE_DEVICE_PATH,
+    HW_PCI_DP,
+    (UINT8) (sizeof (PCI_DEVICE_PATH)),
+    (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8),
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    PCI_DEVICE_NUMBER_PCH_LPC
+  },
+  {
+    ACPI_DEVICE_PATH,
+    ACPI_DP,
+    (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+    (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8),
+    EISA_PNP_ID(0x0501),
+    0
+  },
+  {
+    MESSAGING_DEVICE_PATH,
+    MSG_UART_DP,
+    (UINT8) (sizeof (UART_DEVICE_PATH)),
+    (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8),
+    0,
+    115200,
+    8,
+    1,
+    1
+  },
+  {
+    MESSAGING_DEVICE_PATH,
+    MSG_VENDOR_DP,
+    (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+    (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8),
+    DEVICE_PATH_MESSAGING_PC_ANSI
+  },
+  mEndEntire
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH mUsbClassKeyboardDevicePath = {
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_USB_CLASS_DP,
+      (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
+      (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+    },
+    0xffff,           // VendorId 
+    0xffff,           // ProductId 
+    CLASS_HID,        // DeviceClass 
+    SUBCLASS_BOOT,    // DeviceSubClass
+    PROTOCOL_KEYBOARD // DeviceProtocol
+  },
+
+  { 
+    END_DEVICE_PATH_TYPE, 
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, 
+    END_DEVICE_PATH_LENGTH, 
+    0
+  }
+};
+
+//
+// Onboard VGA controller device path.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_ONBOARD_CONTROLLER_DEVICE_PATH         mPlatformIGDDevice = {
+  mPciRootBridge,
+  {
+    HARDWARE_DEVICE_PATH,
+    HW_PCI_DP,
+    (UINT8) (sizeof (PCI_DEVICE_PATH)),
+    (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8),
+    SA_IGD_FUN,
+    SA_IGD_DEV
+  },
+  mEndEntire
+};
+
+//
+// Predefined platform default console device path.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED BDS_CONSOLE_CONNECT_ENTRY         mPlatformConsole[] = {
+  {
+     (EFI_DEVICE_PATH_PROTOCOL *) &mSerialDevicePath,
+     (CONSOLE_OUT | CONSOLE_IN)
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *) &mKeyboardDevicePath,
+    CONSOLE_IN
+  },
+  {
+    (EFI_DEVICE_PATH_PROTOCOL *) &mUsbClassKeyboardDevicePath, 
+    CONSOLE_IN
+  },
+  {
+    NULL,
+    0
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH gUsbClassMassStorageDevice = {
+  {
+    {
+      MESSAGING_DEVICE_PATH,
+      MSG_USB_CLASS_DP,
+      (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
+      (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
+    },
+    0xffff,  // VendorId 
+    0xffff,  // ProductId 
+    0x08,    // DeviceClass    - USB Mass Storage Class
+    0x06,    // DeviceSubClass - SCSI Transparent Command Set
+    0xff     // DeviceProtocol - Match any Device Protocol
+  },
+  mEndEntire
+};
-- 
2.14.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel