Split the boot manager library from UiApp in MdeModulePkg/Application
and put the library in MdeModulePkg/Library.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dandan Bi <dandan...@intel.com>
---
 MdeModulePkg/Library/BootManagerLib/BootManager.c  | 820 +++++++++++++++++++++
 MdeModulePkg/Library/BootManagerLib/BootManager.h  | 171 +++++
 .../Library/BootManagerLib/BootManagerLib.inf      |  68 ++
 .../Library/BootManagerLib/BootManagerStrings.uni  | Bin 0 -> 3880 bytes
 .../Library/BootManagerLib/BootManagerVfr.Vfr      |  48 ++
 5 files changed, 1107 insertions(+)
 create mode 100644 MdeModulePkg/Library/BootManagerLib/BootManager.c
 create mode 100644 MdeModulePkg/Library/BootManagerLib/BootManager.h
 create mode 100644 MdeModulePkg/Library/BootManagerLib/BootManagerLib.inf
 create mode 100644 MdeModulePkg/Library/BootManagerLib/BootManagerStrings.uni
 create mode 100644 MdeModulePkg/Library/BootManagerLib/BootManagerVfr.Vfr

diff --git a/MdeModulePkg/Library/BootManagerLib/BootManager.c 
b/MdeModulePkg/Library/BootManagerLib/BootManager.c
new file mode 100644
index 0000000..875f6c3
--- /dev/null
+++ b/MdeModulePkg/Library/BootManagerLib/BootManager.c
@@ -0,0 +1,820 @@
+/** @file
+  The boot manager reference implementation
+
+  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+  This software and associated documentation (if any) is furnished
+  under a license and may only be used or copied in accordance
+  with the terms of the license. Except as permitted by such
+  license, no part of this software or documentation may be
+  reproduced, stored in a retrieval system, or transmitted in any
+  form or by any means without the express written consent of
+  Intel Corporation.
+
+**/
+
+#include "BootManager.h"
+
+EFI_EVENT          mBmEvent;
+UINT16             mKeyInput;
+EFI_GUID           mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
+//
+// Boot video resolution and text mode.
+//
+UINT32    mBmBootHorizontalResolution    = 0;
+UINT32    mBmBootVerticalResolution      = 0;
+UINT32    mBmBootTextModeColumn          = 0;
+UINT32    mBmBootTextModeRow             = 0;
+//
+// BIOS setup video resolution and text mode.
+//
+UINT32    mBmSetupTextModeColumn         = 0;
+UINT32    mBmSetupTextModeRow            = 0;
+UINT32    mBmSetupHorizontalResolution   = 0;
+UINT32    mBmSetupVerticalResolution     = 0;
+
+CHAR16             *mDeviceTypeStr[] = {
+  L"Legacy BEV",
+  L"Legacy Floppy",
+  L"Legacy Hard Drive",
+  L"Legacy CD ROM",
+  L"Legacy PCMCIA",
+  L"Legacy USB",
+  L"Legacy Embedded Network",
+  L"Legacy Unknown Device"
+};
+
+HII_VENDOR_DEVICE_PATH  mBootManagerHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    //
+    // {1DDDBE15-481D-4d2b-8277-B191EAF66525}
+    //
+    { 0x1dddbe15, 0x481d, 0x4d2b, { 0x82, 0x77, 0xb1, 0x91, 0xea, 0xf6, 0x65, 
0x25 } }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { 
+      (UINT8) (END_DEVICE_PATH_LENGTH),
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+BOOT_MANAGER_CALLBACK_DATA  gBootManagerPrivate = {
+  BOOT_MANAGER_CALLBACK_DATA_SIGNATURE,
+  NULL,
+  NULL,
+  {
+    BootManagerExtractConfig,
+    BootManagerRouteConfig,
+    BootManagerCallback
+  }
+};
+
+/**
+  This function will change video resolution and text mode
+  according to defined setup mode or defined boot mode  
+
+  @param  IsSetupMode   Indicate mode is changed to setup mode or boot mode. 
+
+  @retval  EFI_SUCCESS  Mode is changed successfully.
+  @retval  Others             Mode failed to be changed.
+
+**/
+EFI_STATUS
+EFIAPI
+BmBdsSetConsoleMode (
+  BOOLEAN  IsSetupMode
+  )
+{
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *SimpleTextOut;
+  UINTN                                 SizeOfInfo;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
+  UINT32                                MaxGopMode;
+  UINT32                                MaxTextMode;
+  UINT32                                ModeNumber;
+  UINT32                                NewHorizontalResolution;
+  UINT32                                NewVerticalResolution;
+  UINT32                                NewColumns;
+  UINT32                                NewRows;
+  UINTN                                 HandleCount;
+  EFI_HANDLE                            *HandleBuffer;
+  EFI_STATUS                            Status;
+  UINTN                                 Index;
+  UINTN                                 CurrentColumn;
+  UINTN                                 CurrentRow;  
+
+  MaxGopMode  = 0;
+  MaxTextMode = 0;
+
+  //
+  // Get current video resolution and text mode 
+  //
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiGraphicsOutputProtocolGuid,
+                  (VOID**)&GraphicsOutput
+                  );
+  if (EFI_ERROR (Status)) {
+    GraphicsOutput = NULL;
+  }
+
+  Status = gBS->HandleProtocol (
+                  gST->ConsoleOutHandle,
+                  &gEfiSimpleTextOutProtocolGuid,
+                  (VOID**)&SimpleTextOut
+                  );
+  if (EFI_ERROR (Status)) {
+    SimpleTextOut = NULL;
+  }
+
+  if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (IsSetupMode) {
+    //
+    // The requried resolution and text mode is setup mode.
+    //
+    NewHorizontalResolution = mBmSetupHorizontalResolution;
+    NewVerticalResolution   = mBmSetupVerticalResolution;
+    NewColumns              = mBmSetupTextModeColumn;
+    NewRows                 = mBmSetupTextModeRow;
+  } else {
+    //
+    // The required resolution and text mode is boot mode.
+    //
+    NewHorizontalResolution = mBmBootHorizontalResolution;
+    NewVerticalResolution   = mBmBootVerticalResolution;
+    NewColumns              = mBmBootTextModeColumn;
+    NewRows                 = mBmBootTextModeRow;   
+  }
+
+  if (GraphicsOutput != NULL) {
+    MaxGopMode  = GraphicsOutput->Mode->MaxMode;
+  }
+
+  if (SimpleTextOut != NULL) {
+    MaxTextMode = SimpleTextOut->Mode->MaxMode;
+  }
+
+  //
+  // 1. If current video resolution is same with required video resolution,
+  //    video resolution need not be changed.
+  //    1.1. If current text mode is same with required text mode, text mode 
need not be changed.
+  //    1.2. If current text mode is different from required text mode, text 
mode need be changed.
+  // 2. If current video resolution is different from required video 
resolution, we need restart whole console drivers.
+  //
+  for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
+    Status = GraphicsOutput->QueryMode (
+                       GraphicsOutput,
+                       ModeNumber,
+                       &SizeOfInfo,
+                       &Info
+                       );
+    if (!EFI_ERROR (Status)) {
+      if ((Info->HorizontalResolution == NewHorizontalResolution) &&
+          (Info->VerticalResolution == NewVerticalResolution)) {
+        if ((GraphicsOutput->Mode->Info->HorizontalResolution == 
NewHorizontalResolution) &&
+            (GraphicsOutput->Mode->Info->VerticalResolution == 
NewVerticalResolution)) {
+          //
+          // Current resolution is same with required resolution, check if 
text mode need be set
+          //
+          Status = SimpleTextOut->QueryMode (SimpleTextOut, 
SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
+          ASSERT_EFI_ERROR (Status);
+          if (CurrentColumn == NewColumns && CurrentRow == NewRows) {
+            //
+            // If current text mode is same with required text mode. Do nothing
+            //
+            FreePool (Info);
+            return EFI_SUCCESS;
+          } else {
+            //
+            // If current text mode is different from requried text mode.  Set 
new video mode
+            //
+            for (Index = 0; Index < MaxTextMode; Index++) {
+              Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, 
&CurrentColumn, &CurrentRow);
+              if (!EFI_ERROR(Status)) {
+                if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
+                  //
+                  // Required text mode is supported, set it.
+                  //
+                  Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
+                  ASSERT_EFI_ERROR (Status);
+                  //
+                  // Update text mode PCD.
+                  //
+                  PcdSet32 (PcdConOutColumn, mBmSetupTextModeColumn);
+                  PcdSet32 (PcdConOutRow, mBmSetupTextModeRow);
+                  FreePool (Info);
+                  return EFI_SUCCESS;
+                }
+              }
+            }
+            if (Index == MaxTextMode) {
+              //
+              // If requried text mode is not supported, return error.
+              //
+              FreePool (Info);
+              return EFI_UNSUPPORTED;
+            }
+          }
+        } else {
+          //
+          // If current video resolution is not same with the new one, set new 
video resolution.
+          // In this case, the driver which produces simple text out need be 
restarted.
+          //
+          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
+          if (!EFI_ERROR (Status)) {
+            FreePool (Info);
+            break;
+          }
+        }
+      }
+      FreePool (Info);
+    }
+  }
+
+  if (ModeNumber == MaxGopMode) {
+    //
+    // If the resolution is not supported, return error.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Set PCD to Inform GraphicsConsole to change video resolution.
+  // Set PCD to Inform Consplitter to change text mode.
+  //
+  PcdSet32 (PcdVideoHorizontalResolution, NewHorizontalResolution);
+  PcdSet32 (PcdVideoVerticalResolution, NewVerticalResolution);
+  PcdSet32 (PcdConOutColumn, NewColumns);
+  PcdSet32 (PcdConOutRow, NewRows);
+
+  //
+  // Video mode is changed, so restart graphics console driver and higher 
level driver.
+  // Reconnect graphics console driver and higher level driver.
+  // Locate all the handles with GOP protocol and reconnect it.
+  //
+  Status = gBS->LocateHandleBuffer (
+                   ByProtocol,
+                   &gEfiSimpleTextOutProtocolGuid,
+                   NULL,
+                   &HandleCount,
+                   &HandleBuffer
+                   );
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < HandleCount; Index++) {
+      gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
+    }
+    for (Index = 0; Index < HandleCount; Index++) {
+      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+    }
+    if (HandleBuffer != NULL) {
+      FreePool (HandleBuffer);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Group the legacy boot options in the BootOption.
+
+  The routine assumes the boot options in the beginning that covers all the 
device 
+  types are ordered properly and re-position the following boot options just 
after
+  the corresponding boot options with the same device type.
+  For example:
+  1. Input  = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
+     Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
+     Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
+
+  2. Input  = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
+     Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
+     Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
+
+**/
+VOID
+GroupMultipleLegacyBootOption4SameType (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  UINTN                        Index;
+  UINTN                        DeviceIndex;
+  UINTN                        DeviceTypeIndex[7];
+  UINTN                        *NextIndex;
+  UINT16                       OptionNumber;
+  UINT16                       *BootOrder;
+  UINTN                        BootOrderSize;
+  CHAR16                       OptionName[sizeof ("Boot####")];
+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+  SetMem (DeviceTypeIndex, sizeof (DeviceTypeIndex), 0xff);
+
+  GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);
+
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", 
BootOrder[Index]);
+    Status = EfiBootManagerVariableToLoadOption (OptionName, &BootOption);
+    ASSERT_EFI_ERROR (Status);
+
+    if ((DevicePathType (BootOption.FilePath) == BBS_DEVICE_PATH) &&
+        (DevicePathSubType (BootOption.FilePath) == BBS_BBS_DP)) {
+      //
+      // Legacy Boot Option
+      //
+      DEBUG ((EFI_D_ERROR, "[BootManagerDxe] ==== Find Legacy Boot Option  
0x%x! ==== \n", Index));
+      ASSERT ((((BBS_BBS_DEVICE_PATH *) BootOption.FilePath)->DeviceType & 
0xF) < sizeof (DeviceTypeIndex) / sizeof (DeviceTypeIndex[0]));
+      NextIndex = &DeviceTypeIndex[((BBS_BBS_DEVICE_PATH *) 
BootOption.FilePath)->DeviceType & 0xF];
+
+      if (*NextIndex == (UINTN) -1) {
+        //
+        // *NextIndex is the Index in BootOrder to put the next Option Number 
for the same type
+        //
+        *NextIndex = Index + 1;
+      } else {
+        //
+        // insert the current boot option before *NextIndex, causing [*Next .. 
Index] shift right one position
+        //
+        OptionNumber = BootOrder[Index];
+        CopyMem (&BootOrder[*NextIndex + 1], &BootOrder[*NextIndex], (Index - 
*NextIndex) * sizeof (UINT16));
+        BootOrder[*NextIndex] = OptionNumber;
+
+        //
+        // Update the DeviceTypeIndex array to reflect the right shift 
operation
+        //
+        for (DeviceIndex = 0; DeviceIndex < sizeof (DeviceTypeIndex) / sizeof 
(DeviceTypeIndex[0]); DeviceIndex++) {
+          if (DeviceTypeIndex[DeviceIndex] != (UINTN) -1 && 
DeviceTypeIndex[DeviceIndex] >= *NextIndex) {
+            DeviceTypeIndex[DeviceIndex]++;
+          }
+        }
+      }
+    }
+    EfiBootManagerFreeLoadOption (&BootOption);
+  }
+
+  gRT->SetVariable (
+         L"BootOrder",
+         &gEfiGlobalVariableGuid,
+         VAR_FLAG,
+         BootOrderSize,
+         BootOrder
+         );
+  FreePool (BootOrder);
+}
+
+/**
+  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 *
+BmDevicePathToStr (
+  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;
+}
+
+/**
+  This function invokes Boot Manager. If all devices have not a chance to be 
connected,
+  the connect all will be triggered. It then enumerate all boot options. If 
+  a boot option from the Boot Manager page is selected, Boot Manager will boot
+  from this boot option.
+  
+**/
+VOID
+UpdateBootManager (
+  VOID
+  )
+{
+  UINTN                         Index;
+  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption;
+  UINTN                         BootOptionCount;
+  EFI_STRING_ID                 Token;
+  CHAR16                        *HelpString;
+  EFI_STRING_ID                 HelpToken;
+  UINT16                        *TempStr;
+  EFI_HII_HANDLE                HiiHandle;
+  UINTN                         TempSize;
+  VOID                          *StartOpCodeHandle;
+  VOID                          *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL            *StartLabel;
+  EFI_IFR_GUID_LABEL            *EndLabel;
+  UINT16                        DeviceType;
+  BOOLEAN                       IsLegacyOption;
+  BOOLEAN                       NeedEndOp;
+  UINTN                         MaxLen;
+
+  DeviceType = (UINT16) -1;
+
+  EfiBootManagerConnectAll ();
+
+  //
+  // for better user experience
+  // 1. User changes HD configuration (e.g.: unplug HDD), here we have a 
chance to remove the HDD boot option
+  // 2. User enables/disables UEFI PXE, here we have a chance to add/remove 
EFI Network boot option
+  //
+  EfiBootManagerRefreshAllBootOption ();
+
+  //
+  // BdsDxe doesn't group the legacy boot options for the same device type
+  // It's UI's choice.
+  //
+  GroupMultipleLegacyBootOption4SameType ();
+
+  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, 
LoadOptionTypeBoot);
+
+  HiiHandle = gBootManagerPrivate.HiiHandle;
+
+  //
+  // Allocate space for creation of UpdateData Buffer
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, 
&gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_BOOT_OPTION;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, 
&gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_BOOT_OPTION_END;
+  mKeyInput = 0;
+  NeedEndOp = FALSE;
+  for (Index = 0; Index < BootOptionCount; Index++) {
+    //
+    // At this stage we are creating a menu entry, thus the Keys are 
reproduceable
+    //
+    mKeyInput++;
+
+    //
+    // Don't display the hidden/inactive boot option
+    //
+    if (((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) || 
((BootOption[Index].Attributes & LOAD_OPTION_ACTIVE) == 0)) {
+      continue;
+    }
+
+    //
+    // Group the legacy boot option in the sub title created dynamically
+    //
+    IsLegacyOption = (BOOLEAN) (
+                       (DevicePathType (BootOption[Index].FilePath) == 
BBS_DEVICE_PATH) &&
+                       (DevicePathSubType (BootOption[Index].FilePath) == 
BBS_BBS_DP)
+                       );
+
+    if (!IsLegacyOption && NeedEndOp) {
+      NeedEndOp = FALSE;
+      HiiCreateEndOpCode (StartOpCodeHandle);
+    }
+    
+    if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) 
BootOption[Index].FilePath)->DeviceType) {
+      if (NeedEndOp) {
+        HiiCreateEndOpCode (StartOpCodeHandle);
+      }
+
+      DeviceType = ((BBS_BBS_DEVICE_PATH *) 
BootOption[Index].FilePath)->DeviceType;
+      Token      = HiiSetString (
+                     HiiHandle,
+                     0,
+                     mDeviceTypeStr[
+                       MIN (DeviceType & 0xF, sizeof (mDeviceTypeStr) / sizeof 
(mDeviceTypeStr[0]) - 1)
+                       ],
+                     NULL
+                     );
+      HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);
+      NeedEndOp = TRUE;
+    }
+
+    ASSERT (BootOption[Index].Description != NULL);
+
+    Token = HiiSetString (HiiHandle, 0, BootOption[Index].Description, NULL);
+
+    TempStr = BmDevicePathToStr (BootOption[Index].FilePath);
+    TempSize = StrSize (TempStr);
+    HelpString = AllocateZeroPool (TempSize + StrSize (L"Device Path : "));
+    MaxLen = (TempSize + StrSize (L"Device Path : "))/sizeof(CHAR16);
+    ASSERT (HelpString != NULL);
+    StrCatS (HelpString, MaxLen, L"Device Path : ");
+    StrCatS (HelpString, MaxLen, TempStr);
+
+    HelpToken = HiiSetString (HiiHandle, 0, HelpString, NULL);
+
+    HiiCreateActionOpCode (
+      StartOpCodeHandle,
+      mKeyInput,
+      Token,
+      HelpToken,
+      EFI_IFR_FLAG_CALLBACK,
+      0
+      );
+  }
+
+  if (NeedEndOp) {
+    HiiCreateEndOpCode (StartOpCodeHandle);
+  }
+
+  HiiUpdateForm (
+    HiiHandle,
+    &mBootManagerGuid,
+    BOOT_MANAGER_FORM_ID,
+    StartOpCodeHandle,
+    EndOpCodeHandle
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+
+  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
+}
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param Request         A null-terminated Unicode string in <ConfigRequest> 
format.
+  @param Progress        On return, points to a character in the Request 
string.
+                         Points to the string's null terminator if request was 
successful.
+                         Points to the most recent '&' before the first 
failing name/value
+                         pair (or the beginning of the string if the failure 
is in the
+                         first name/value pair) if the request was not 
successful.
+  @param Results         A null-terminated Unicode string in <ConfigAltResp> 
format which
+                         has all values filled in for the names in the Request 
string.
+                         String to be allocated by the called function.
+
+  @retval  EFI_SUCCESS            The Results is filled with the requested 
values.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in 
this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerExtractConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  CONST EFI_STRING                       Request,
+  OUT EFI_STRING                             *Progress,
+  OUT EFI_STRING                             *Results
+  )
+{
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *Progress = Request;
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param Configuration   A null-terminated Unicode string in <ConfigResp> 
format.
+  @param Progress        A pointer to a string filled in with the offset of 
the most
+                         recent '&' before the first failing name/value pair 
(or the
+                         beginning of the string if the failure is in the first
+                         name/value pair) or the terminating NULL if all was 
successful.
+
+  @retval  EFI_SUCCESS            The Results is processed successfully.
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in 
this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerRouteConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  CONST EFI_STRING                       Configuration,
+  OUT EFI_STRING                             *Progress
+  )
+{
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Progress = Configuration;
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  This call back function is registered with Boot Manager formset.
+  When user selects a boot option, this call back function will
+  be triggered. The boot option is saved for later processing.
+
+
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param Action          Specifies the type of action taken by the browser.
+  @param QuestionId      A unique value which is sent to the original 
exporting driver
+                         so that it can identify the type of data to expect.
+  @param Type            The type of value for the question.
+  @param Value           A pointer to the data being sent to the original 
exporting driver.
+  @param ActionRequest   On return, points to the action requested by the 
callback function.
+
+  @retval  EFI_SUCCESS           The callback successfully handled the action.
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with 
invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerCallback (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  EFI_BROWSER_ACTION                     Action,
+  IN  EFI_QUESTION_ID                        QuestionId,
+  IN  UINT8                                  Type,
+  IN  EFI_IFR_TYPE_VALUE                     *Value,
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
+  )
+{
+  EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
+  UINTN                        BootOptionCount;
+  EFI_INPUT_KEY                Key;
+  if (Action != EFI_BROWSER_ACTION_CHANGED) {
+    //
+    // Do nothing for other UEFI Action. Only do call back when data is 
changed.
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((Value == NULL) || (ActionRequest == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, 
LoadOptionTypeBoot);
+  //
+  // parse the selected option
+  //
+  BmBdsSetConsoleMode (FALSE);
+  EfiBootManagerBoot (&BootOption[QuestionId - 1]);
+  BmBdsSetConsoleMode (TRUE);
+
+  if (EFI_ERROR (BootOption[QuestionId - 1].Status)) {
+    gST->ConOut->OutputString (
+                  gST->ConOut,
+                  HiiGetString (gBootManagerPrivate.HiiHandle, STRING_TOKEN 
(STR_ANY_KEY_CONTINUE), NULL)
+                  );
+    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+  }
+
+  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
+
+  return EFI_SUCCESS;
+}
+
+/**  
+  call back hooked on gEfiSetupEnterGuid, create the dynamic content for UEFI 
Option Rom Control.
+
+  @param  Event    The event
+  @param  Context  Notify event context.
+
+**/
+VOID
+UpdateBootManagerEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  //
+  // Update boot manager page 
+  //
+  UpdateBootManager ();
+}
+
+/**
+
+  Install Boot Manager Menu driver.
+
+  @param ImageHandle     The image handle.
+  @param SystemTable     The system table.
+
+  @retval  EFI_SUCEESS  Install Boot manager menu success.
+  @retval  Other        Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerLibConstructor (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS                     Status;
+  VOID                           *Registration;
+
+  //
+  // Install Device Path Protocol and Config Access protocol to driver handle
+  //
+  gBootManagerPrivate.DriverHandle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &gBootManagerPrivate.DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mBootManagerHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &gBootManagerPrivate.ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Publish our HII data
+  //
+  gBootManagerPrivate.HiiHandle = HiiAddPackages (
+                                    &mBootManagerGuid,
+                                    gBootManagerPrivate.DriverHandle,
+                                    BootManagerVfrBin,
+                                    BootManagerLibStrings,
+                                    NULL
+                                    );
+  ASSERT (gBootManagerPrivate.HiiHandle != NULL);
+
+  //
+  // Create event to update page when enter setup.
+  //
+  Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, 
UpdateBootManagerEvent, NULL, &mBmEvent);
+  ASSERT_EFI_ERROR (Status);
+  if(!EFI_ERROR(Status)){
+    Status = gBS->RegisterProtocolNotify (&gEfiSetupEnterGuid, mBmEvent, 
&Registration);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unloads the application and its installed protocol.
+
+  @param[in]  ImageHandle       Handle that identifies the image to be 
unloaded.
+  @param[in]  SystemTable       System Table
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+BootManagerLibDestructor (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  gBootManagerPrivate.DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mBootManagerHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &gBootManagerPrivate.ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  HiiRemovePackages (gBootManagerPrivate.HiiHandle);
+
+  gBS->CloseEvent (mBmEvent);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/MdeModulePkg/Library/BootManagerLib/BootManager.h 
b/MdeModulePkg/Library/BootManagerLib/BootManager.h
new file mode 100644
index 0000000..346d0c3
--- /dev/null
+++ b/MdeModulePkg/Library/BootManagerLib/BootManager.h
@@ -0,0 +1,171 @@
+/** @file
+  The boot manager reference implement
+
+  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+  This software and associated documentation (if any) is furnished
+  under a license and may only be used or copied in accordance
+  with the terms of the license. Except as permitted by such
+  license, no part of this software or documentation may be
+  reproduced, stored in a retrieval system, or transmitted in any
+  form or by any means without the express written consent of
+  Intel Corporation.
+
+**/
+
+#ifndef _EFI_BOOT_MANAGER_H_
+#define _EFI_BOOT_MANAGER_H_
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/HiiSetupEnter.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/DevicePathToText.h>
+
+#include <Library/PrintLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootManagerLib.h>
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH             VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL       End;
+} HII_VENDOR_DEVICE_PATH;
+#pragma pack()
+
+//
+// These are defined as the same with vfr file
+//
+#define BOOT_MANAGER_FORMSET_GUID \
+  { \
+  0x847bc3fe, 0xb974, 0x446d, {0x94, 0x49, 0x5a, 0xd5, 0x41, 0x2e, 0x99, 0x3b} 
\
+  }
+
+#define BOOT_MANAGER_FORM_ID     0x1000
+
+#define LABEL_BOOT_OPTION        0x00
+#define LABEL_BOOT_OPTION_END    0x01
+
+//
+// Variable created with this flag will be "Efi:...."
+//
+#define VAR_FLAG  EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE
+
+//
+// These are the VFR compiler generated data representing our VFR data.
+//
+extern UINT8 BootManagerVfrBin[];
+
+#define BOOT_MANAGER_CALLBACK_DATA_SIGNATURE  SIGNATURE_32 ('B', 'M', 'C', 'B')
+
+typedef struct {
+  UINTN                           Signature;
+
+  //
+  // HII relative handles
+  //
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_HANDLE                      DriverHandle;
+
+  //
+  // Produced protocols
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL   ConfigAccess;
+} BOOT_MANAGER_CALLBACK_DATA;
+
+/**
+  This call back function is registered with Boot Manager formset.
+  When user selects a boot option, this call back function will
+  be triggered. The boot option is saved for later processing.
+
+
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param Action          Specifies the type of action taken by the browser.
+  @param QuestionId      A unique value which is sent to the original 
exporting driver
+                         so that it can identify the type of data to expect.
+  @param Type            The type of value for the question.
+  @param Value           A pointer to the data being sent to the original 
exporting driver.
+  @param ActionRequest   On return, points to the action requested by the 
callback function.
+
+  @retval  EFI_SUCCESS           The callback successfully handled the action.
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with 
invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerCallback (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  EFI_BROWSER_ACTION                     Action,
+  IN  EFI_QUESTION_ID                        QuestionId,
+  IN  UINT8                                  Type,
+  IN  EFI_IFR_TYPE_VALUE                     *Value,
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
+  );
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+
+  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param Request         - A null-terminated Unicode string in <ConfigRequest> 
format.
+  @param Progress        - On return, points to a character in the Request 
string.
+                         Points to the string's null terminator if request was 
successful.
+                         Points to the most recent '&' before the first 
failing name/value
+                         pair (or the beginning of the string if the failure 
is in the
+                         first name/value pair) if the request was not 
successful.
+  @param Results         - A null-terminated Unicode string in <ConfigAltResp> 
format which
+                         has all values filled in for the names in the Request 
string.
+                         String to be allocated by the called function.
+
+  @retval  EFI_SUCCESS            The Results is filled with the requested 
values.
+  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval  EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown 
name.
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in 
this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerExtractConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  CONST EFI_STRING                       Request,
+  OUT EFI_STRING                             *Progress,
+  OUT EFI_STRING                             *Results
+  );
+
+/**
+  This function processes the results of changes in configuration.
+
+
+  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param Configuration   - A null-terminated Unicode string in <ConfigResp> 
format.
+  @param Progress        - A pointer to a string filled in with the offset of 
the most
+                         recent '&' before the first failing name/value pair 
(or the
+                         beginning of the string if the failure is in the first
+                         name/value pair) or the terminating NULL if all was 
successful.
+
+  @retval  EFI_SUCCESS            The Results is processed successfully.
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in 
this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+BootManagerRouteConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
+  IN  CONST EFI_STRING                       Configuration,
+  OUT EFI_STRING                             *Progress
+  );
+
+#endif
diff --git a/MdeModulePkg/Library/BootManagerLib/BootManagerLib.inf 
b/MdeModulePkg/Library/BootManagerLib/BootManagerLib.inf
new file mode 100644
index 0000000..30b6493
--- /dev/null
+++ b/MdeModulePkg/Library/BootManagerLib/BootManagerLib.inf
@@ -0,0 +1,68 @@
+## @file
+#  Boot Manager Library used by UiApp.
+#  
+#  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+#  This software and associated documentation (if any) is furnished
+#  under a license and may only be used or copied in accordance
+#  with the terms of the license. Except as permitted by such
+#  license, no part of this software or documentation may be
+#  reproduced, stored in a retrieval system, or transmitted in any
+#  form or by any means without the express written consent of
+#  Intel Corporation.
+#  
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BootManagerLib
+  FILE_GUID                      = CCB2DCE1-4FC8-41CB-88C5-D349E134C9FC
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION
+  CONSTRUCTOR                    = BootManagerLibConstructor
+  DESTRUCTOR                     = BootManagerLibDestructor
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  BootManager.h
+  BootManagerVfr.Vfr
+  BootManagerStrings.uni
+  BootManager.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  UefiRuntimeServicesTableLib
+  ReportStatusCodeLib
+  MemoryAllocationLib
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  PrintLib
+  HiiLib
+  UefiBootManagerLib
+
+[Guids]
+  gEfiIfrTianoGuid                              ## CONSUMES ## GUID (Extended 
IFR Guid Opcode)
+  gEfiIfrFrontPageGuid                          ## CONSUMES ## GUID
+  gEfiSetupEnterGuid                            ## CONSUMES ## GUID
+ 
+[Protocols]
+  gEfiHiiConfigAccessProtocolGuid               ## CONSUMES
+  gEfiDevicePathToTextProtocolGuid              ## CONSUMES
+
+[FeaturePcd]
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow                         ## 
CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn                      ## 
CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution         ## 
CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution           ## 
CONSUMES
+
diff --git a/MdeModulePkg/Library/BootManagerLib/BootManagerStrings.uni 
b/MdeModulePkg/Library/BootManagerLib/BootManagerStrings.uni
new file mode 100644
index 
0000000000000000000000000000000000000000..6be2b29dfb1a4565f546606047ba39370ff64ace
GIT binary patch
literal 3880
zcmd6q-BJ@l5QY2ND&Jv+3(yk$DZPu70YNDtP#_mxr9!fSlp%?mM9gDYKBRA<p06k4
zZX^le##mF?+1;7$K6CnKJHLKDF~%c}#9mv|TGqDI?%O?oALm4?r#7%m>m9q$Q$xGh
z-O+ELUsrd1y>IF+)4Z*@tChqKt){h_q*7lAJFc`l)%xaCTRW2N*~sl(*rn@Px4J!)
zzUTH-<Av@v#!t`er9IaDzU&O7wXJ(JWYWR4rndp%rdG;YX9s5qy1|`E4n&!K(X}C5
zC7t2Kw*KIQgAc;e@^kj3xhcKZ(vEE6r)>D#*N(2xw%jt>;EOjyyV71z=9m&&*Usix
z!^qDVY&5k$({7$F9aYgEL#^Ni*skf<*1o!H=NvhnE3J<7jECBOckb&$KQGvV$LgAU
z(h>0DS#;DjSa0aQ<NAvjuC;$4Y>8j73jdi-38yfWuT0{@6T9}+HTEQhEo6FQdGw+S
zeCLk3FE;A3RkS~;lNjj8Dq8RgT5}Au{1#3>&p(ktcq>}R?>*V+3MJS;3x>Wdqji$W
z5Mv>SQbk$Kqp+{Du|E}O$Obg*g73cG7MX}%=}4-GB<56<4~(G!&l7V&TcUUk9_tD*
z{NO$OmdY2Lg)G1i*Se3Ei3FkmJRy1muSEol<R1H@3>AmU^U7BJ9q(7g2skgqBh`hB
z16fCzex~}9*otC?b^K0FthnrSxu#CAVSCD9<o3pl{*VP^gJiG@|9NFQRhFMvRoQ>&
z*RoYKc3n?EH1C>Y8OjnhZ}J3SnN=GDrg_@$zBUa{k(t}^tctDa{2bYlxT=aLI4av)
zXQ^uMG#}WpPJVMt!&CGyc#2h)YMv_kVg(No94a_f^pi6@QgjYwjl9ca`hVm3-<)ff
zzoJ*F%7x&$MPhmpf1P<<$ayc>w+CDD1G!B7F4=c~##dCk=qIW<T|)d`QR!pXz_%#+
zoVpn6RLLtq_{v}-=!_cC6ypW^^E5_uMa_Lh+D)z0MrvV>Vpe3)?GVjF^$*L+=Ey$1
z5B)>VKYWM!8oGwIt!d9B&+uFE3P^OoMeq_ev*p_8JE&^YBu~|MA(Pvt6XHvZY^>JP
z>j^dFjb!gO7KzV15|`x@z5&F~d<M41d0EwbEFbJ^uH5<!T7-ey<8@igkga*v&?m3y
z)Ok#Xe;VQcMCb_Tb4V0@6ld=h$ILs<AzW6}L+s9ou0=RJRs_fHh%BPBnyfydM<Uj#
z0I6yKV_D3W#bQr5=;-N-*K~K~nMpqK?z5xhTgp?Ovwxo>n>fj=@5_NY0D7mYUr(Iz
Sx6(U*EW-S<7z}pl5q|?@dn*_K

literal 0
HcmV?d00001

diff --git a/MdeModulePkg/Library/BootManagerLib/BootManagerVfr.Vfr 
b/MdeModulePkg/Library/BootManagerLib/BootManagerVfr.Vfr
new file mode 100644
index 0000000..44bfc53
--- /dev/null
+++ b/MdeModulePkg/Library/BootManagerLib/BootManagerVfr.Vfr
@@ -0,0 +1,48 @@
+///** @file
+//
+//  Boot Manager formset.
+//
+//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+//  This software and associated documentation (if any) is furnished
+//  under a license and may only be used or copied in accordance
+//  with the terms of the license. Except as permitted by such
+//  license, no part of this software or documentation may be
+//  reproduced, stored in a retrieval system, or transmitted in any
+//  form or by any means without the express written consent of
+//  Intel Corporation.
+
+
+//**/
+#include <guid/HiiFrontPageFormset.h>
+#define FORMSET_GUID  { 0x847bc3fe, 0xb974, 0x446d, 0x94, 0x49, 0x5a, 0xd5, 
0x41, 0x2e, 0x99, 0x3b }
+
+#define BOOT_MANAGER_FORM_ID     0x1000
+
+#define LABEL_BOOT_OPTION        0x00
+#define LABEL_BOOT_OPTION_END    0x01
+
+formset
+  guid      = FORMSET_GUID,
+  title     = STRING_TOKEN(STR_BM_BANNER),
+  help      = STRING_TOKEN(STR_BOOT_MANAGER_HELP),
+  classguid = EFI_IFR_FRONT_PAGE_GUID,
+
+  form formid = BOOT_MANAGER_FORM_ID,
+       title  = STRING_TOKEN(STR_BM_BANNER);
+
+    subtitle text = STRING_TOKEN(STR_LAST_STRING);
+    subtitle text = STRING_TOKEN(STR_BOOT_OPTION_BANNER);
+    subtitle text = STRING_TOKEN(STR_LAST_STRING);
+
+    //
+    // This is where we will dynamically add choices for the Boot Manager
+    //
+    label LABEL_BOOT_OPTION;
+    label LABEL_BOOT_OPTION_END;
+
+    subtitle text = STRING_TOKEN(STR_LAST_STRING);
+    subtitle text = STRING_TOKEN(STR_HELP_FOOTER);
+
+  endform;
+
+endformset;
-- 
1.9.5.msysgit.1

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

Reply via email to