UEFI HII: Merge UEFI HII support changes from branch.
authorqwang12 <qwang12@de2fecce-e211-0410-80a6-f3fac2684e05>
Mon, 21 Jan 2008 14:39:56 +0000 (14:39 +0000)
committerqwang12 <qwang12@de2fecce-e211-0410-80a6-f3fac2684e05>
Mon, 21 Jan 2008 14:39:56 +0000 (14:39 +0000)
git-svn-id: https://edk2.tianocore.org/svn/edk2/trunk@4599 de2fecce-e211-0410-80a6-f3fac2684e05

139 files changed:
edk2/MdeModulePkg/Core/Dxe/DxeMain.inf
edk2/MdeModulePkg/Include/Library/GenericBdsLib.h [new file with mode: 0644]
edk2/MdeModulePkg/Include/Library/PlatformBdsLib.h [new file with mode: 0644]
edk2/MdeModulePkg/Include/MdeModuleHii.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/BdsBoot.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/BdsConnect.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/BdsMisc.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/DevicePath.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/Ebc/BmMachine.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.msa [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/Ia32/BmMachine.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/Ia32/ClearDr.asm [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/Ipf/BmMachine.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/Ipf/ShadowRom.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/Performance.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/R8Lib.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/R8Lib.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/x64/BmMachine.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/GenericBdsLib/x64/ClearDr.asm [new file with mode: 0644]
edk2/MdeModulePkg/Library/GraphicsLib/Graphics.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/GraphicsLib/GraphicsLib.inf [new file with mode: 0644]
edk2/MdeModulePkg/Library/GraphicsLib/GraphicsLib.msa [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/IfrSupportLib.inf [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/IfrSupportLib.msa [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/R8Lib.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/R8Lib.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrCommon.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrForm.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrLibraryInternal.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrOpCodeCreation.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrString.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/PlatformBdsLibNull/BdsPlatform.c [new file with mode: 0644]
edk2/MdeModulePkg/Library/PlatformBdsLibNull/BdsPlatform.h [new file with mode: 0644]
edk2/MdeModulePkg/Library/PlatformBdsLibNull/PlatformBdsLibNull.inf [new file with mode: 0644]
edk2/MdeModulePkg/Library/PlatformBdsLibNull/PlatformData.c [new file with mode: 0644]
edk2/MdeModulePkg/MdeModulePkg.dec
edk2/MdeModulePkg/MdeModulePkg.dsc
edk2/MdeModulePkg/Universal/BdsDxe/Bds.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BdsDxe.inf [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BdsDxe.msa [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/Bm.vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BmLib.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/Bmstring.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/BootOption.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/ConsoleOption.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/Data.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/FE.vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/FormGuid.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/UpdatePage.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMaint/Variable.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManager.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerStrings.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/BootMngr/BootManagerVfr.Vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/Capsules.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerStrings.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManagerVfr.Vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/FrontPage.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/FrontPage.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/FrontPageStrings.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/FrontPageVfr.Vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/Hotkey.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/Hotkey.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/HwErrRecSupport.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/Language.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/Language.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/MemoryTest.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/String.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/String.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/BdsDxe/Strings.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.c
edk2/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsole.h
edk2/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
edk2/MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.msa
edk2/MdeModulePkg/Universal/DevicePathDxe/DevicePathFromText.c
edk2/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c
edk2/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.msa [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/NVDataStruc.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/inventory.vfr [new file with mode: 0644]
edk2/MdeModulePkg/Universal/DriverSampleDxe/inventorystrings.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.msa [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseEntry.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/R8Lib.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/R8Lib.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/HiiDatabaseDxe/String.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Print.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Print.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/R8Lib.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/R8Lib.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowser.msa [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c [new file with mode: 0644]
edk2/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h [new file with mode: 0644]
edk2/MdeModulePkg/Universal/iScsi/IScsi.inf
edk2/MdeModulePkg/Universal/iScsi/IScsiCHAP.c
edk2/MdeModulePkg/Universal/iScsi/IScsiCHAP.h
edk2/MdeModulePkg/Universal/iScsi/IScsiConfig.c
edk2/MdeModulePkg/Universal/iScsi/IScsiConfig.h
edk2/MdeModulePkg/Universal/iScsi/IScsiConfigDxe.vfr
edk2/MdeModulePkg/Universal/iScsi/IScsiConfigNVDataStruc.h
edk2/MdeModulePkg/Universal/iScsi/IScsiDhcp.c
edk2/MdeModulePkg/Universal/iScsi/IScsiDhcp.h
edk2/MdeModulePkg/Universal/iScsi/IScsiIbft.c
edk2/MdeModulePkg/Universal/iScsi/IScsiImpl.h
edk2/MdeModulePkg/Universal/iScsi/IScsiMisc.c
edk2/MdeModulePkg/Universal/iScsi/IScsiProto.c
edk2/MdeModulePkg/Universal/iScsi/IScsiProto.h

index 9257fba..a6b6df2 100644 (file)
   gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueDxeCoreHandoffToBds | 0x3041001   # EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT\r
   gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueBootServiceExit | 0x3100019       # EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES\r
   gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueDxeDriverBegin | 0x3040002        # EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN\r
-  gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueDxeDriverEnd | 0x3040003          # EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END
\ No newline at end of file
+  gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueDxeDriverEnd | 0x3040003          # EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END\r
+\r
diff --git a/edk2/MdeModulePkg/Include/Library/GenericBdsLib.h b/edk2/MdeModulePkg/Include/Library/GenericBdsLib.h
new file mode 100644 (file)
index 0000000..9266a86
--- /dev/null
@@ -0,0 +1,565 @@
+/*++\r
+\r
+Copyright (c) 2004 - 2007, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  GenericBdsLib.h\r
+\r
+Abstract:\r
+\r
+  Generic BDS library definition, include the file and data structure\r
+\r
+--*/\r
+\r
+#ifndef _GENERIC_BDS_LIB_H_\r
+#define _GENERIC_BDS_LIB_H_\r
+\r
+//\r
+// WQBugBug: These Macro will be handled properly later.\r
+//\r
+//#undef EFI_SPECIFICATION_VERSION\r
+//#define EFI_SPECIFICATION_VERSION 0x0002000A\r
+\r
+#define PI_SPECIFICATION_VERSION 0x00010000\r
+\r
+#include <PiDxe.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <IndustryStandard/PeImage.h>\r
+\r
+\r
+extern EFI_HANDLE mBdsImageHandle;\r
+\r
+//\r
+// Constants which are variable names used to access variables\r
+//\r
+#define VarLegacyDevOrder L"LegacyDevOrder"\r
+\r
+//\r
+// Data structures and defines\r
+//\r
+#define FRONT_PAGE_QUESTION_ID  0x0000\r
+#define FRONT_PAGE_DATA_WIDTH   0x01\r
+\r
+//\r
+// ConnectType\r
+//\r
+#define CONSOLE_OUT 0x00000001\r
+#define STD_ERROR   0x00000002\r
+#define CONSOLE_IN  0x00000004\r
+#define CONSOLE_ALL (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)\r
+\r
+//\r
+// Load Option Attributes defined in EFI Specification\r
+//\r
+#define LOAD_OPTION_ACTIVE              0x00000001\r
+#define LOAD_OPTION_FORCE_RECONNECT     0x00000002\r
+\r
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
+#define LOAD_OPTION_HIDDEN              0x00000008\r
+#define LOAD_OPTION_CATEGORY            0x00001F00\r
+\r
+#define LOAD_OPTION_CATEGORY_BOOT       0x00000000\r
+#define LOAD_OPTION_CATEGORY_APP        0x00000100\r
+\r
+#define EFI_BOOT_OPTION_SUPPORT_KEY     0x00000001\r
+#define EFI_BOOT_OPTION_SUPPORT_APP     0x00000002\r
+#endif\r
+\r
+#define IS_LOAD_OPTION_TYPE(_c, _Mask)  (BOOLEAN) (((_c) & (_Mask)) != 0)\r
+\r
+//\r
+// Define Maxmim characters that will be accepted\r
+//\r
+#define MAX_CHAR            480\r
+#define MAX_CHAR_SIZE       (MAX_CHAR * 2)\r
+\r
+#define MIN_ALIGNMENT_SIZE  4\r
+#define ALIGN_SIZE(a)       ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)\r
+\r
+//\r
+// Define maximum characters for boot option variable "BootXXXX"\r
+//\r
+#define BOOT_OPTION_MAX_CHAR 10\r
+\r
+//\r
+// This data structure is the part of BDS_CONNECT_ENTRY that we can hard code.\r
+//\r
+#define BDS_LOAD_OPTION_SIGNATURE EFI_SIGNATURE_32 ('B', 'd', 'C', 'O')\r
+\r
+typedef struct {\r
+\r
+  UINTN                     Signature;\r
+  LIST_ENTRY                Link;\r
+\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+\r
+  CHAR16                    *OptionName;\r
+  UINTN                     OptionNumber;\r
+  UINT16                    BootCurrent;\r
+  UINT32                    Attribute;\r
+  CHAR16                    *Description;\r
+  VOID                      *LoadOptions;\r
+  UINT32                    LoadOptionsSize;\r
+  CHAR16                    *StatusString;\r
+\r
+} BDS_COMMON_OPTION;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  UINTN                     ConnectType;\r
+} BDS_CONSOLE_CONNECT_ENTRY;\r
+\r
+//\r
+// Lib Functions\r
+//\r
+\r
+//\r
+// Bds boot relate lib functions\r
+//\r
+EFI_STATUS\r
+BdsLibUpdateBootOrderList (\r
+  IN  LIST_ENTRY                 *BdsOptionList,\r
+  IN  CHAR16                         *VariableName\r
+  );\r
+\r
+VOID\r
+BdsLibBootNext (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibBootViaBootOption (\r
+  IN  BDS_COMMON_OPTION             * Option,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL      * DevicePath,\r
+  OUT UINTN                         *ExitDataSize,\r
+  OUT CHAR16                        **ExitData OPTIONAL\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibEnumerateAllBootOption (\r
+  IN OUT LIST_ENTRY    *BdsBootOptionList\r
+  );\r
+\r
+VOID\r
+BdsLibBuildOptionFromHandle (\r
+  IN  EFI_HANDLE          Handle,\r
+  IN  LIST_ENTRY      *BdsBootOptionList,\r
+  IN  CHAR16              *String\r
+  );\r
+\r
+VOID\r
+BdsLibBuildOptionFromShell (\r
+  IN  EFI_HANDLE                     Handle,\r
+  IN  LIST_ENTRY                 *BdsBootOptionList\r
+  );\r
+\r
+//\r
+// Bds misc lib functions\r
+//\r
+UINT16\r
+BdsLibGetTimeout (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibGetBootMode (\r
+  OUT EFI_BOOT_MODE       *BootMode\r
+  );\r
+\r
+VOID\r
+BdsLibLoadDrivers (\r
+  IN  LIST_ENTRY              *BdsDriverLists\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibBuildOptionFromVar (\r
+  IN  LIST_ENTRY              *BdsCommonOptionList,\r
+  IN  CHAR16                      *VariableName\r
+  );\r
+\r
+VOID                      *\r
+BdsLibGetVariableAndSize (\r
+  IN  CHAR16              *Name,\r
+  IN  EFI_GUID            *VendorGuid,\r
+  OUT UINTN               *VariableSize\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibOutputStrings (\r
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut,\r
+  ...\r
+  );\r
+\r
+BDS_COMMON_OPTION         *\r
+BdsLibVariableToOption (\r
+  IN OUT LIST_ENTRY               *BdsCommonOptionList,\r
+  IN CHAR16                           *VariableName\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibRegisterNewOption (\r
+  IN  LIST_ENTRY                 *BdsOptionList,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,\r
+  IN  CHAR16                         *String,\r
+  IN  CHAR16                         *VariableName\r
+  );\r
+\r
+//\r
+// Bds connect or disconnect driver lib funcion\r
+//\r
+VOID\r
+BdsLibConnectAllDriversToAllControllers (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+BdsLibConnectAll (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibConnectDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibConnectAllEfi (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibDisconnectAllEfi (\r
+  VOID\r
+  );\r
+\r
+//\r
+// Bds console relate lib functions\r
+//\r
+VOID\r
+BdsLibConnectAllConsoles (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibConnectAllDefaultConsoles (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibUpdateConsoleVariable (\r
+  IN  CHAR16                    *ConVarName,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibConnectConsoleVariable (\r
+  IN  CHAR16                 *ConVarName\r
+  );\r
+\r
+//\r
+// Bds device path relate lib functions\r
+//\r
+EFI_DEVICE_PATH_PROTOCOL  *\r
+BdsLibUnpackDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath\r
+  );\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Multi,\r
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Single\r
+  );\r
+\r
+BOOLEAN\r
+BdsLibMatchDevicePaths (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single\r
+  );\r
+\r
+CHAR16                    *\r
+DevicePathToStr (\r
+  EFI_DEVICE_PATH_PROTOCOL     *DevPath\r
+  );\r
+\r
+VOID                      *\r
+EfiLibGetVariable (\r
+  IN CHAR16               *Name,\r
+  IN EFI_GUID             *VendorGuid\r
+  );\r
+\r
+//\r
+// Internal definitions\r
+//\r
+typedef struct {\r
+  CHAR16  *str;\r
+  UINTN   len;\r
+  UINTN   maxlen;\r
+} POOL_PRINT;\r
+\r
+typedef struct {\r
+  UINT8 Type;\r
+  UINT8 SubType;\r
+  VOID (*Function) (POOL_PRINT *, VOID *);\r
+} DEVICE_PATH_STRING_TABLE;\r
+\r
+extern EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  EFI_GUID                  Guid;\r
+  UINT8                     VendorDefinedData[1];\r
+} VENDOR_DEVICE_PATH_WITH_DATA;\r
+\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+\r
+extern EFI_GUID mEfiDevicePathMessagingSASGuid;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  UINT16                    NetworkProtocol;\r
+  UINT16                    LoginOption;\r
+  UINT64                    Lun;\r
+  UINT16                    TargetPortalGroupTag;\r
+  CHAR16                    iSCSITargetName[1];\r
+} ISCSI_DEVICE_PATH_WITH_NAME;\r
+\r
+#endif\r
+\r
+//\r
+// Internal functions\r
+//\r
+EFI_STATUS\r
+BdsBootByDiskSignatureAndPartition (\r
+  IN  BDS_COMMON_OPTION          * Option,\r
+  IN  HARDDRIVE_DEVICE_PATH      * HardDriveDevicePath,\r
+  IN  UINT32                     LoadOptionsSize,\r
+  IN  VOID                       *LoadOptions,\r
+  OUT UINTN                      *ExitDataSize,\r
+  OUT CHAR16                     **ExitData OPTIONAL\r
+  );\r
+\r
+//\r
+// Notes: EFI 64 shadow all option rom\r
+//\r
+#if defined (MDE_CPU_IPF)\r
+#define EFI64_SHADOW_ALL_LEGACY_ROM() ShadowAllOptionRom ();\r
+VOID\r
+ShadowAllOptionRom();\r
+#else\r
+#define EFI64_SHADOW_ALL_LEGACY_ROM()\r
+#endif\r
+\r
+//\r
+// BBS support macros and functions\r
+//\r
+\r
+#if defined(MDE_CPU_IA32) || defined(MDE_CPU_X64)\r
+#define REFRESH_LEGACY_BOOT_OPTIONS \\r
+        BdsDeleteAllInvalidLegacyBootOptions ();\\r
+        BdsAddNonExistingLegacyBootOptions (); \\r
+        BdsUpdateLegacyDevOrder ()\r
+#else\r
+#define REFRESH_LEGACY_BOOT_OPTIONS\r
+#endif\r
+\r
+EFI_STATUS\r
+BdsDeleteAllInvalidLegacyBootOptions (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsAddNonExistingLegacyBootOptions (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsUpdateLegacyDevOrder (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsRefreshBbsTableForBoot (\r
+  IN BDS_COMMON_OPTION        *Entry\r
+  );\r
+\r
+EFI_STATUS\r
+BdsDeleteBootOption (\r
+  IN UINTN                       OptionNumber,\r
+  IN OUT UINT16                  *BootOrder,\r
+  IN OUT UINTN                   *BootOrderSize\r
+  );\r
+\r
+//\r
+//The interface functions relate with Setup Browser Reset Reminder feature\r
+//\r
+VOID\r
+EnableResetReminderFeature (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+DisableResetReminderFeature (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EnableResetRequired (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+DisableResetRequired (\r
+  VOID\r
+  );\r
+\r
+BOOLEAN\r
+IsResetReminderFeatureEnable (\r
+  VOID\r
+  );\r
+\r
+BOOLEAN\r
+IsResetRequired (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+SetupResetReminder (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibGetImageHeader (\r
+  IN  EFI_HANDLE                  Device,\r
+  IN  CHAR16                      *FileName,\r
+  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,\r
+  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+BdsLibGetHiiHandles (\r
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
+  IN     EFI_HII_DATABASE_PROTOCOL *HiiDatabase,\r
+#else\r
+  IN     EFI_HII_PROTOCOL          *Hii,\r
+#endif\r
+  IN OUT UINT16                    *HandleBufferLength,\r
+  OUT    EFI_HII_HANDLE            **HiiHandleBuffer\r
+  );\r
+  \r
+//\r
+// Define the boot type which to classify the boot option type\r
+// Different boot option type could have different boot behavior\r
+// Use their device path node (Type + SubType) as type value\r
+// The boot type here can be added according to requirement\r
+//\r
+//\r
+// ACPI boot type. For ACPI device, cannot use sub-type to distinguish device, so hardcode their value\r
+//\r
+#define  BDS_EFI_ACPI_FLOPPY_BOOT         0x0201\r
+//\r
+// Message boot type\r
+// If a device path of boot option only point to a message node, the boot option is message boot type\r
+//\r
+#define  BDS_EFI_MESSAGE_ATAPI_BOOT       0x0301 // Type 03; Sub-Type 01\r
+#define  BDS_EFI_MESSAGE_SCSI_BOOT        0x0302 // Type 03; Sub-Type 02\r
+#define  BDS_EFI_MESSAGE_USB_DEVICE_BOOT  0x0305 // Type 03; Sub-Type 05\r
+#define  BDS_EFI_MESSAGE_MISC_BOOT        0x03FF\r
+//\r
+// Media boot type\r
+// If a device path of boot option contain a media node, the boot option is media boot type\r
+//\r
+#define  BDS_EFI_MEDIA_HD_BOOT            0x0401 // Type 04; Sub-Type 01\r
+#define  BDS_EFI_MEDIA_CDROM_BOOT         0x0402 // Type 04; Sub-Type 02\r
+//\r
+// BBS boot type\r
+// If a device path of boot option contain a BBS node, the boot option is BBS boot type\r
+//\r
+#define  BDS_LEGACY_BBS_BOOT              0x0501 //  Type 05; Sub-Type 01\r
+\r
+#define  BDS_EFI_UNSUPPORT                0xFFFF\r
+\r
+//\r
+// USB host controller Programming Interface.\r
+//\r
+#define  PCI_CLASSC_PI_UHCI               0x00\r
+#define  PCI_CLASSC_PI_EHCI               0x20\r
+\r
+BOOLEAN\r
+MatchPartitionDevicePathNode (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL   *BlockIoDevicePath,\r
+  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath\r
+  );\r
+  \r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsExpandPartitionPartialDevicePathToFull (\r
+  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath\r
+  );\r
+  \r
+EFI_HANDLE\r
+BdsLibGetBootableHandle (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath\r
+  );\r
+  \r
+BOOLEAN\r
+BdsLibIsValidEFIBootOptDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,\r
+  IN BOOLEAN                      CheckMedia\r
+  );\r
+  \r
+UINT32\r
+BdsGetBootTypeFromDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath\r
+  );\r
+  \r
+VOID\r
+EFIAPI\r
+BdsLibSaveMemoryTypeInformation (\r
+  VOID \r
+  );\r
+  \r
+EFI_STATUS\r
+EFIAPI\r
+BdsLibUpdateFvFileDevicePath (\r
+  IN  OUT EFI_DEVICE_PATH_PROTOCOL      ** DevicePath,\r
+  IN  EFI_GUID                          *FileGuid\r
+  );\r
+\r
+EFI_STATUS\r
+BdsLibConnectUsbDevByShortFormDP (\r
+  IN CHAR8                      HostControllerPI,\r
+  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath\r
+  );\r
+  \r
+EFI_TPL\r
+BdsLibGetCurrentTpl (\r
+  VOID\r
+  );\r
+\r
+//\r
+// The implementation of this function is provided by Platform code.\r
+//\r
+VOID\r
+DevPathVendor (\r
+  IN OUT POOL_PRINT       *Str,\r
+  IN VOID                 *DevPath\r
+  )\r
+;\r
+\r
+CHAR16 *\r
+CatPrint (\r
+  IN OUT POOL_PRINT   *Str,\r
+  IN CHAR16           *fmt,\r
+  ...\r
+  )\r
+;\r
+#endif // _BDS_LIB_H_\r
diff --git a/edk2/MdeModulePkg/Include/Library/PlatformBdsLib.h b/edk2/MdeModulePkg/Include/Library/PlatformBdsLib.h
new file mode 100644 (file)
index 0000000..cc11824
--- /dev/null
@@ -0,0 +1,98 @@
+/*++\r
+\r
+Copyright (c) 2008, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  PlatformBdsLib.h\r
+\r
+Abstract:\r
+\r
+  Platform BDS library definition, include the file and data structure\r
+\r
+--*/\r
+\r
+#ifndef __PLATFORM_BDS_LIB_H_\r
+#define __PLATFORM_BDS_LIB_H_\r
+\r
+#include <PiDxe.h>\r
+#include <Protocol/Bds.h>\r
+#include <Protocol/GenericMemoryTest.h>\r
+\r
+//\r
+// Bds AP Context data\r
+//\r
+#define EFI_BDS_ARCH_PROTOCOL_INSTANCE_SIGNATURE  EFI_SIGNATURE_32 ('B', 'd', 's', 'A')\r
+typedef struct _EFI_BDS_ARCH_PROTOCOL_INSTANCE EFI_BDS_ARCH_PROTOCOL_INSTANCE;\r
+\r
+struct _EFI_BDS_ARCH_PROTOCOL_INSTANCE {\r
+  UINTN                     Signature;\r
+  EFI_HANDLE                Handle;\r
+  EFI_BDS_ARCH_PROTOCOL     Bds;\r
+  //\r
+  // Save the current boot mode\r
+  //\r
+  EFI_BOOT_MODE             BootMode;\r
+  //\r
+  // Set true if boot with default settings\r
+  //\r
+  BOOLEAN                   DefaultBoot;\r
+  //\r
+  // The system default timeout for choose the boot option\r
+  //\r
+  UINT16                    TimeoutDefault;\r
+  //\r
+  // Memory Test Level\r
+  //\r
+  EXTENDMEM_COVERAGE_LEVEL  MemoryTestLevel;\r
+};\r
+\r
+//\r
+// Platform BDS Functions\r
+//\r
+VOID\r
+EFIAPI\r
+PlatformBdsInit (\r
+  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData\r
+  )\r
+;\r
+\r
+VOID\r
+EFIAPI\r
+PlatformBdsPolicyBehavior (\r
+  IN EFI_BDS_ARCH_PROTOCOL_INSTANCE  *PrivateData,\r
+  IN LIST_ENTRY                      *DriverOptionList,\r
+  IN LIST_ENTRY                      *BootOptionList\r
+  )\r
+;\r
+\r
+\r
+VOID\r
+PlatformBdsBootFail (\r
+  IN  BDS_COMMON_OPTION  *Option,\r
+  IN  EFI_STATUS         Status,\r
+  IN  CHAR16             *ExitData,\r
+  IN  UINTN              ExitDataSize\r
+  )\r
+;\r
+\r
+VOID\r
+PlatformBdsBootSuccess (\r
+  IN  BDS_COMMON_OPTION *Option\r
+  )\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformBdsLockNonUpdatableFlash (\r
+  VOID\r
+  )\r
+;\r
+#endif\r
diff --git a/edk2/MdeModulePkg/Include/MdeModuleHii.h b/edk2/MdeModulePkg/Include/MdeModuleHii.h
new file mode 100644 (file)
index 0000000..7f99ccd
--- /dev/null
@@ -0,0 +1,125 @@
+/* @file\r
+\r
+  EDK II specific HII relative definition.\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _MDEMODULE_HII_H\r
+#define _MDEMODULE_HII_H\r
+\r
+#define NARROW_CHAR         0xFFF0\r
+#define WIDE_CHAR           0xFFF1\r
+#define NON_BREAKING_CHAR   0xFFF2\r
+\r
+#define GLYPH_WIDTH         EFI_GLYPH_WIDTH\r
+#define GLYPH_HEIGHT        EFI_GLYPH_HEIGHT\r
+\r
+//\r
+// State defined for password statemachine \r
+//\r
+#define BROWSER_STATE_VALIDATE_PASSWORD  0\r
+#define BROWSER_STATE_SET_PASSWORD       1\r
+\r
+\r
+//\r
+// Tiano Implementation specific Device Path definition.\r
+//\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH             VendorDevicePath;\r
+  UINT32                         MonotonicCount;\r
+} HII_VENDOR_DEVICE_PATH_NODE;\r
+\r
+typedef struct {\r
+  HII_VENDOR_DEVICE_PATH_NODE    Node;\r
+  EFI_DEVICE_PATH_PROTOCOL       End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+\r
+//\r
+// References to string tokens must use this macro to enable scanning for\r
+// token usages.\r
+//\r
+#define STRING_TOKEN(t) t\r
+\r
+//\r
+// GUIDed opcodes defined for Tiano\r
+//\r
+#define EFI_IFR_TIANO_GUID \\r
+  { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce} }\r
+\r
+\r
+#pragma pack(1)\r
+\r
+#define EFI_IFR_EXTEND_OP_LABEL       0x0\r
+#define EFI_IFR_EXTEND_OP_BANNER      0x1\r
+#define EFI_IFR_EXTEND_OP_TIMEOUT     0x2\r
+#define EFI_IFR_EXTEND_OP_CLASS       0x3\r
+#define EFI_IFR_EXTEND_OP_SUBCLASS    0x4\r
+\r
+typedef struct _EFI_IFR_GUID_LABEL {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode;\r
+  UINT16              Number;\r
+} EFI_IFR_GUID_LABEL;\r
+\r
+#define EFI_IFR_BANNER_ALIGN_LEFT     0\r
+#define EFI_IFR_BANNER_ALIGN_CENTER   1\r
+#define EFI_IFR_BANNER_ALIGN_RIGHT    2\r
+\r
+typedef struct _EFI_IFR_GUID_BANNER {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER\r
+  EFI_STRING_ID       Title;        // The string token for the banner title\r
+  UINT16              LineNumber;   // 1-based line number\r
+  UINT8               Alignment;    // left, center, or right-aligned\r
+} EFI_IFR_GUID_BANNER;\r
+\r
+typedef struct _EFI_IFR_GUID_TIMEOUT {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode;\r
+  UINT16              TimeOut;\r
+} EFI_IFR_GUID_TIMEOUT;\r
+\r
+#define EFI_NON_DEVICE_CLASS              0x00\r
+#define EFI_DISK_DEVICE_CLASS             0x01\r
+#define EFI_VIDEO_DEVICE_CLASS            0x02\r
+#define EFI_NETWORK_DEVICE_CLASS          0x04\r
+#define EFI_INPUT_DEVICE_CLASS            0x08\r
+#define EFI_ON_BOARD_DEVICE_CLASS         0x10\r
+#define EFI_OTHER_DEVICE_CLASS            0x20\r
+\r
+typedef struct _EFI_IFR_GUID_CLASS {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode;\r
+  UINT16              Class;\r
+} EFI_IFR_GUID_CLASS;\r
+\r
+#define EFI_SETUP_APPLICATION_SUBCLASS    0x00\r
+#define EFI_GENERAL_APPLICATION_SUBCLASS  0x01\r
+#define EFI_FRONT_PAGE_SUBCLASS           0x02\r
+#define EFI_SINGLE_USE_SUBCLASS           0x03\r
+\r
+typedef struct _EFI_IFR_GUID_SUBCLASS {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode;\r
+  UINT16              SubClass;\r
+} EFI_IFR_GUID_SUBCLASS;\r
+\r
+#pragma pack()\r
+\r
+#endif\r
+\r
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/BdsBoot.c b/edk2/MdeModulePkg/Library/GenericBdsLib/BdsBoot.c
new file mode 100644 (file)
index 0000000..5071a67
--- /dev/null
@@ -0,0 +1,1912 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BdsBoot.c
+
+Abstract:
+
+  BDS Lib functions which relate with create or process the boot
+  option.
+
+
+**/
+
+#include "InternalBdsLib.h"
+
+BOOLEAN mEnumBootDevice = FALSE;
+
+//
+// This GUID is used for an EFI Variable that stores the front device pathes
+// for a partial device path that starts with the HD node.
+//
+EFI_GUID  mHdBootVariablePrivateGuid = { 0xfab7e9e1, 0x39dd, 0x4f2b, { 0x84, 0x8, 0xe2, 0xe, 0x90, 0x6c, 0xb6, 0xde } };
+
+
+
+/**
+  Boot the legacy system with the boot option
+
+  @param  Option                 The legacy boot option which have BBS device path
+
+  @retval EFI_UNSUPPORTED        There is no legacybios protocol, do not support
+                                 legacy boot.
+  @retval EFI_STATUS             Return the status of LegacyBios->LegacyBoot ().
+
+**/
+EFI_STATUS
+BdsLibDoLegacyBoot (
+  IN  BDS_COMMON_OPTION           *Option
+  )
+{
+  EFI_STATUS                Status;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+
+  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+  if (EFI_ERROR (Status)) {
+    //
+    // If no LegacyBios protocol we do not support legacy boot
+    //
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Notes: if we seperate the int 19, then we don't need to refresh BBS
+  //
+  BdsRefreshBbsTableForBoot (Option);
+
+  //
+  // Write boot to OS performance data to a file
+  //
+  PERF_CODE (
+    WriteBootToOsPerformanceData ();
+  );
+
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Legacy Boot: %S\n", Option->Description));
+  return LegacyBios->LegacyBoot (
+                      LegacyBios,
+                      (BBS_BBS_DEVICE_PATH *) Option->DevicePath,
+                      Option->LoadOptionsSize,
+                      Option->LoadOptions
+                      );
+}
+
+
+/**
+  Process the boot option follow the EFI 1.1 specification and
+  special treat the legacy boot option with BBS_DEVICE_PATH.
+
+  @param  Option                 The boot option need to be processed
+  @param  DevicePath             The device path which describe where to load the
+                                 boot image or the legcy BBS device path to boot
+                                 the legacy OS
+  @param  ExitDataSize           Returned directly from gBS->StartImage ()
+  @param  ExitData               Returned directly from gBS->StartImage ()
+
+  @retval EFI_SUCCESS            Status from gBS->StartImage ()
+  @retval EFI_NOT_FOUND          If the Device Path is not found in the system
+
+**/
+EFI_STATUS
+BdsLibBootViaBootOption (
+  IN  BDS_COMMON_OPTION             * Option,
+  IN  EFI_DEVICE_PATH_PROTOCOL      * DevicePath,
+  OUT UINTN                         *ExitDataSize,
+  OUT CHAR16                        **ExitData OPTIONAL
+  )
+{
+  EFI_STATUS                Status;
+  EFI_HANDLE                Handle;
+  EFI_HANDLE                ImageHandle;
+  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
+  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
+  EFI_DEVICE_PATH_PROTOCOL  *WorkingDevicePath;
+  EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
+  LIST_ENTRY                TempBootLists;
+
+  //
+  // Record the performance data for End of BDS
+  //
+  PERF_END (0, BDS_TOK, NULL, 0);
+
+  *ExitDataSize = 0;
+  *ExitData     = NULL;
+
+  //
+  // Notes: put EFI64 ROM Shadow Solution
+  //
+  EFI64_SHADOW_ALL_LEGACY_ROM ();
+
+  //
+  // Notes: this code can be remove after the s3 script table
+  // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or
+  // EFI_EVENT_SIGNAL_LEGACY_BOOT
+  //
+  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save);
+  if (!EFI_ERROR (Status)) {
+    AcpiS3Save->S3Save (AcpiS3Save, NULL);
+  }
+  //
+  // If it's Device Path that starts with a hard drive path, append it with the front part to compose a
+  // full device path
+  //
+  WorkingDevicePath = NULL;
+  if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
+      (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) {
+    WorkingDevicePath = BdsExpandPartitionPartialDevicePathToFull (
+                          (HARDDRIVE_DEVICE_PATH *)DevicePath
+                          );
+    if (WorkingDevicePath != NULL) {
+      DevicePath = WorkingDevicePath;
+    }
+  }
+  //
+  // Signal the EFI_EVENT_SIGNAL_READY_TO_BOOT event
+  //
+  EfiSignalEventReadyToBoot();
+  
+  
+  //
+  // Set Boot Current
+  //
+  gRT->SetVariable (
+        L"BootCurrent",
+        &gEfiGlobalVariableGuid,
+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+        sizeof (UINT16),
+        &Option->BootCurrent
+        );
+
+  if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&
+      (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)
+    ) {
+    //
+    // Check to see if we should legacy BOOT. If yes then do the legacy boot
+    //
+    return BdsLibDoLegacyBoot (Option);
+  }
+
+  //
+  // If the boot option point to Internal FV shell, make sure it is valid
+  //
+  Status = BdsLibUpdateFvFileDevicePath (&DevicePath, &gEfiShellFileGuid);
+  if (!EFI_ERROR(Status)) {
+    if (Option->DevicePath != NULL) {
+      SafeFreePool(Option->DevicePath);
+    }
+    Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));
+    CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
+    //
+    // Update the shell boot option
+    //
+    InitializeListHead (&TempBootLists);
+    BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder");
+  }
+
+  //
+  // Drop the TPL level from TPL_APPLICATION to TPL_APPLICATION
+  //
+  gBS->RestoreTPL (TPL_APPLICATION);
+
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting EFI way %S\n", Option->Description));
+
+  Status = gBS->LoadImage (
+                  TRUE,
+                  mBdsImageHandle,
+                  DevicePath,
+                  NULL,
+                  0,
+                  &ImageHandle
+                  );
+
+  //
+  // If we didn't find an image directly, we need to try as if it is a removable device boot opotion
+  // and load the image according to the default boot behavior for removable device.
+  //
+  if (EFI_ERROR (Status)) {
+    //
+    // check if there is a bootable removable media could be found in this device path ,
+    // and get the bootable media handle
+    //
+    Handle = BdsLibGetBootableHandle(DevicePath);
+    if (Handle == NULL) {
+       goto Done;
+    }
+    //
+    // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
+    //  machinename is ia32, ia64, x64, ...
+    //
+    FilePath = FileDevicePath (Handle, DEFAULT_REMOVABLE_FILE_NAME);
+    if (FilePath) {
+      Status = gBS->LoadImage (
+                      TRUE,
+                      mBdsImageHandle,
+                      FilePath,
+                      NULL,
+                      0,
+                      &ImageHandle
+                      );
+      if (EFI_ERROR (Status)) {
+        //
+        // The DevicePath failed, and it's not a valid
+        // removable media device.
+        //
+        goto Done;
+      }
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+    //
+    // It there is any error from the Boot attempt exit now.
+    //
+    goto Done;
+  }
+  //
+  // Provide the image with it's load options
+  //
+  Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
+  ASSERT_EFI_ERROR (Status);
+
+  if (Option->LoadOptionsSize != 0) {
+    ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
+    ImageInfo->LoadOptions      = Option->LoadOptions;
+  }
+  //
+  // Before calling the image, enable the Watchdog Timer for
+  // the 5 Minute period
+  //
+  gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
+
+  Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);
+  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status));
+
+  //
+  // Clear the Watchdog Timer after the image returns
+  //
+  gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
+
+Done:
+  //
+  // Clear Boot Current
+  //
+  gRT->SetVariable (
+        L"BootCurrent",
+        &gEfiGlobalVariableGuid,
+        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+        0,
+        &Option->BootCurrent
+        );
+
+  //
+  // Raise the TPL level back to TPL_APPLICATION
+  //
+  gBS->RaiseTPL (TPL_APPLICATION);
+
+  return Status;
+}
+
+
+/**
+  Expand a device path that starts with a hard drive media device path node to be a
+  full device path that includes the full hardware path to the device. We need
+  to do this so it can be booted. As an optimizaiton the front match (the part point
+  to the partition node. E.g. ACPI() /PCI()/ATA()/Partition() ) is saved in a variable
+  so a connect all is not required on every boot. All successful history device path
+  which point to partition node (the front part) will be saved.
+
+  @param  HardDriveDevicePath    EFI Device Path to boot, if it starts with a hard
+                                 drive media device path.
+ A Pointer to the full device path.
+  @retval NULL                   Cannot find a valid Hard Drive devic path
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+BdsExpandPartitionPartialDevicePathToFull (
+  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     BlockIoHandleCount;
+  EFI_HANDLE                *BlockIoBuffer;
+  EFI_DEVICE_PATH_PROTOCOL  *FullDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *BlockIoDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     Index;
+  UINTN                     InstanceNum;
+  EFI_DEVICE_PATH_PROTOCOL  *CachedDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
+  UINTN                     CachedDevicePathSize;
+  BOOLEAN                   DeviceExist;
+  BOOLEAN                   NeedAdjust;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  UINTN                     Size;
+
+  FullDevicePath = NULL;
+  //
+  // Check if there is prestore 'HDDP' variable.
+  // If exist, search the front path which point to partition node in the variable instants.
+  // If fail to find or 'HDDP' not exist, reconnect all and search in all system
+  //
+  CachedDevicePath = BdsLibGetVariableAndSize (
+                      L"HDDP",
+                      &mHdBootVariablePrivateGuid,
+                      &CachedDevicePathSize
+                      );
+  if (CachedDevicePath != NULL) {
+    TempNewDevicePath = CachedDevicePath;
+    DeviceExist = FALSE;
+    NeedAdjust = FALSE;
+    do {
+      //
+      // Check every instance of the variable
+      // First, check wheather the instance contain the partition node, which is needed for distinguishing  multi
+      // partial partition boot option. Second, check wheather the instance could be connected.
+      //
+      Instance  = GetNextDevicePathInstance (&TempNewDevicePath, &Size);
+      if (MatchPartitionDevicePathNode (Instance, HardDriveDevicePath)) {
+        //
+        // Connect the device path instance, the device path point to hard drive media device path node
+        // e.g. ACPI() /PCI()/ATA()/Partition()
+        //
+        Status = BdsLibConnectDevicePath (Instance);
+        if (!EFI_ERROR (Status)) {
+          DeviceExist = TRUE;
+          break;
+        }
+      }
+      //
+      // Come here means the first instance is not matched
+      //
+      NeedAdjust = TRUE;
+      SafeFreePool(Instance);
+    } while (TempNewDevicePath != NULL);
+
+    if (DeviceExist) {
+      //
+      // Find the matched device path.
+      // Append the file path infomration from the boot option and return the fully expanded device path.
+      //
+      DevicePath    = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
+      FullDevicePath = AppendDevicePath (Instance, DevicePath);
+
+      //
+      // Adjust the 'HDDP' instances sequense if the matched one is not first one.
+      //
+      if (NeedAdjust) {
+        //
+        // First delete the matched instance.
+        //
+        TempNewDevicePath = CachedDevicePath;
+        CachedDevicePath = BdsLibDelPartMatchInstance ( CachedDevicePath, Instance );
+        SafeFreePool (TempNewDevicePath);
+        //
+        // Second, append the remaining parth after the matched instance
+        //
+        TempNewDevicePath = CachedDevicePath;
+        CachedDevicePath = AppendDevicePathInstance ( Instance, CachedDevicePath );
+        SafeFreePool (TempNewDevicePath);
+        //
+        // Save the matching Device Path so we don't need to do a connect all next time
+        //
+        Status = gRT->SetVariable (
+                        L"HDDP",
+                        &mHdBootVariablePrivateGuid,
+                        EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                        GetDevicePathSize (CachedDevicePath),
+                        CachedDevicePath
+                        );
+      }
+      SafeFreePool(Instance);
+      gBS->FreePool (CachedDevicePath);
+      return FullDevicePath;
+    }
+  }
+
+  //
+  // If we get here we fail to find or 'HDDP' not exist, and now we need
+  // to seach all devices in the system for a matched partition
+  //
+  BdsLibConnectAllDriversToAllControllers ();
+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);
+  if (EFI_ERROR (Status) || BlockIoHandleCount == 0) {
+    //
+    // If there was an error or there are no device handles that support
+    // the BLOCK_IO Protocol, then return.
+    //
+    return NULL;
+  }
+  //
+  // Loop through all the device handles that support the BLOCK_IO Protocol
+  //
+  for (Index = 0; Index < BlockIoHandleCount; Index++) {
+
+    Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);
+    if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {
+      continue;
+    }
+
+    if (MatchPartitionDevicePathNode (BlockIoDevicePath, HardDriveDevicePath)) {
+      //
+      // Find the matched partition device path
+      //
+      DevicePath    = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
+      FullDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);
+
+      //
+      // Save the matched patition device path in 'HDDP' variable
+      //
+      if (CachedDevicePath != NULL) {
+        //
+        // Save the matched patition device path as first instance of 'HDDP' variable
+        //
+        if (BdsLibMatchDevicePaths (CachedDevicePath, BlockIoDevicePath)) {
+          TempNewDevicePath = CachedDevicePath;
+          CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath, BlockIoDevicePath);
+          SafeFreePool(TempNewDevicePath);
+
+          TempNewDevicePath = CachedDevicePath;
+          CachedDevicePath = AppendDevicePathInstance (BlockIoDevicePath, CachedDevicePath);
+          SafeFreePool(TempNewDevicePath);
+        } else {
+          TempNewDevicePath = CachedDevicePath;
+          CachedDevicePath = AppendDevicePathInstance (BlockIoDevicePath, CachedDevicePath);
+          SafeFreePool(TempNewDevicePath);
+        }
+        //
+        // Here limit the device path instance number to 12, which is max number for a system support 3 IDE controller
+        // If the user try to boot many OS in different HDs or partitions, in theary, the 'HDDP' variable maybe become larger and larger.
+        //
+        InstanceNum = 0;
+        TempNewDevicePath = CachedDevicePath;
+        while (!IsDevicePathEnd (TempNewDevicePath)) {
+          TempNewDevicePath = NextDevicePathNode (TempNewDevicePath);
+          //
+          // Parse one instance
+          //
+          while (!IsDevicePathEndType (TempNewDevicePath)) {
+            TempNewDevicePath = NextDevicePathNode (TempNewDevicePath);
+          }
+          InstanceNum++;
+          //
+          // If the CachedDevicePath variable contain too much instance, only remain 12 instances.
+          //
+          if (InstanceNum >= 12) {
+            SetDevicePathEndNode (TempNewDevicePath);
+            break;
+          }
+        }
+      } else {
+        CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath);
+      }
+
+      //
+      // Save the matching Device Path so we don't need to do a connect all next time
+      //
+      Status = gRT->SetVariable (
+                      L"HDDP",
+                      &mHdBootVariablePrivateGuid,
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                      GetDevicePathSize (CachedDevicePath),
+                      CachedDevicePath
+                      );
+
+      break;
+    }
+  }
+  gBS->FreePool (CachedDevicePath);
+  gBS->FreePool (BlockIoBuffer);
+  return FullDevicePath;
+}
+
+
+/**
+  Check whether there is a instance in BlockIoDevicePath, which contain multi device path
+  instances, has the same partition node with HardDriveDevicePath device path
+
+  @param  BlockIoDevicePath      Multi device path instances which need to check
+  @param  HardDriveDevicePath    A device path which starts with a hard drive media
+                                 device path.
+
+  @retval TRUE                   There is a matched device path instance FALSE
+                                 -There is no matched device path instance
+
+**/
+BOOLEAN
+MatchPartitionDevicePathNode (
+  IN  EFI_DEVICE_PATH_PROTOCOL   *BlockIoDevicePath,
+  IN  HARDDRIVE_DEVICE_PATH      *HardDriveDevicePath
+  )
+{
+  HARDDRIVE_DEVICE_PATH     *TmpHdPath;
+  HARDDRIVE_DEVICE_PATH     *TempPath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  BOOLEAN                   Match;
+  EFI_DEVICE_PATH_PROTOCOL  *BlockIoHdDevicePathNode;
+
+  if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) {
+    return FALSE;
+  }
+  //
+  // Make PreviousDevicePath == the device path node before the end node
+  //
+  DevicePath          = BlockIoDevicePath;
+  BlockIoHdDevicePathNode = NULL;
+
+  //
+  // find the partition device path node
+  //
+  while (!IsDevicePathEnd (DevicePath)) {
+    if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) &&
+        (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)
+        ) {
+      BlockIoHdDevicePathNode = DevicePath;
+      break;
+    }
+
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  if (BlockIoHdDevicePathNode == NULL) {
+    return FALSE;
+  }
+  //
+  // See if the harddrive device path in blockio matches the orig Hard Drive Node
+  //
+  TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode;
+  TempPath  = (HARDDRIVE_DEVICE_PATH *) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);
+  Match = FALSE;
+  //
+  // Check for the match
+  //
+  if ((TmpHdPath->MBRType == TempPath->MBRType) &&
+      (TmpHdPath->SignatureType == TempPath->SignatureType)) {
+    switch (TmpHdPath->SignatureType) {
+    case SIGNATURE_TYPE_GUID:
+      Match = CompareGuid ((EFI_GUID *)TmpHdPath->Signature, (EFI_GUID *)TempPath->Signature);
+      break;
+    case SIGNATURE_TYPE_MBR:
+      Match = (BOOLEAN)(*((UINT32 *)(&(TmpHdPath->Signature[0]))) == *(UINT32 *)(&(TempPath->Signature[0])));
+      break;
+    default:
+      Match = FALSE;
+      break;
+    }
+  }
+
+  return Match;
+}
+
+
+/**
+  Delete the boot option associated with the handle passed in
+
+  @param  Handle                 The handle which present the device path to create
+                                 boot option
+
+  @retval EFI_SUCCESS            Delete the boot option success
+  @retval EFI_NOT_FOUND          If the Device Path is not found in the system
+  @retval EFI_OUT_OF_RESOURCES   Lack of memory resource
+  @retval Other                  Error return value from SetVariable()
+
+**/
+EFI_STATUS
+BdsLibDeleteOptionFromHandle (
+  IN  EFI_HANDLE                 Handle
+  )
+{
+  UINT16                    *BootOrder;
+  UINT8                     *BootOptionVar;
+  UINTN                     BootOrderSize;
+  UINTN                     BootOptionSize;
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];
+  UINTN                     DevicePathSize;
+  UINTN                     OptionDevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
+  UINT8                     *TempPtr;
+
+  Status        = EFI_SUCCESS;
+  BootOrder     = NULL;
+  BootOrderSize = 0;
+
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  if (NULL == BootOrder) {
+    return EFI_NOT_FOUND;
+  }
+
+  DevicePath = DevicePathFromHandle (Handle);
+  if (DevicePath == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  DevicePathSize = GetDevicePathSize (DevicePath);
+
+  Index = 0;
+  while (Index < BootOrderSize / sizeof (UINT16)) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+    if (NULL == BootOptionVar) {
+      gBS->FreePool (BootOrder);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    TempPtr = BootOptionVar;
+    TempPtr += sizeof (UINT32) + sizeof (UINT16);
+    TempPtr += StrSize ((CHAR16 *) TempPtr);
+    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+    OptionDevicePathSize = GetDevicePathSize (OptionDevicePath);
+
+    //
+    // Check whether the device path match
+    //
+    if ((OptionDevicePathSize == DevicePathSize) &&
+        (CompareMem (DevicePath, OptionDevicePath, DevicePathSize) == 0)) {
+      BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
+      gBS->FreePool (BootOptionVar);
+      break;
+    }
+
+    gBS->FreePool (BootOptionVar);
+    Index++;
+  }
+
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  BootOrderSize,
+                  BootOrder
+                  );
+
+  gBS->FreePool (BootOrder);
+
+  return Status;
+}
+
+
+/**
+  Delete all invalid EFI boot options. The probable invalid boot option could
+  be Removable media or Network boot device.
+
+  VOID
+
+  @retval EFI_SUCCESS            Delete all invalid boot option success
+  @retval EFI_NOT_FOUND          Variable "BootOrder" is not found
+  @retval EFI_OUT_OF_RESOURCES   Lack of memory resource
+  @retval Other                  Error return value from SetVariable()
+
+**/
+EFI_STATUS
+BdsDeleteAllInvalidEfiBootOption (
+  VOID
+  )
+{
+  UINT16                    *BootOrder;
+  UINT8                     *BootOptionVar;
+  UINTN                     BootOrderSize;
+  UINTN                     BootOptionSize;
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  UINTN                     Index2;
+  UINT16                    BootOption[BOOT_OPTION_MAX_CHAR];
+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
+  UINT8                     *TempPtr;
+
+  Status        = EFI_SUCCESS;
+  BootOrder     = NULL;
+  BootOrderSize = 0;
+
+  BootOrder = BdsLibGetVariableAndSize (
+                L"BootOrder",
+                &gEfiGlobalVariableGuid,
+                &BootOrderSize
+                );
+  if (NULL == BootOrder) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = 0;
+  while (Index < BootOrderSize / sizeof (UINT16)) {
+    UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);
+    BootOptionVar = BdsLibGetVariableAndSize (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      &BootOptionSize
+                      );
+    if (NULL == BootOptionVar) {
+      gBS->FreePool (BootOrder);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    TempPtr = BootOptionVar;
+    TempPtr += sizeof (UINT32) + sizeof (UINT16);
+    TempPtr += StrSize ((CHAR16 *) TempPtr);
+    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+
+    //
+    // Skip legacy boot option (BBS boot device)
+    //
+    if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&
+        (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {
+      gBS->FreePool (BootOptionVar);
+      Index++;
+      continue;
+    }
+
+    if (!BdsLibIsValidEFIBootOptDevicePath (OptionDevicePath, FALSE)) {
+      //
+      // Delete this invalid boot option "Boot####"
+      //
+      Status = gRT->SetVariable (
+                      BootOption,
+                      &gEfiGlobalVariableGuid,
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                      0,
+                      NULL
+                      );
+      //
+      // Mark this boot option in boot order as deleted
+      //
+      BootOrder[Index] = 0xffff;
+    }
+
+    gBS->FreePool (BootOptionVar);
+    Index++;
+  }
+
+  //
+  // Adjust boot order array
+  //
+  Index2 = 0;
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
+    if (BootOrder[Index] != 0xffff) {
+      BootOrder[Index2] = BootOrder[Index];
+      Index2 ++;
+    }
+  }
+  Status = gRT->SetVariable (
+                  L"BootOrder",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  Index2 * sizeof (UINT16),
+                  BootOrder
+                  );
+
+  gBS->FreePool (BootOrder);
+
+  return Status;
+}
+
+
+/**
+  This function will enumerate all possible boot device in the system,
+  it will only excute once of every boot.
+
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+
+  @retval EFI_SUCCESS            Finished all the boot device enumerate and create
+                                 the boot option base on that boot device
+
+**/
+EFI_STATUS
+BdsLibEnumerateAllBootOption (
+  IN OUT LIST_ENTRY          *BdsBootOptionList
+  )
+{
+  EFI_STATUS                    Status;
+  UINT16                        FloppyNumber;
+  UINT16                        CdromNumber;
+  UINT16                        UsbNumber;
+  UINT16                        MiscNumber;
+  UINT16                        NonBlockNumber;
+  UINTN                         NumberBlockIoHandles;
+  EFI_HANDLE                    *BlockIoHandles;
+  EFI_BLOCK_IO_PROTOCOL         *BlkIo;
+  UINTN                         Index;
+  UINTN                         NumberSimpleNetworkHandles;
+  EFI_HANDLE                    *SimpleNetworkHandles;
+  UINTN                         FvHandleCount;
+  EFI_HANDLE                    *FvHandleBuffer;
+  EFI_FV_FILETYPE               Type;
+  UINTN                         Size;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINT32                        AuthenticationStatus;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;
+#else
+  EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
+#endif
+  EFI_DEVICE_PATH_PROTOCOL     *DevicePath;
+  UINTN                         DevicePathType;
+  CHAR16                        Buffer[40];
+  EFI_HANDLE                    *FileSystemHandles;
+  UINTN                         NumberFileSystemHandles;
+  BOOLEAN                       NeedDelete;
+  EFI_IMAGE_DOS_HEADER          DosHeader;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
+
+  FloppyNumber = 0;
+  CdromNumber = 0;
+  UsbNumber = 0;
+  MiscNumber = 0;
+  ZeroMem (Buffer, sizeof (Buffer));
+  //
+  // If the boot device enumerate happened, just get the boot
+  // device from the boot order variable
+  //
+  if (mEnumBootDevice) {
+    BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
+    return EFI_SUCCESS;
+  }
+  //
+  // Notes: this dirty code is to get the legacy boot option from the
+  // BBS table and create to variable as the EFI boot option, it should
+  // be removed after the CSM can provide legacy boot option directly
+  //
+  REFRESH_LEGACY_BOOT_OPTIONS;
+
+  //
+  // Delete invalid boot option
+  //
+  BdsDeleteAllInvalidEfiBootOption ();
+  //
+  // Parse removable media
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiBlockIoProtocolGuid,
+        NULL,
+        &NumberBlockIoHandles,
+        &BlockIoHandles
+        );
+  for (Index = 0; Index < NumberBlockIoHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    BlockIoHandles[Index],
+                    &gEfiBlockIoProtocolGuid,
+                    (VOID **) &BlkIo
+                    );
+    if (!EFI_ERROR (Status)) {
+      if (!BlkIo->Media->RemovableMedia) {
+        //
+        // skip the non-removable block devices
+        //
+        continue;
+      }
+    }
+    DevicePath  = DevicePathFromHandle (BlockIoHandles[Index]);
+    DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath);
+
+    switch (DevicePathType) {
+    case BDS_EFI_ACPI_FLOPPY_BOOT:
+      if (FloppyNumber == 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy");
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Floppy %d", FloppyNumber);
+      }
+      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+      FloppyNumber++;
+      break;
+
+    case BDS_EFI_MESSAGE_ATAPI_BOOT:
+      if (CdromNumber == 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM");
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI DVD/CDROM %d", CdromNumber);
+      }
+      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+      CdromNumber++;
+      break;
+
+    case BDS_EFI_MESSAGE_USB_DEVICE_BOOT:
+      if (UsbNumber == 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device");
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI USB Device %d", UsbNumber);
+      }
+      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+      UsbNumber++;
+      break;
+
+    case BDS_EFI_MESSAGE_SCSI_BOOT:
+      if (UsbNumber == 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device");
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI SCSI Device %d", UsbNumber);
+      }
+      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+      UsbNumber++;
+      break;
+
+    case BDS_EFI_MESSAGE_MISC_BOOT:
+      if (MiscNumber == 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device");
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Misc Device %d", MiscNumber);
+      }
+      BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer);
+      MiscNumber++;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  if (NumberBlockIoHandles) {
+    gBS->FreePool (BlockIoHandles);
+  }
+
+  //
+  // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here.
+  //
+  NonBlockNumber = 0;
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiSimpleFileSystemProtocolGuid,
+        NULL,
+        &NumberFileSystemHandles,
+        &FileSystemHandles
+        );
+  for (Index = 0; Index < NumberFileSystemHandles; Index++) {
+    Status = gBS->HandleProtocol (
+                    FileSystemHandles[Index],
+                    &gEfiBlockIoProtocolGuid,
+                    (VOID **) &BlkIo
+                    );
+     if (!EFI_ERROR (Status)) {
+      //
+      //  Skip if the file system handle supports a BlkIo protocol,
+      //
+      continue;
+    }
+
+    //
+    // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI
+    //  machinename is ia32, ia64, x64, ...
+    //
+    Hdr.Union = &HdrData;
+    NeedDelete = TRUE;
+    Status     = BdsLibGetImageHeader (
+                   FileSystemHandles[Index],
+                   DEFAULT_REMOVABLE_FILE_NAME,
+                   &DosHeader,
+                   Hdr
+                   );
+    if (!EFI_ERROR (Status) &&
+        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
+        Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+      NeedDelete = FALSE;
+    }
+
+    if (NeedDelete) {
+      //
+      // No such file or the file is not a EFI application, delete this boot option
+      //
+      BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]);
+    } else {
+      if (NonBlockNumber == 0) {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device");
+      } else {
+        UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Non-Block Boot Device %d", NonBlockNumber);
+      }
+      BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer);
+      NonBlockNumber++;
+    }
+  }
+
+  if (NumberFileSystemHandles) {
+    gBS->FreePool (FileSystemHandles);
+  }
+
+  //
+  // Parse Network Boot Device
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+        &gEfiSimpleNetworkProtocolGuid,
+        NULL,
+        &NumberSimpleNetworkHandles,
+        &SimpleNetworkHandles
+        );
+  for (Index = 0; Index < NumberSimpleNetworkHandles; Index++) {
+    if (Index == 0) {
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network");
+    } else {
+      UnicodeSPrint (Buffer, sizeof (Buffer), L"EFI Network %d", Index);
+    }
+    BdsLibBuildOptionFromHandle (SimpleNetworkHandles[Index], BdsBootOptionList, Buffer);
+  }
+
+  if (NumberSimpleNetworkHandles) {
+    gBS->FreePool (SimpleNetworkHandles);
+  }
+
+  //
+  // Check if we have on flash shell
+  //
+  gBS->LocateHandleBuffer (
+        ByProtocol,
+     #if (PI_SPECIFICATION_VERSION < 0x00010000)
+        &gEfiFirmwareVolumeProtocolGuid,
+     #else
+        &gEfiFirmwareVolume2ProtocolGuid,
+     #endif
+        NULL,
+        &FvHandleCount,
+        &FvHandleBuffer
+        );
+  for (Index = 0; Index < FvHandleCount; Index++) {
+    gBS->HandleProtocol (
+          FvHandleBuffer[Index],
+       #if (PI_SPECIFICATION_VERSION < 0x00010000)
+          &gEfiFirmwareVolumeProtocolGuid,
+       #else
+          &gEfiFirmwareVolume2ProtocolGuid,
+       #endif
+          (VOID **) &Fv
+          );
+
+    Status = Fv->ReadFile (
+                  Fv,
+                  &gEfiShellFileGuid,
+                  NULL,
+                  &Size,
+                  &Type,
+                  &Attributes,
+                  &AuthenticationStatus
+                  );
+    if (EFI_ERROR (Status)) {
+      //
+      // Skip if no shell file in the FV
+      //
+      continue;
+    }
+    //
+    // Build the shell boot option
+    //
+    BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);
+  }
+
+  if (FvHandleCount) {
+    gBS->FreePool (FvHandleBuffer);
+  }
+  //
+  // Make sure every boot only have one time
+  // boot device enumerate
+  //
+  BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");
+  mEnumBootDevice = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Build the boot option with the handle parsed in
+
+  @param  Handle                 The handle which present the device path to create
+                                 boot option
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+
+  @return VOID
+
+**/
+VOID
+BdsLibBuildOptionFromHandle (
+  IN  EFI_HANDLE                 Handle,
+  IN  LIST_ENTRY                 *BdsBootOptionList,
+  IN  CHAR16                     *String
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+  DevicePath  = DevicePathFromHandle (Handle);
+
+  //
+  // Create and register new boot option
+  //
+  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, String, L"BootOrder");
+}
+
+
+/**
+  Build the on flash shell boot option with the handle parsed in
+
+  @param  Handle                 The handle which present the device path to create
+                                 on flash shell boot option
+  @param  BdsBootOptionList      The header of the link list which indexed all
+                                 current boot options
+
+  @return None
+
+**/
+VOID
+BdsLibBuildOptionFromShell (
+  IN EFI_HANDLE                  Handle,
+  IN OUT LIST_ENTRY              *BdsBootOptionList
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;
+
+  DevicePath = DevicePathFromHandle (Handle);
+
+  //
+  // Build the shell device path
+  //
+  EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid);
+  //
+  //ShellNode.Header.Type     = MEDIA_DEVICE_PATH;
+  //ShellNode.Header.SubType  = MEDIA_FV_FILEPATH_DP;
+  //SetDevicePathNodeLength (&ShellNode.Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
+  //CopyMem (&ShellNode.NameGuid, &gEfiShellFileGuid, sizeof (EFI_GUID));
+  //
+  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);
+
+  //
+  // Create and register the shell boot option
+  //
+  BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"EFI Internal Shell", L"BootOrder");
+
+}
+
+
+/**
+  Boot from the EFI1.1 spec defined "BootNext" variable
+
+  None
+
+  @return None
+
+**/
+VOID
+BdsLibBootNext (
+  VOID
+  )
+{
+  UINT16            *BootNext;
+  UINTN             BootNextSize;
+  CHAR16            Buffer[20];
+  BDS_COMMON_OPTION *BootOption;
+  LIST_ENTRY        TempList;
+  UINTN             ExitDataSize;
+  CHAR16            *ExitData;
+
+  //
+  // Init the boot option name buffer and temp link list
+  //
+  InitializeListHead (&TempList);
+  ZeroMem (Buffer, sizeof (Buffer));
+
+  BootNext = BdsLibGetVariableAndSize (
+              L"BootNext",
+              &gEfiGlobalVariableGuid,
+              &BootNextSize
+              );
+
+  //
+  // Clear the boot next variable first
+  //
+  if (BootNext != NULL) {
+    gRT->SetVariable (
+          L"BootNext",
+          &gEfiGlobalVariableGuid,
+          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+          0,
+          BootNext
+          );
+
+    //
+    // Start to build the boot option and try to boot
+    //
+    UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);
+    BootOption = BdsLibVariableToOption (&TempList, Buffer);
+    BdsLibConnectDevicePath (BootOption->DevicePath);
+    BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);
+  }
+
+}
+
+
+
+/**
+  Return the bootable media handle.
+  First, check the device is connected
+  Second, check whether the device path point to a device which support SimpleFileSystemProtocol,
+  Third, detect the the default boot file in the Media, and return the removable Media handle.
+
+  @param  DevicePath             Device Path to a  bootable device
+
+  @retval NULL                   The device path points to an EFI bootable Media
+  @retval NULL                   The media on the DevicePath is not bootable
+
+**/
+EFI_HANDLE
+BdsLibGetBootableHandle (
+  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
+  EFI_HANDLE                      Handle;
+  EFI_BLOCK_IO_PROTOCOL           *BlockIo;
+  VOID                            *Buffer;
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
+  UINTN                           Size;
+  UINTN                           TempSize;
+  EFI_HANDLE                      ReturnHandle;
+  EFI_HANDLE                      *SimpleFileSystemHandles;
+
+  UINTN                           NumberSimpleFileSystemHandles;
+  UINTN                           Index;
+  EFI_IMAGE_DOS_HEADER            DosHeader;
+  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
+
+  UpdatedDevicePath = DevicePath;
+  //
+  // Check whether the device is connected
+  //
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &UpdatedDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    //
+    // Skip the case that the boot option point to a simple file protocol which does not consume block Io protocol,
+    //
+    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &UpdatedDevicePath, &Handle);
+    if (EFI_ERROR (Status)) {
+      //
+      // Fail to find the proper BlockIo and simple file protocol, maybe because device not present,  we need to connect it firstly
+      //
+      UpdatedDevicePath = DevicePath;
+      Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);
+      gBS->ConnectController (Handle, NULL, NULL, TRUE);
+    }
+  } else {
+    //
+    // Get BlockIo protocal and check removable attribute
+    //
+    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+    //
+    // Issue a dummy read to the device to check for media change.
+    // When the removable media is changed, any Block IO read/write will
+    // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is
+    // returned. After the Block IO protocol is reinstalled, subsequent
+    // Block IO read/write will success.
+    //
+    Buffer = AllocatePool (BlockIo->Media->BlockSize);
+    if (Buffer != NULL) {
+      BlockIo->ReadBlocks (
+               BlockIo,
+               BlockIo->Media->MediaId,
+               0,
+               BlockIo->Media->BlockSize,
+               Buffer
+               );
+      gBS->FreePool (Buffer);
+    }
+  }
+
+  //
+  // Detect the the default boot file from removable Media
+  //
+
+  //
+  // If fail to get bootable handle specified by a USB boot option, the BDS should try to find other bootable device in the same USB bus
+  // Try to locate the USB node device path first, if fail then use its previour PCI node to search
+  //
+  DupDevicePath = DuplicateDevicePath (DevicePath);
+  UpdatedDevicePath = DupDevicePath;
+  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle);
+  //
+  // if the resulting device path point to a usb node, and the usb node is a dummy node, should only let device path only point to the previous Pci node
+  // Acpi()/Pci()/Usb() --> Acpi()/Pci()
+  //
+  if ((DevicePathType (UpdatedDevicePath) == MESSAGING_DEVICE_PATH) &&
+      (DevicePathSubType (UpdatedDevicePath) == MSG_USB_DP)) {
+    //
+    // Remove the usb node, let the device path only point to PCI node
+    //
+    SetDevicePathEndNode (UpdatedDevicePath);
+    UpdatedDevicePath = DupDevicePath;
+  } else {
+    UpdatedDevicePath = DevicePath;
+  }
+
+  //
+  // Get the device path size of boot option
+  //
+  Size = GetDevicePathSize(UpdatedDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
+  ReturnHandle = NULL;
+  gBS->LocateHandleBuffer (
+      ByProtocol,
+      &gEfiSimpleFileSystemProtocolGuid,
+      NULL,
+      &NumberSimpleFileSystemHandles,
+      &SimpleFileSystemHandles
+      );
+  for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) {
+    //
+    // Get the device path size of SimpleFileSystem handle
+    //
+    TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]);
+    TempSize = GetDevicePathSize (TempDevicePath)- sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node
+    //
+    // Check whether the device path of boot option is part of the  SimpleFileSystem handle's device path
+    //
+    if (Size <= TempSize && CompareMem (TempDevicePath, UpdatedDevicePath, Size)==0) {
+      //
+      // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media
+      //  machinename is ia32, ia64, x64, ...
+      //
+      Hdr.Union = &HdrData;
+      Status = BdsLibGetImageHeader (
+                 SimpleFileSystemHandles[Index],
+                 DEFAULT_REMOVABLE_FILE_NAME,
+                 &DosHeader,
+                 Hdr
+                 );
+      if (!EFI_ERROR (Status) &&
+        EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) &&
+        Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+        ReturnHandle = SimpleFileSystemHandles[Index];
+        break;
+      }
+    }
+  }
+
+  if (DupDevicePath != NULL) {
+    SafeFreePool(DupDevicePath);
+  }
+  if (SimpleFileSystemHandles !=NULL ) {
+    gBS->FreePool (SimpleFileSystemHandles);
+  }
+
+  return ReturnHandle;
+}
+
+
+
+
+/**
+  Check to see if the network cable is plugged in. If the DevicePath is not
+  connected it will be connected.
+
+  @param  DevicePath             Device Path to check
+
+  @retval TRUE                   DevicePath points to an Network that is connected
+  @retval FALSE                  DevicePath does not point to a bootable network
+
+**/
+BOOLEAN
+BdsLibNetworkBootWithMediaPresent (
+  IN  EFI_DEVICE_PATH_PROTOCOL      *DevicePath
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_DEVICE_PATH_PROTOCOL        *UpdatedDevicePath;
+  EFI_HANDLE                      Handle;
+  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;
+  BOOLEAN                         MediaPresent;
+
+  MediaPresent = FALSE;
+
+  UpdatedDevicePath = DevicePath;
+  Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    //
+    // Device not present so see if we need to connect it
+    //
+    Status = BdsLibConnectDevicePath (DevicePath);
+    if (!EFI_ERROR (Status)) {
+      //
+      // This one should work after we did the connect
+      //
+      Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle);
+    }
+  }
+
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp);
+    if (!EFI_ERROR (Status)) {
+      if (Snp->Mode->MediaPresentSupported) {
+        if (Snp->Mode->State == EfiSimpleNetworkInitialized) {
+          //
+          // In case some one else is using the SNP check to see if it's connected
+          //
+          MediaPresent = Snp->Mode->MediaPresent;
+        } else {
+          //
+          // No one is using SNP so we need to Start and Initialize so
+          // MediaPresent will be valid.
+          //
+          Status = Snp->Start (Snp);
+          if (!EFI_ERROR (Status)) {
+            Status = Snp->Initialize (Snp, 0, 0);
+            if (!EFI_ERROR (Status)) {
+              MediaPresent = Snp->Mode->MediaPresent;
+              Snp->Shutdown (Snp);
+            }
+            Snp->Stop (Snp);
+          }
+        }
+      } else {
+        MediaPresent = TRUE;
+      }
+    }
+  }
+
+  return MediaPresent;
+}
+
+
+
+/**
+  For a bootable Device path, return its boot type
+
+  @param  DevicePath             The bootable device Path to check
+
+  @return UINT32 Boot type :
+  @return //
+  @return // If the device path contains any media deviec path node, it is media boot type
+  @return // For the floppy node, handle it as media node
+  @return //
+  @return BDS_EFI_MEDIA_HD_BOOT
+  @return BDS_EFI_MEDIA_CDROM_BOOT
+  @return BDS_EFI_ACPI_FLOPPY_BOOT
+  @return //
+  @return // If the device path not contains any media deviec path node,  and
+  @return // its last device path node point to a message device path node, it is
+  @return // a message boot type
+  @return //
+  @return BDS_EFI_MESSAGE_ATAPI_BOOT
+  @return BDS_EFI_MESSAGE_SCSI_BOOT
+  @return BDS_EFI_MESSAGE_USB_DEVICE_BOOT
+  @return BDS_EFI_MESSAGE_MISC_BOOT
+  @return //
+  @return // Legacy boot type
+  @return //
+  @return BDS_LEGACY_BBS_BOOT
+  @return //
+  @return // If a EFI Removable BlockIO device path not point to a media and message devie,
+  @return // it is unsupported
+  @return //
+  @return BDS_EFI_UNSUPPORT
+
+**/
+UINT32
+BdsGetBootTypeFromDevicePath (
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
+  )
+{
+  ACPI_HID_DEVICE_PATH          *Acpi;
+  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
+
+
+  if (NULL == DevicePath) {
+    return BDS_EFI_UNSUPPORT;
+  }
+
+  TempDevicePath = DevicePath;
+
+  while (!IsDevicePathEndType (TempDevicePath)) {
+    switch (DevicePathType (TempDevicePath)) {
+      case BBS_DEVICE_PATH:
+         return BDS_LEGACY_BBS_BOOT;
+      case MEDIA_DEVICE_PATH:
+        if (DevicePathSubType (TempDevicePath) == MEDIA_HARDDRIVE_DP) {
+          return BDS_EFI_MEDIA_HD_BOOT;
+        } else if (DevicePathSubType (TempDevicePath) == MEDIA_CDROM_DP) {
+          return BDS_EFI_MEDIA_CDROM_BOOT;
+        }
+        break;
+      case ACPI_DEVICE_PATH:
+        Acpi = (ACPI_HID_DEVICE_PATH *) TempDevicePath;
+        if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {
+          return BDS_EFI_ACPI_FLOPPY_BOOT;
+        }
+        break;
+      case MESSAGING_DEVICE_PATH:
+        //
+        // if the device path not only point to driver device, it is not a messaging device path.
+        //
+        LastDeviceNode = NextDevicePathNode (TempDevicePath);
+        if (!IsDevicePathEndType (LastDeviceNode)) {
+          break;
+        }
+
+        if (DevicePathSubType(TempDevicePath) == MSG_ATAPI_DP) {
+          return BDS_EFI_MESSAGE_ATAPI_BOOT;
+        } else if (DevicePathSubType(TempDevicePath) == MSG_USB_DP) {
+          return BDS_EFI_MESSAGE_USB_DEVICE_BOOT;
+        } else if (DevicePathSubType(TempDevicePath) == MSG_SCSI_DP) {
+          return BDS_EFI_MESSAGE_SCSI_BOOT;
+        }
+        return BDS_EFI_MESSAGE_MISC_BOOT;
+      default:
+        break;
+    }
+    TempDevicePath = NextDevicePathNode (TempDevicePath);
+  }
+
+  return BDS_EFI_UNSUPPORT;
+}
+
+
+/**
+  Check whether the Device path in a boot option point to a valide bootable device,
+  And if CheckMedia is true, check the device is ready to boot now.
+
+  DevPath -- the Device path in a boot option
+  CheckMedia -- if true, check the device is ready to boot now.
+
+  @return TRUE      -- the Device path  is valide
+  @return FALSE   -- the Device path  is invalide .
+
+**/
+BOOLEAN
+BdsLibIsValidEFIBootOptDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath,
+  IN BOOLEAN                      CheckMedia
+  )
+{
+  EFI_STATUS                Status;
+  EFI_HANDLE                Handle;
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *LastDeviceNode;
+  EFI_BLOCK_IO_PROTOCOL     *BlockIo;
+
+  TempDevicePath = DevPath;
+  LastDeviceNode = DevPath;
+  //
+  // Check if it's a valid boot option for network boot device
+  // Only check if there is SimpleNetworkProtocol installed. If yes, that means
+  // there is the network card there.
+  //
+  Status = gBS->LocateDevicePath (
+                  &gEfiSimpleNetworkProtocolGuid,
+                  &TempDevicePath,
+                  &Handle
+                  );
+  if (EFI_ERROR (Status)) {
+    //
+    // Device not present so see if we need to connect it
+    //
+    TempDevicePath = DevPath;
+    BdsLibConnectDevicePath (TempDevicePath);
+    Status = gBS->LocateDevicePath (
+                    &gEfiSimpleNetworkProtocolGuid,
+                    &TempDevicePath,
+                    &Handle
+                    );
+  }
+  if (!EFI_ERROR (Status)) {
+    if (CheckMedia) {
+      //
+      // Test if it is ready to boot now
+      //
+      if (BdsLibNetworkBootWithMediaPresent(DevPath)) {
+        return TRUE;
+      }
+    } else {
+      return TRUE;
+    }
+  }
+
+  //
+  // If the boot option point to a file, it is a valid EFI boot option,
+  // and assume it is ready to boot now
+  //
+  while (!EfiIsDevicePathEnd (TempDevicePath)) {
+     LastDeviceNode = TempDevicePath;
+     TempDevicePath = EfiNextDevicePathNode (TempDevicePath);
+  }
+  if ((DevicePathType (LastDeviceNode) == MEDIA_DEVICE_PATH) &&
+    (DevicePathSubType (LastDeviceNode) == MEDIA_FILEPATH_DP)) {
+    return TRUE;
+  }
+
+  //
+  // If the boot option point to a internal Shell, it is a valid EFI boot option,
+  // and assume it is ready to boot now
+  //
+  if (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL) {
+     return TRUE;
+  }
+
+  //
+  // If the boot option point to a blockIO device, no matter whether or not it is a removeable device, it is a valid EFI boot option
+  //
+  TempDevicePath = DevPath;
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);
+  if (EFI_ERROR (Status)) {
+    //
+    // Device not present so see if we need to connect it
+    //
+    Status = BdsLibConnectDevicePath (DevPath);
+    if (!EFI_ERROR (Status)) {
+      //
+      // Try again to get the Block Io protocol after we did the connect
+      //
+      TempDevicePath = DevPath;
+      Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle);
+    }
+  }
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+    if (!EFI_ERROR (Status)) {
+      if (CheckMedia) {
+        //
+        // Test if it is ready to boot now
+        //
+        if (BdsLibGetBootableHandle (DevPath) != NULL) {
+          return TRUE;
+        }
+      } else {
+        return TRUE;
+      }
+    }
+  } else {
+    //
+    // if the boot option point to a simple file protocol which does not consume block Io protocol, it is also a valid EFI boot option,
+    //
+    Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &TempDevicePath, &Handle);
+    if (!EFI_ERROR (Status)) {
+      if (CheckMedia) {
+        //
+        // Test if it is ready to boot now
+        //
+        if (BdsLibGetBootableHandle (DevPath) != NULL) {
+          return TRUE;
+        }
+      } else {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+
+/**
+  According to a file guild, check a Fv file device path is valid. If it is invalid,
+  try to return the valid device path.
+  FV address maybe changes for memory layout adjust from time to time, use this funciton
+  could promise the Fv file device path is right.
+
+  @param  DevicePath             on input, the Fv file device path need to check on
+                                 output, the updated valid Fv file device path
+  @param  FileGuid               the Fv file guild
+
+  @retval EFI_INVALID_PARAMETER  the input DevicePath or FileGuid is invalid
+                                 parameter
+  @retval EFI_UNSUPPORTED        the input DevicePath does not contain Fv file
+                                 guild at all
+  @retval EFI_ALREADY_STARTED    the input DevicePath has pointed to Fv file, it is
+                                 valid
+  @retval EFI_SUCCESS            has successfully updated the invalid DevicePath,
+                                 and return the updated device path in DevicePath
+
+**/
+EFI_STATUS
+EFIAPI
+BdsLibUpdateFvFileDevicePath (
+  IN  OUT EFI_DEVICE_PATH_PROTOCOL      ** DevicePath,
+  IN  EFI_GUID                          *FileGuid
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL      *LastDeviceNode;
+  EFI_STATUS                    Status;
+  EFI_GUID                      *GuidPoint;
+  UINTN                         Index;
+  UINTN                         FvHandleCount;
+  EFI_HANDLE                    *FvHandleBuffer;
+  EFI_FV_FILETYPE               Type;
+  UINTN                         Size;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  UINT32                        AuthenticationStatus;
+  BOOLEAN                       FindFvFile;
+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+  EFI_FIRMWARE_VOLUME_PROTOCOL  *Fv;
+#else
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;
+  EFI_HANDLE                    FoundFvHandle;
+  EFI_DEVICE_PATH_PROTOCOL      *NewDevicePath;
+
+  if ((DevicePath == NULL) || (*DevicePath == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (FileGuid == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Check whether the device path point to the default the input Fv file
+  //
+  TempDevicePath = *DevicePath;
+  LastDeviceNode = TempDevicePath;
+  while (!EfiIsDevicePathEnd (TempDevicePath)) {
+     LastDeviceNode = TempDevicePath;
+     TempDevicePath = EfiNextDevicePathNode (TempDevicePath);
+  }
+  GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+                (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+                );
+  if (GuidPoint == NULL) {
+    //
+    // if this option does not points to a Fv file, just return EFI_UNSUPPORTED
+    //
+    return EFI_UNSUPPORTED;
+  }
+  if (!CompareGuid (GuidPoint, FileGuid)) {
+    //
+    // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check whether the input Fv file device path is valid
+  //
+  TempDevicePath = *DevicePath;
+  FoundFvHandle = NULL;
+  Status = gBS->LocateDevicePath (
+                #if (PI_SPECIFICATION_VERSION < 0x00010000)
+                  &gEfiFirmwareVolumeProtocolGuid,
+                #else
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                #endif
+                  &TempDevicePath,
+                  &FoundFvHandle
+                  );
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (
+                    FoundFvHandle,
+                  #if (PI_SPECIFICATION_VERSION < 0x00010000)
+                    &gEfiFirmwareVolumeProtocolGuid,
+                  #else
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                  #endif
+                    (VOID **) &Fv
+                    );
+    if (!EFI_ERROR (Status)) {
+      //
+      // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there
+      //
+      Status = Fv->ReadFile (
+                    Fv,
+                    FileGuid,
+                    NULL,
+                    &Size,
+                    &Type,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+      if (!EFI_ERROR (Status)) {
+        return EFI_ALREADY_STARTED;
+      }
+    }
+  }
+
+  //
+  // Look for the input wanted FV file in current FV
+  // First, try to look for in Bds own FV. Bds and input wanted FV file usually are in the same FV
+  //
+  FindFvFile = FALSE;
+  FoundFvHandle = NULL;
+  Status = gBS->HandleProtocol (
+             mBdsImageHandle,
+             &gEfiLoadedImageProtocolGuid,
+             (VOID **) &LoadedImage
+             );
+  if (!EFI_ERROR (Status)) {
+    Status = gBS->HandleProtocol (
+                    LoadedImage->DeviceHandle,
+                  #if (PI_SPECIFICATION_VERSION < 0x00010000)
+                    &gEfiFirmwareVolumeProtocolGuid,
+                  #else
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                  #endif
+                    (VOID **) &Fv
+                    );
+    if (!EFI_ERROR (Status)) {
+      Status = Fv->ReadFile (
+                    Fv,
+                    FileGuid,
+                    NULL,
+                    &Size,
+                    &Type,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+      if (!EFI_ERROR (Status)) {
+        FindFvFile = TRUE;
+        FoundFvHandle = LoadedImage->DeviceHandle;
+      }
+    }
+  }
+  //
+  // Second, if fail to find, try to enumerate all FV
+  //
+  if (!FindFvFile) {
+    gBS->LocateHandleBuffer (
+          ByProtocol,
+       #if (PI_SPECIFICATION_VERSION < 0x00010000)
+          &gEfiFirmwareVolumeProtocolGuid,
+       #else
+          &gEfiFirmwareVolume2ProtocolGuid,
+       #endif
+          NULL,
+          &FvHandleCount,
+          &FvHandleBuffer
+          );
+    for (Index = 0; Index < FvHandleCount; Index++) {
+      gBS->HandleProtocol (
+            FvHandleBuffer[Index],
+         #if (PI_SPECIFICATION_VERSION < 0x00010000)
+            &gEfiFirmwareVolumeProtocolGuid,
+         #else
+            &gEfiFirmwareVolume2ProtocolGuid,
+         #endif
+            (VOID **) &Fv
+            );
+
+      Status = Fv->ReadFile (
+                    Fv,
+                    FileGuid,
+                    NULL,
+                    &Size,
+                    &Type,
+                    &Attributes,
+                    &AuthenticationStatus
+                    );
+      if (EFI_ERROR (Status)) {
+        //
+        // Skip if input Fv file not in the FV
+        //
+        continue;
+      }
+      FindFvFile = TRUE;
+      FoundFvHandle = FvHandleBuffer[Index];
+      break;
+    }
+  }
+
+  if (FindFvFile) {
+    //
+    // Build the shell device path
+    //
+    NewDevicePath = DevicePathFromHandle (FoundFvHandle);
+    EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);
+    NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);
+    *DevicePath = NewDevicePath;
+    return EFI_SUCCESS;
+  }
+  return EFI_NOT_FOUND;
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/BdsConnect.c b/edk2/MdeModulePkg/Library/GenericBdsLib/BdsConnect.c
new file mode 100644 (file)
index 0000000..6e9068b
--- /dev/null
@@ -0,0 +1,424 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BdsConnect.c
+
+Abstract:
+
+  BDS Lib functions which relate with connect the device
+
+
+**/
+
+#include "InternalBdsLib.h"
+
+
+/**
+  This function will connect all the system driver to controller
+  first, and then special connect the default console, this make
+  sure all the system controller avialbe and the platform default
+  console connected.
+
+  None
+
+  @return None
+
+**/
+VOID
+BdsLibConnectAll (
+  VOID
+  )
+{
+  //
+  // Connect the platform console first
+  //
+  BdsLibConnectAllDefaultConsoles ();
+
+  //
+  // Generic way to connect all the drivers
+  //
+  BdsLibConnectAllDriversToAllControllers ();
+
+  //
+  // Here we have the assumption that we have already had
+  // platform default console
+  //
+  BdsLibConnectAllDefaultConsoles ();
+}
+
+
+/**
+  This function will connect all the system drivers to all controllers
+  first, and then connect all the console devices the system current
+  have. After this we should get all the device work and console avariable
+  if the system have console device.
+
+  None
+
+  @return None
+
+**/
+VOID
+BdsLibGenericConnectAll (
+  VOID
+  )
+{
+  //
+  // Most generic way to connect all the drivers
+  //
+  BdsLibConnectAllDriversToAllControllers ();
+  BdsLibConnectAllConsoles ();
+}
+
+
+/**
+  This function will create all handles associate with every device
+  path node. If the handle associate with one device path node can not
+  be created success, then still give one chance to do the dispatch,
+  which load the missing drivers if possible.
+
+  @param  DevicePathToConnect   The device path which will be connected, it can be
+                                a multi-instance device path
+
+  @retval EFI_SUCCESS           All handles associate with every device path  node
+                                have been created
+  @retval EFI_OUT_OF_RESOURCES  There is no resource to create new handles
+  @retval EFI_NOT_FOUND         Create the handle associate with one device  path
+                                node failed
+
+**/
+EFI_STATUS
+BdsLibConnectDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  EFI_HANDLE                Handle;
+  EFI_HANDLE                PreviousHandle;
+  UINTN                     Size;
+
+  if (DevicePathToConnect == NULL) {
+    return EFI_SUCCESS;
+  }
+
+  DevicePath        = DuplicateDevicePath (DevicePathToConnect);
+  CopyOfDevicePath  = DevicePath;
+  if (DevicePath == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  do {
+    //
+    // The outer loop handles multi instance device paths.
+    // Only console variables contain multiple instance device paths.
+    //
+    // After this call DevicePath points to the next Instance
+    //
+    Instance  = GetNextDevicePathInstance (&DevicePath, &Size);
+    Next      = Instance;
+    while (!IsDevicePathEndType (Next)) {
+      Next = NextDevicePathNode (Next);
+    }
+
+    SetDevicePathEndNode (Next);
+
+    //
+    // Start the real work of connect with RemainingDevicePath
+    //
+    PreviousHandle = NULL;
+    do {
+      //
+      // Find the handle that best matches the Device Path. If it is only a
+      // partial match the remaining part of the device path is returned in
+      // RemainingDevicePath.
+      //
+      RemainingDevicePath = Instance;
+      Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
+
+      if (!EFI_ERROR (Status)) {
+        if (Handle == PreviousHandle) {
+          //
+          // If no forward progress is made try invoking the Dispatcher.
+          // A new FV may have been added to the system an new drivers
+          // may now be found.
+          // Status == EFI_SUCCESS means a driver was dispatched
+          // Status == EFI_NOT_FOUND means no new drivers were dispatched
+          //
+          Status = gDS->Dispatch ();
+        }
+
+        if (!EFI_ERROR (Status)) {
+          PreviousHandle = Handle;
+          //
+          // Connect all drivers that apply to Handle and RemainingDevicePath,
+          // the Recursive flag is FALSE so only one level will be expanded.
+          //
+          // Do not check the connect status here, if the connect controller fail,
+          // then still give the chance to do dispatch, because partial
+          // RemainingDevicepath may be in the new FV
+          //
+          // 1. If the connect fail, RemainingDevicepath and handle will not
+          //    change, so next time will do the dispatch, then dispatch's status
+          //    will take effect
+          // 2. If the connect success, the RemainingDevicepath and handle will
+          //    change, then avoid the dispatch, we have chance to continue the
+          //    next connection
+          //
+          gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
+        }
+      }
+      //
+      // Loop until RemainingDevicePath is an empty device path
+      //
+    } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
+
+  } while (DevicePath != NULL);
+
+  if (CopyOfDevicePath != NULL) {
+    gBS->FreePool (CopyOfDevicePath);
+  }
+  //
+  // All handle with DevicePath exists in the handle database
+  //
+  return Status;
+}
+
+
+/**
+  This function will connect all current system handles recursively. The
+  connection will finish until every handle's child handle created if it have.
+
+  None
+
+  @retval EFI_SUCCESS           All handles and it's child handle have been
+                                connected
+  @retval EFI_STATUS            Return the status of gBS->LocateHandleBuffer().
+
+**/
+EFI_STATUS
+BdsLibConnectAllEfi (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       HandleCount;
+  EFI_HANDLE  *HandleBuffer;
+  UINTN       Index;
+
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+  }
+
+  gBS->FreePool (HandleBuffer);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function will disconnect all current system handles. The disconnection
+  will finish until every handle have been disconnected.
+
+  None
+
+  @retval EFI_SUCCESS           All handles have been disconnected
+  @retval EFI_STATUS            Return the status of gBS->LocateHandleBuffer().
+
+**/
+EFI_STATUS
+BdsLibDisconnectAllEfi (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       HandleCount;
+  EFI_HANDLE  *HandleBuffer;
+  UINTN       Index;
+
+  //
+  // Disconnect all
+  //
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
+  }
+
+  gBS->FreePool (HandleBuffer);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Connects all drivers to all controllers.
+  This function make sure all the current system driver will manage
+  the correspoinding controllers if have. And at the same time, make
+  sure all the system controllers have driver to manage it if have.
+
+  None
+
+  @return None
+
+**/
+VOID
+BdsLibConnectAllDriversToAllControllers (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  do {
+    //
+    // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
+    //
+    BdsLibConnectAllEfi ();
+
+    //
+    // Check to see if it's possible to dispatch an more DXE drivers.
+    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
+    // If anything is Dispatched Status == EFI_SUCCESS and we will try
+    // the connect again.
+    //
+    Status = gDS->Dispatch ();
+
+  } while (!EFI_ERROR (Status));
+
+}
+
+
+/**
+  Connect the specific Usb device which match the short form device path,
+  and whose bus is determined by Host Controller (Uhci or Ehci)
+
+  @param  HostControllerPI      Uhci (0x00) or Ehci (0x20) or Both uhci and ehci
+                                (0xFF)
+  @param  RemainingDevicePath   a short-form device path that starts with the first
+                                element  being a USB WWID or a USB Class device
+                                path
+
+  @return EFI_INVALID_PARAMETER
+  @return EFI_SUCCESS
+  @return EFI_NOT_FOUND
+
+**/
+EFI_STATUS
+BdsLibConnectUsbDevByShortFormDP(
+  IN CHAR8                      HostControllerPI,
+  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_HANDLE                            *HandleArray;
+  UINTN                                 HandleArrayCount;
+  UINTN                                 Index;
+  EFI_PCI_IO_PROTOCOL                   *PciIo;
+  UINT8                                 Class[3];
+  BOOLEAN                               AtLeastOneConnected;
+
+  //
+  // Check the passed in parameters
+  //
+  if (RemainingDevicePath == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) ||
+      ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+      && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP)
+#endif
+      )) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (HostControllerPI != 0xFF &&
+      HostControllerPI != 0x00 &&
+      HostControllerPI != 0x20) {
+    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,
+                  &HandleArrayCount,
+                  &HandleArray
+                  );
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < HandleArrayCount; Index++) {
+      Status = gBS->HandleProtocol (
+                      HandleArray[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)) {
+          if ((PCI_CLASS_SERIAL == Class[2]) &&
+              (PCI_CLASS_SERIAL_USB == Class[1])) {
+            if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) {
+              Status = gBS->ConnectController (
+                              HandleArray[Index],
+                              NULL,
+                              RemainingDevicePath,
+                              FALSE
+                              );
+              if (!EFI_ERROR(Status)) {
+                AtLeastOneConnected = TRUE;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    if (AtLeastOneConnected) {
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c b/edk2/MdeModulePkg/Library/GenericBdsLib/BdsConsole.c
new file mode 100644 (file)
index 0000000..db28b68
--- /dev/null
@@ -0,0 +1,399 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BdsConsole.c
+
+Abstract:
+
+  BDS Lib functions which contain all the code to connect console device
+
+
+**/
+
+#include "InternalBdsLib.h"
+//@MT:#include "EfiPrintLib.h"
+
+BOOLEAN
+IsNvNeed (
+  IN CHAR16 *ConVarName
+  )
+{
+  CHAR16 *Ptr;
+
+  Ptr = ConVarName;
+
+  //
+  // If the variable includes "Dev" at last, we consider
+  // it does not support NV attribute.
+  //
+  while (*Ptr) {
+    Ptr++;
+  }
+
+  if ((*(Ptr-3) == 'D') && (*(Ptr-2) == 'e') && (*(Ptr-1) == 'v')) {
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
+
+
+/**
+  This function update console variable based on ConVarName, it can
+  add or remove one specific console device path from the variable
+
+  @param  ConVarName               Console related variable name, ConIn, ConOut,
+                                   ErrOut.
+  @param  CustomizedConDevicePath  The console device path which will be added to
+                                   the console variable ConVarName, this parameter
+                                   can not be multi-instance.
+  @param  ExclusiveDevicePath      The console device path which will be removed
+                                   from the console variable ConVarName, this
+                                   parameter can not be multi-instance.
+
+  @retval EFI_UNSUPPORTED          Add or remove the same device path.
+  @retval EFI_SUCCESS              Success add or remove the device path from  the
+                                   console variable.
+
+**/
+EFI_STATUS
+BdsLibUpdateConsoleVariable (
+  IN  CHAR16                    *ConVarName,
+  IN  EFI_DEVICE_PATH_PROTOCOL  *CustomizedConDevicePath,
+  IN  EFI_DEVICE_PATH_PROTOCOL  *ExclusiveDevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *VarConsole;
+  UINTN                     DevicePathSize;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
+  UINT32                    Attributes;
+
+  VarConsole      = NULL;
+  DevicePathSize  = 0;
+
+  //
+  // Notes: check the device path point, here should check
+  // with compare memory
+  //
+  if (CustomizedConDevicePath == ExclusiveDevicePath) {
+    return EFI_UNSUPPORTED;
+  }
+  //
+  // Delete the ExclusiveDevicePath from current default console
+  //
+  VarConsole = BdsLibGetVariableAndSize (
+                ConVarName,
+                &gEfiGlobalVariableGuid,
+                &DevicePathSize
+                );
+
+  //
+  // Initialize NewDevicePath
+  //
+  NewDevicePath  = VarConsole;
+
+  //
+  // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
+  // In the end, NewDevicePath is the final device path.
+  //
+  if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
+      NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
+  }
+  //
+  // Try to append customized device path to NewDevicePath.
+  //
+  if (CustomizedConDevicePath != NULL) {
+    if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
+      //
+      // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
+      //
+      NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
+      //
+      // In the first check, the default console variable will be _ModuleEntryPoint,
+      // just append current customized device path
+      //
+      TempNewDevicePath = NewDevicePath;
+      NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
+      SafeFreePool(TempNewDevicePath);
+    }
+  }
+
+  //
+  // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
+  //
+  if (IsNvNeed(ConVarName)) {
+    //
+    // ConVarName has NV attribute.
+    //
+    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
+  } else {
+    //
+    // ConVarName does not have NV attribute.
+    //
+    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+  }
+
+  //
+  // Finally, Update the variable of the default console by NewDevicePath
+  //
+  gRT->SetVariable (
+        ConVarName,
+        &gEfiGlobalVariableGuid,
+        Attributes,
+        GetDevicePathSize (NewDevicePath),
+        NewDevicePath
+        );
+
+  if (VarConsole == NewDevicePath) {
+    SafeFreePool(VarConsole);
+  } else {
+    SafeFreePool(VarConsole);
+    SafeFreePool(NewDevicePath);
+  }
+
+  return EFI_SUCCESS;
+
+}
+
+
+/**
+  Connect the console device base on the variable ConVarName, if
+  device path of the ConVarName is multi-instance device path, if
+  anyone of the instances is connected success, then this function
+  will return success.
+
+  @param  ConVarName               Console related variable name, ConIn, ConOut,
+                                   ErrOut.
+
+  @retval EFI_NOT_FOUND            There is not any console devices connected
+                                   success
+  @retval EFI_SUCCESS              Success connect any one instance of the console
+                                   device path base on the variable ConVarName.
+
+**/
+EFI_STATUS
+BdsLibConnectConsoleVariable (
+  IN  CHAR16                 *ConVarName
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
+  UINTN                     VariableSize;
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *Next;
+  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
+  UINTN                     Size;
+  BOOLEAN                   DeviceExist;
+
+  Status      = EFI_SUCCESS;
+  DeviceExist = FALSE;
+
+  //
+  // Check if the console variable exist
+  //
+  StartDevicePath = BdsLibGetVariableAndSize (
+                      ConVarName,
+                      &gEfiGlobalVariableGuid,
+                      &VariableSize
+                      );
+  if (StartDevicePath == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  CopyOfDevicePath = StartDevicePath;
+  do {
+    //
+    // Check every instance of the console variable
+    //
+    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
+    Next      = Instance;
+    while (!IsDevicePathEndType (Next)) {
+      Next = NextDevicePathNode (Next);
+    }
+
+    SetDevicePathEndNode (Next);
+    //
+    // Check USB1.1 console
+    //
+    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
+       ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+       || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
+#endif
+       )) {
+      //
+      // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus
+      //
+      Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);
+      if (!EFI_ERROR (Status)) {
+        DeviceExist = TRUE;
+      }
+
+      Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);
+      if (!EFI_ERROR (Status)) {
+        DeviceExist = TRUE;
+      }
+    } else {
+      //
+      // Connect the instance device path
+      //
+      Status = BdsLibConnectDevicePath (Instance);
+      if (EFI_ERROR (Status)) {
+        //
+        // Delete the instance from the console varialbe
+        //
+        BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
+      } else {
+        DeviceExist = TRUE;
+      }
+    }
+    SafeFreePool(Instance);
+  } while (CopyOfDevicePath != NULL);
+
+  gBS->FreePool (StartDevicePath);
+
+  if (DeviceExist == FALSE) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function will search every simpletxt devive in current system,
+  and make every simpletxt device as pertantial console device.
+
+  None
+
+  @return None
+
+**/
+VOID
+BdsLibConnectAllConsoles (
+  VOID
+  )
+{
+  UINTN                     Index;
+  EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;
+  UINTN                     HandleCount;
+  EFI_HANDLE                *HandleBuffer;
+
+  Index         = 0;
+  HandleCount   = 0;
+  HandleBuffer  = NULL;
+  ConDevicePath = NULL;
+
+  //
+  // Update all the console varables
+  //
+  gBS->LocateHandleBuffer (
+          ByProtocol,
+          &gEfiSimpleTextInProtocolGuid,
+          NULL,
+          &HandleCount,
+          &HandleBuffer
+          );
+  
+  for (Index = 0; Index < HandleCount; Index++) {
+    gBS->HandleProtocol (
+            HandleBuffer[Index],
+            &gEfiDevicePathProtocolGuid,
+            (VOID **) &ConDevicePath
+            );
+    BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
+  }
+
+  SafeFreePool(HandleBuffer);
+
+  gBS->LocateHandleBuffer (
+          ByProtocol,
+          &gEfiSimpleTextOutProtocolGuid,
+          NULL,
+          &HandleCount,
+          &HandleBuffer
+          );
+  for (Index = 0; Index < HandleCount; Index++) {
+    gBS->HandleProtocol (
+            HandleBuffer[Index],
+            &gEfiDevicePathProtocolGuid,
+            (VOID **) &ConDevicePath
+            );
+    BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
+    BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
+  }
+
+  SafeFreePool(HandleBuffer);
+
+  //
+  // Connect all console variables
+  //
+  BdsLibConnectAllDefaultConsoles ();
+
+}
+
+
+/**
+  This function will connect console device base on the console
+  device variable ConIn, ConOut and ErrOut.
+
+  None
+
+  @retval EFI_SUCCESS              At least one of the ConIn and ConOut device have
+                                   been connected success.
+  @retval EFI_STATUS               Return the status of
+                                   BdsLibConnectConsoleVariable ().
+
+**/
+EFI_STATUS
+BdsLibConnectAllDefaultConsoles (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+
+  //
+  // Connect all default console variables
+  //
+
+  //
+  // It seems impossible not to have any ConOut device on platform,
+  // so we check the status here.
+  //
+  Status = BdsLibConnectConsoleVariable (L"ConOut");
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Insert the performance probe for Console Out
+  //
+  PERF_START (NULL, "ConOut", "BDS", 1);
+  PERF_END (NULL, "ConOut", "BDS", 0);
+
+  //
+  // Because possibly the platform is legacy free, in such case,
+  // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
+  // so we need not check the status.
+  //
+  BdsLibConnectConsoleVariable (L"ConIn");
+
+  //
+  // The _ModuleEntryPoint err out var is legal.
+  //
+  BdsLibConnectConsoleVariable (L"ErrOut");
+
+  return EFI_SUCCESS;
+
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/BdsMisc.c b/edk2/MdeModulePkg/Library/GenericBdsLib/BdsMisc.c
new file mode 100644 (file)
index 0000000..739913b
--- /dev/null
@@ -0,0 +1,1415 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BdsMisc.c
+
+Abstract:
+
+  Misc BDS library function
+
+
+**/
+
+#include "InternalBdsLib.h"
+
+
+#define MAX_STRING_LEN        200
+
+static BOOLEAN   mFeaturerSwitch = TRUE;
+static BOOLEAN   mResetRequired = FALSE;
+
+extern UINT16 gPlatformBootTimeOutDefault;
+
+
+/**
+  Return the default value for system Timeout variable.
+
+  None
+
+  @return Timeout value.
+
+**/
+UINT16
+BdsLibGetTimeout (
+  VOID
+  )
+{
+  UINT16      Timeout;
+  UINTN       Size;
+  EFI_STATUS  Status;
+
+  //
+  // Return Timeout variable or 0xffff if no valid
+  // Timeout variable exists.
+  //
+  Size    = sizeof (UINT16);
+  Status  = gRT->GetVariable (L"Timeout", &gEfiGlobalVariableGuid, NULL, &Size, &Timeout);
+  if (!EFI_ERROR (Status)) {
+    return Timeout;
+  }
+  //
+  // To make the current EFI Automatic-Test activity possible, just add
+  // following code to make AutoBoot enabled when this variable is not
+  // present.
+  // This code should be removed later.
+  //
+  Timeout = PcdGet16 (PcdPlatformBootTimeOutDefault);
+
+  //
+  // Notes: Platform should set default variable if non exists on all error cases!!!
+  //
+  Status = gRT->SetVariable (
+                  L"Timeout",
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  sizeof (UINT16),
+                  &Timeout
+                  );
+  return Timeout;
+}
+
+
+/**
+  The function will go through the driver optoin link list, load and start
+  every driver the driver optoin device path point to.
+
+  @param  BdsDriverLists        The header of the current driver option link list
+
+  @return None
+
+**/
+VOID
+BdsLibLoadDrivers (
+  IN LIST_ENTRY                   *BdsDriverLists
+  )
+{
+  EFI_STATUS                Status;
+  LIST_ENTRY                *Link;
+  BDS_COMMON_OPTION         *Option;
+  EFI_HANDLE                ImageHandle;
+  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
+  UINTN                     ExitDataSize;
+  CHAR16                    *ExitData;
+  BOOLEAN                   ReconnectAll;
+
+  ReconnectAll = FALSE;
+
+  //
+  // Process the driver option
+  //
+  for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) {
+    Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
+    //
+    // If a load option is not marked as LOAD_OPTION_ACTIVE,
+    // the boot manager will not automatically load the option.
+    //
+    if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) {
+      continue;
+    }
+    //
+    // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
+    // then all of the EFI drivers in the system will be disconnected and
+    // reconnected after the last driver load option is processed.
+    //
+    if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) {
+      ReconnectAll = TRUE;
+    }
+    //
+    // Make sure the driver path is connected.
+    //
+    BdsLibConnectDevicePath (Option->DevicePath);
+
+    //
+    // Load and start the image that Driver#### describes
+    //
+    Status = gBS->LoadImage (
+                    FALSE,
+                    mBdsImageHandle,
+                    Option->DevicePath,
+                    NULL,
+                    0,
+                    &ImageHandle
+                    );
+
+    if (!EFI_ERROR (Status)) {
+      gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo);
+
+      //
+      // Verify whether this image is a driver, if not,
+      // exit it and continue to parse next load option
+      //
+      if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) {
+        gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL);
+        continue;
+      }
+
+      if (Option->LoadOptionsSize != 0) {
+        ImageInfo->LoadOptionsSize  = Option->LoadOptionsSize;
+        ImageInfo->LoadOptions      = Option->LoadOptions;
+      }
+      //
+      // Before calling the image, enable the Watchdog Timer for
+      // the 5 Minute period
+      //
+      gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);
+
+      Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
+      DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", Status));
+
+      //
+      // Clear the Watchdog Timer after the image returns
+      //
+      gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
+    }
+  }
+  //
+  // Process the LOAD_OPTION_FORCE_RECONNECT driver option
+  //
+  if (ReconnectAll) {
+    BdsLibDisconnectAllEfi ();
+    BdsLibConnectAll ();
+  }
+
+}
+
+
+/**
+  Get the Option Number that does not used
+  Try to locate the specific option variable one by one untile find a free number
+
+  @param  VariableName          Indicate if the boot#### or driver#### option
+
+  @return The Minimal Free Option Number
+
+**/
+UINT16
+BdsLibGetFreeOptionNumber (
+  IN  CHAR16    *VariableName
+  )
+{
+  UINT16        Number;
+  UINTN         Index;
+  CHAR16        StrTemp[10];
+  UINT16        *OptionBuffer;
+  UINTN         OptionSize;
+
+  //
+  // Try to find the minimum free number from 0, 1, 2, 3....
+  //
+  Index = 0;
+  do {
+    if (*VariableName == 'B') {
+      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);
+    } else {
+      UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index);
+    }
+    //
+    // try if the option number is used
+    //
+    OptionBuffer = BdsLibGetVariableAndSize (
+              StrTemp,
+              &gEfiGlobalVariableGuid,
+              &OptionSize
+              );
+    if (OptionBuffer == NULL) {
+      break;
+    }
+    Index++;
+  } while (1);
+
+  Number = (UINT16) Index;
+  return Number;
+}
+
+
+/**
+  This function will register the new boot#### or driver#### option base on
+  the VariableName. The new registered boot#### or driver#### will be linked
+  to BdsOptionList and also update to the VariableName. After the boot#### or
+  driver#### updated, the BootOrder or DriverOrder will also be updated.
+
+  @param  BdsOptionList         The header of the boot#### or driver#### link list
+  @param  DevicePath            The device path which the boot#### or driver####
+                                option present
+  @param  String                The description of the boot#### or driver####
+  @param  VariableName          Indicate if the boot#### or driver#### option
+
+  @retval EFI_SUCCESS           The boot#### or driver#### have been success
+                                registered
+  @retval EFI_STATUS            Return the status of gRT->SetVariable ().
+
+**/
+EFI_STATUS
+BdsLibRegisterNewOption (
+  IN  LIST_ENTRY                     *BdsOptionList,
+  IN  EFI_DEVICE_PATH_PROTOCOL       *DevicePath,
+  IN  CHAR16                         *String,
+  IN  CHAR16                         *VariableName
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Index;
+  UINT16                    RegisterOptionNumber;
+  UINT16                    *TempOptionPtr;
+  UINTN                     TempOptionSize;
+  UINT16                    *OptionOrderPtr;
+  VOID                      *OptionPtr;
+  UINTN                     OptionSize;
+  UINT8                     *TempPtr;
+  EFI_DEVICE_PATH_PROTOCOL  *OptionDevicePath;
+  CHAR16                    *Description;
+  CHAR16                    OptionName[10];
+  BOOLEAN                   UpdateBootDevicePath;
+  UINT16                    BootOrderEntry;
+  UINTN                     OrderItemNum;
+
+
+  OptionPtr             = NULL;
+  OptionSize            = 0;
+  TempPtr               = NULL;
+  OptionDevicePath      = NULL;
+  Description           = NULL;
+  OptionOrderPtr        = NULL;
+  UpdateBootDevicePath  = FALSE;
+  ZeroMem (OptionName, sizeof (OptionName));
+
+  TempOptionSize = 0;
+  TempOptionPtr = BdsLibGetVariableAndSize (
+                    VariableName,
+                    &gEfiGlobalVariableGuid,
+                    &TempOptionSize
+                    );
+
+  //
+  // Compare with current option variable
+  //
+  for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) {
+
+    if (*VariableName == 'B') {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]);
+    } else {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]);
+    }
+
+    OptionPtr = BdsLibGetVariableAndSize (
+                  OptionName,
+                  &gEfiGlobalVariableGuid,
+                  &OptionSize
+                  );
+    if (OptionPtr == NULL) {
+      continue;
+    }
+    TempPtr = OptionPtr;
+    TempPtr += sizeof (UINT32) + sizeof (UINT16);
+    Description = (CHAR16 *) TempPtr;
+    TempPtr += StrSize ((CHAR16 *) TempPtr);
+    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+
+    //
+    // Notes: the description may will change base on the GetStringToken
+    //
+    if (CompareMem (Description, String, StrSize (Description)) == 0) {
+      if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) {
+        //
+        // Got the option, so just return
+        //
+        gBS->FreePool (OptionPtr);
+        gBS->FreePool (TempOptionPtr);
+        return EFI_SUCCESS;
+      } else {
+        //
+        // Boot device path changed, need update.
+        //
+        UpdateBootDevicePath = TRUE;
+        break;
+      }
+    }
+
+    gBS->FreePool (OptionPtr);
+  }
+
+  OptionSize          = sizeof (UINT32) + sizeof (UINT16) + StrSize (String);
+  OptionSize += GetDevicePathSize (DevicePath);
+  OptionPtr           = AllocateZeroPool (OptionSize);
+  TempPtr             = OptionPtr;
+  *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE;
+  TempPtr += sizeof (UINT32);
+  *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath);
+  TempPtr += sizeof (UINT16);
+  CopyMem (TempPtr, String, StrSize (String));
+  TempPtr += StrSize (String);
+  CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath));
+
+  if (UpdateBootDevicePath) {
+    //
+    // The number in option#### to be updated
+    //
+    RegisterOptionNumber = TempOptionPtr[Index];
+  } else {
+    //
+    // The new option#### number
+    //
+    RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName);
+  }
+
+  if (*VariableName == 'B') {
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber);
+  } else {
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber);
+  }
+
+  Status = gRT->SetVariable (
+                  OptionName,
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  OptionSize,
+                  OptionPtr
+                  );
+  if (EFI_ERROR (Status) || UpdateBootDevicePath) {
+    gBS->FreePool (OptionPtr);
+    gBS->FreePool (TempOptionPtr);
+    return Status;
+  }
+
+  gBS->FreePool (OptionPtr);
+
+  //
+  // Update the option order variable
+  //
+
+  //
+  // If no BootOrder
+  //
+  if (TempOptionSize == 0) {
+    BootOrderEntry = 0;
+    Status = gRT->SetVariable (
+                    VariableName,
+                    &gEfiGlobalVariableGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                    sizeof (UINT16),
+                    &BootOrderEntry
+                    );
+    if (EFI_ERROR (Status)) {
+      gBS->FreePool (TempOptionPtr);
+      return Status;
+    }
+    return EFI_SUCCESS;
+  }
+
+  if (UpdateBootDevicePath) {
+    //
+    // If just update a old option, the new optionorder size not change
+    //
+    OrderItemNum = (TempOptionSize / sizeof (UINT16)) ;
+    OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16));
+    CopyMem (OptionOrderPtr, TempOptionPtr, OrderItemNum * sizeof (UINT16));
+  } else {
+    OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ;
+    OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16));
+    CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof (UINT16));
+  }
+
+  OptionOrderPtr[Index] = RegisterOptionNumber;
+
+  Status = gRT->SetVariable (
+                  VariableName,
+                  &gEfiGlobalVariableGuid,
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+                  OrderItemNum * sizeof (UINT16),
+                  OptionOrderPtr
+                  );
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (TempOptionPtr);
+    gBS->FreePool (OptionOrderPtr);
+    return Status;
+  }
+
+  gBS->FreePool (TempOptionPtr);
+  gBS->FreePool (OptionOrderPtr);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Build the boot#### or driver#### option from the VariableName, the
+  build boot#### or driver#### will also be linked to BdsCommonOptionList
+
+  @param  BdsCommonOptionList   The header of the boot#### or driver#### option
+                                link list
+  @param  VariableName          EFI Variable name indicate if it is boot#### or
+                                driver####
+
+  @retval BDS_COMMON_OPTION     Get the option just been created
+  @retval NULL                  Failed to get the new option
+
+**/
+BDS_COMMON_OPTION *
+BdsLibVariableToOption (
+  IN OUT LIST_ENTRY                   *BdsCommonOptionList,
+  IN  CHAR16                          *VariableName
+  )
+{
+  UINT32                    Attribute;
+  UINT16                    FilePathSize;
+  UINT8                     *Variable;
+  UINT8                     *TempPtr;
+  UINTN                     VariableSize;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  BDS_COMMON_OPTION         *Option;
+  VOID                      *LoadOptions;
+  UINT32                    LoadOptionsSize;
+  CHAR16                    *Description;
+  UINT8                     NumOff;
+  //
+  // Read the variable. We will never free this data.
+  //
+  Variable = BdsLibGetVariableAndSize (
+              VariableName,
+              &gEfiGlobalVariableGuid,
+              &VariableSize
+              );
+  if (Variable == NULL) {
+    return NULL;
+  }
+  //
+  // Notes: careful defined the variable of Boot#### or
+  // Driver####, consider use some macro to abstract the code
+  //
+  //
+  // Get the option attribute
+  //
+  TempPtr   = Variable;
+  Attribute = *(UINT32 *) Variable;
+  TempPtr += sizeof (UINT32);
+
+  //
+  // Get the option's device path size
+  //
+  FilePathSize = *(UINT16 *) TempPtr;
+  TempPtr += sizeof (UINT16);
+
+  //
+  // Get the option's description string
+  //
+  Description = (CHAR16 *) TempPtr;
+
+  //
+  // Get the option's description string size
+  //
+  TempPtr += StrSize ((CHAR16 *) TempPtr);
+
+  //
+  // Get the option's device path
+  //
+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
+  TempPtr += FilePathSize;
+
+  LoadOptions     = TempPtr;
+  LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
+
+  //
+  // The Console variables may have multiple device paths, so make
+  // an Entry for each one.
+  //
+  Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION));
+  if (Option == NULL) {
+    return NULL;
+  }
+
+  Option->Signature   = BDS_LOAD_OPTION_SIGNATURE;
+  Option->DevicePath  = AllocateZeroPool (GetDevicePathSize (DevicePath));
+  CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));
+  Option->Attribute   = Attribute;
+  Option->Description = AllocateZeroPool (StrSize (Description));
+  CopyMem (Option->Description, Description, StrSize (Description));
+  Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
+  CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
+  Option->LoadOptionsSize = LoadOptionsSize;
+
+  //
+  // Get the value from VariableName Unicode string
+  // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this
+  // Unicode stream to ASCII without any loss in meaning.
+  //
+  if (*VariableName == 'B') {
+    NumOff = sizeof (L"Boot")/sizeof(CHAR16) -1 ;
+    Option->BootCurrent = (UINT16) ((VariableName[NumOff]  -'0') * 0x1000);
+    Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+1]-'0') * 0x100));
+    Option->BootCurrent = (UINT16) (Option->BootCurrent +  ((VariableName[NumOff+2]-'0') * 0x10));
+    Option->BootCurrent = (UINT16) (Option->BootCurrent + ((VariableName[NumOff+3]-'0')));
+  }
+  //
+  // Insert active entry to BdsDeviceList
+  //
+  if ((Option->Attribute & LOAD_OPTION_ACTIVE) == LOAD_OPTION_ACTIVE) {
+    InsertTailList (BdsCommonOptionList, &Option->Link);
+    gBS->FreePool (Variable);
+    return Option;
+  }
+
+  gBS->FreePool (Variable);
+  gBS->FreePool (Option);
+  return NULL;
+
+}
+
+
+/**
+  Process BootOrder, or DriverOrder variables, by calling
+  BdsLibVariableToOption () for each UINT16 in the variables.
+
+  @param  BdsCommonOptionList   The header of the option list base on variable
+                                VariableName
+  @param  VariableName          EFI Variable name indicate the BootOrder or
+                                DriverOrder
+
+  @retval EFI_SUCCESS           Success create the boot option or driver option
+                                list
+  @retval EFI_OUT_OF_RESOURCES  Failed to get the boot option or driver option list
+
+**/
+EFI_STATUS
+BdsLibBuildOptionFromVar (
+  IN  LIST_ENTRY                      *BdsCommonOptionList,
+  IN  CHAR16                          *VariableName
+  )
+{
+  UINT16            *OptionOrder;
+  UINTN             OptionOrderSize;
+  UINTN             Index;
+  BDS_COMMON_OPTION *Option;
+  CHAR16            OptionName[20];
+
+  //
+  // Zero Buffer in order to get all BOOT#### variables
+  //
+  ZeroMem (OptionName, sizeof (OptionName));
+
+  //
+  // Read the BootOrder, or DriverOrder variable.
+  //
+  OptionOrder = BdsLibGetVariableAndSize (
+                  VariableName,
+                  &gEfiGlobalVariableGuid,
+                  &OptionOrderSize
+                  );
+  if (OptionOrder == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
+    if (*VariableName == 'B') {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
+    } else {
+      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
+    }
+
+    Option              = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
+    Option->BootCurrent = OptionOrder[Index];
+
+  }
+
+  gBS->FreePool (OptionOrder);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Get boot mode by looking up configuration table and parsing HOB list
+
+  @param  BootMode              Boot mode from PEI handoff HOB.
+
+  @retval EFI_SUCCESS           Successfully get boot mode
+  @retval EFI_NOT_FOUND         Can not find the current system boot mode
+
+**/
+EFI_STATUS
+BdsLibGetBootMode (
+  OUT EFI_BOOT_MODE       *BootMode
+  )
+{
+  VOID        *HobList;
+  EFI_STATUS  Status;
+
+  //
+  // Get Hob list
+  //
+  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Hob list not found\n"));
+    *BootMode = 0;
+    return EFI_NOT_FOUND;
+  }
+
+  Status = R8_GetHobBootMode (HobList, BootMode);
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
+  buffer, and the size of the buffer. If failure return NULL.
+
+  @param  Name                  String part of EFI variable name
+  @param  VendorGuid            GUID part of EFI variable name
+  @param  VariableSize          Returns the size of the EFI variable that was read
+
+  @return Dynamically allocated memory that contains a copy of the EFI variable.
+  @return Caller is responsible freeing the buffer.
+  @retval NULL                  Variable was not read
+
+**/
+VOID *
+BdsLibGetVariableAndSize (
+  IN  CHAR16              *Name,
+  IN  EFI_GUID            *VendorGuid,
+  OUT UINTN               *VariableSize
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       BufferSize;
+  VOID        *Buffer;
+
+  Buffer = NULL;
+
+  //
+  // Pass in a zero size buffer to find the required buffer size.
+  //
+  BufferSize  = 0;
+  Status      = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    //
+    // Allocate the buffer to return
+    //
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      return NULL;
+    }
+    //
+    // Read variable into the allocated buffer.
+    //
+    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
+    if (EFI_ERROR (Status)) {
+      BufferSize = 0;
+    }
+  }
+
+  *VariableSize = BufferSize;
+  return Buffer;
+}
+
+
+/**
+  Delete the instance in Multi which matches partly with Single instance
+
+  @param  Multi                 A pointer to a multi-instance device path data
+                                structure.
+  @param  Single                A pointer to a single-instance device path data
+                                structure.
+
+  @return This function will remove the device path instances in Multi which partly
+  @return match with the Single, and return the result device path. If there is no
+  @return remaining device path as a result, this function will return NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+BdsLibDelPartMatchInstance (
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Multi,
+  IN     EFI_DEVICE_PATH_PROTOCOL  *Single
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Instance;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *TempNewDevicePath;
+  UINTN                     InstanceSize;
+  UINTN                     SingleDpSize;
+  UINTN                     Size;
+
+  NewDevicePath     = NULL;
+  TempNewDevicePath = NULL;
+
+  if (Multi == NULL || Single == NULL) {
+    return Multi;
+  }
+
+  Instance        =  GetNextDevicePathInstance (&Multi, &InstanceSize);
+  SingleDpSize    =  GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
+  InstanceSize    -= END_DEVICE_PATH_LENGTH;
+
+  while (Instance != NULL) {
+
+    Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
+
+    if ((CompareMem (Instance, Single, Size) != 0)) {
+      //
+      // Append the device path instance which does not match with Single
+      //
+      TempNewDevicePath = NewDevicePath;
+      NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
+      SafeFreePool(TempNewDevicePath);
+    }
+    SafeFreePool(Instance);
+    Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
+    InstanceSize  -= END_DEVICE_PATH_LENGTH;
+  }
+
+  return NewDevicePath;
+}
+
+
+/**
+  Function compares a device path data structure to that of all the nodes of a
+  second device path instance.
+
+  @param  Multi                 A pointer to a multi-instance device path data
+                                structure.
+  @param  Single                A pointer to a single-instance device path data
+                                structure.
+
+  @retval TRUE                  If the Single is contained within Multi
+  @retval FALSE                 The Single is not match within Multi
+
+**/
+BOOLEAN
+BdsLibMatchDevicePaths (
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
+  UINTN                     Size;
+
+  if (!Multi || !Single) {
+    return FALSE;
+  }
+
+  DevicePath      = Multi;
+  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);
+
+  //
+  // Search for the match of 'Single' in 'Multi'
+  //
+  while (DevicePathInst != NULL) {
+    //
+    // If the single device path is found in multiple device paths,
+    // return success
+    //
+    if (CompareMem (Single, DevicePathInst, Size) == 0) {
+      gBS->FreePool (DevicePathInst);
+      return TRUE;
+    }
+
+    gBS->FreePool (DevicePathInst);
+    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
+  }
+
+  return FALSE;
+}
+
+
+/**
+  This function prints a series of strings.
+
+  @param  ConOut                Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+  @param  ...                   A variable argument list containing series of
+                                strings, the last string must be NULL.
+
+  @retval EFI_SUCCESS           Success print out the string using ConOut.
+  @retval EFI_STATUS            Return the status of the ConOut->OutputString ().
+
+**/
+EFI_STATUS
+BdsLibOutputStrings (
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut,
+  ...
+  )
+{
+  VA_LIST     args;
+  EFI_STATUS  Status;
+  CHAR16      *String;
+
+  Status = EFI_SUCCESS;
+  VA_START (args, ConOut);
+
+  while (!EFI_ERROR (Status)) {
+    //
+    // If String is NULL, then it's the end of the list
+    //
+    String = VA_ARG (args, CHAR16 *);
+    if (!String) {
+      break;
+    }
+
+    Status = ConOut->OutputString (ConOut, String);
+
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+  }
+
+  return Status;
+}
+
+//
+//  Following are BDS Lib functions which  contain all the code about setup browser reset reminder feature.
+//  Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser  if
+//  user change any option setting which needs a reset to be effective, and  the reset will be applied according to  the user selection.
+//
+
+
+/**
+  Enable the setup browser reset reminder feature.
+  This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
+
+  VOID
+
+  @return VOID
+
+**/
+VOID
+EnableResetReminderFeature (
+  VOID
+  )
+{
+  mFeaturerSwitch = TRUE;
+}
+
+
+/**
+  Disable the setup browser reset reminder feature.
+  This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
+
+  VOID
+
+  @return VOID
+
+**/
+VOID
+DisableResetReminderFeature (
+  VOID
+  )
+{
+  mFeaturerSwitch = FALSE;
+}
+
+
+/**
+  Record the info that  a reset is required.
+  A  module boolean variable is used to record whether a reset is required.
+
+  VOID
+
+  @return VOID
+
+**/
+VOID
+EnableResetRequired (
+  VOID
+  )
+{
+  mResetRequired = TRUE;
+}
+
+
+/**
+  Record the info that  no reset is required.
+  A  module boolean variable is used to record whether a reset is required.
+
+  VOID
+
+  @return VOID
+
+**/
+VOID
+DisableResetRequired (
+  VOID
+  )
+{
+  mResetRequired = FALSE;
+}
+
+
+/**
+  Check whether platform policy enable the reset reminder feature. The default is enabled.
+
+  VOID
+
+  @return VOID
+
+**/
+BOOLEAN
+IsResetReminderFeatureEnable (
+  VOID
+  )
+{
+  return mFeaturerSwitch;
+}
+
+
+/**
+  Check if  user changed any option setting which needs a system reset to be effective.
+
+  VOID
+
+  @return VOID
+
+**/
+BOOLEAN
+IsResetRequired (
+  VOID
+  )
+{
+  return mResetRequired;
+}
+
+
+/**
+  Check whether a reset is needed, and finish the reset reminder feature.
+  If a reset is needed, Popup a menu to notice user, and finish the feature
+  according to the user selection.
+
+  VOID
+
+  @return VOID
+
+**/
+VOID
+SetupResetReminder (
+  VOID
+  )
+{
+#if (EFI_SPECIFICATION_VERSION < 0x0002000A)
+  EFI_STATUS                    Status;
+  EFI_FORM_BROWSER_PROTOCOL     *Browser;
+#endif
+  EFI_INPUT_KEY                 Key;
+  CHAR16                        *StringBuffer1;
+  CHAR16                        *StringBuffer2;
+
+
+  //
+  //check any reset required change is applied? if yes, reset system
+  //
+  if (IsResetReminderFeatureEnable ()) {
+    if (IsResetRequired ()) {
+
+#if (EFI_SPECIFICATION_VERSION < 0x0002000A)
+      Status = gBS->LocateProtocol (
+                      &gEfiFormBrowserProtocolGuid,
+                      NULL,
+                      &Browser
+                      );
+#endif
+
+      StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
+      ASSERT (StringBuffer1 != NULL);
+      StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
+      ASSERT (StringBuffer2 != NULL);
+      StrCpy (StringBuffer1, L"Configuration changed. Reset to apply it Now ? ");
+      StrCpy (StringBuffer2, L"Enter (YES)  /   Esc (NO)");
+      //
+      // Popup a menu to notice user
+      //
+      do {
+#if (EFI_SPECIFICATION_VERSION < 0x0002000A)
+        Browser->CreatePopUp (2, TRUE, 0, NULL, &Key, StringBuffer1, StringBuffer2);
+#else
+        IfrLibCreatePopUp (2, &Key, StringBuffer1, StringBuffer2);
+#endif
+      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
+
+      gBS->FreePool (StringBuffer1);
+      gBS->FreePool (StringBuffer2);
+      //
+      // If the user hits the YES Response key, reset
+      //
+      if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
+        gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+      }
+      gST->ConOut->ClearScreen (gST->ConOut);
+    }
+  }
+}
+
+
+/**
+  Get the headers (dos, image, optional header) from an image
+
+  @param  Device                SimpleFileSystem device handle
+  @param  FileName              File name for the image
+  @param  DosHeader             Pointer to dos header
+  @param  ImageHeader           Pointer to image header
+  @param  OptionalHeader        Pointer to optional header
+
+  @retval EFI_SUCCESS           Successfully get the machine type.
+  @retval EFI_NOT_FOUND         The file is not found.
+  @retval EFI_LOAD_ERROR        File is not a valid image file.
+
+**/
+EFI_STATUS
+BdsLibGetImageHeader (
+  IN  EFI_HANDLE                  Device,
+  IN  CHAR16                      *FileName,
+  OUT EFI_IMAGE_DOS_HEADER        *DosHeader,
+  OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Volume;
+  EFI_FILE_HANDLE                  Root;
+  EFI_FILE_HANDLE                  ThisFile;
+  UINTN                            BufferSize;
+  UINT64                           FileSize;
+  EFI_FILE_INFO                    *Info;
+
+  Root     = NULL;
+  ThisFile = NULL;
+  //
+  // Handle the file system interface to the device
+  //
+  Status = gBS->HandleProtocol (
+                  Device,
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  (VOID *) &Volume
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = Volume->OpenVolume (
+                     Volume,
+                     &Root
+                     );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  //
+  // Get file size
+  //
+  BufferSize  = SIZE_OF_EFI_FILE_INFO + 200;
+  do {
+    Info   = NULL;
+    Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info);
+    if (EFI_ERROR (Status)) {
+      goto Done;
+    }
+    Status = ThisFile->GetInfo (
+                         ThisFile,
+                         &gEfiFileInfoGuid,
+                         &BufferSize,
+                         Info
+                         );
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+    if (Status != EFI_BUFFER_TOO_SMALL) {
+      goto Done;
+    }
+    gBS->FreePool (Info);
+  } while (TRUE);
+
+  FileSize = Info->FileSize;
+  gBS->FreePool (Info);
+
+  //
+  // Read dos header
+  //
+  BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);
+  Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader);
+  if (EFI_ERROR (Status) ||
+      BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) ||
+      FileSize <= DosHeader->e_lfanew ||
+      DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+  //
+  // Move to PE signature
+  //
+  Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+  //
+  // Read and check PE signature
+  //
+  BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
+  Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32);
+  if (EFI_ERROR (Status) ||
+      BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) ||
+      Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+  //
+  // Check PE32 or PE32+ magic
+  //
+  if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
+      Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+    Status = EFI_LOAD_ERROR;
+    goto Done;
+  }
+
+ Done:
+  if (ThisFile != NULL) {
+    ThisFile->Close (ThisFile);
+  }
+  if (Root != NULL) {
+    Root->Close (Root);
+  }
+  return Status;
+}
+
+#if (EFI_SPECIFICATION_VERSION < 0x0002000A)
+EFI_STATUS
+BdsLibGetHiiHandles (
+  IN     EFI_HII_PROTOCOL *Hii,
+  IN OUT UINT16           *HandleBufferLength,
+  OUT    EFI_HII_HANDLE   **HiiHandleBuffer
+  )
+/*++
+
+Routine Description:
+
+  Determines the handles that are currently active in the database.
+  It's the caller's responsibility to free handle buffer.
+
+Arguments:
+
+  This                  - A pointer to the EFI_HII_PROTOCOL instance.
+  HandleBufferLength    - On input, a pointer to the length of the handle buffer. On output,
+                          the length of the handle buffer that is required for the handles found.
+  HiiHandleBuffer       - Pointer to an array of EFI_HII_PROTOCOL instances returned.
+
+Returns:
+
+  EFI_SUCCESS           - Get an array of EFI_HII_PROTOCOL instances successfully.
+  EFI_INVALID_PARAMETER - Hii is NULL.
+  EFI_NOT_FOUND         - Database not found.
+
+--*/
+{
+  UINT16      TempBufferLength;
+  EFI_STATUS  Status;
+
+  TempBufferLength = 0;
+
+  //
+  // Try to find the actual buffer size for HiiHandle Buffer.
+  //
+  Status = Hii->FindHandles (Hii, &TempBufferLength, *HiiHandleBuffer);
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+      *HiiHandleBuffer = AllocateZeroPool (TempBufferLength);
+      Status = Hii->FindHandles (Hii, &TempBufferLength, *HiiHandleBuffer);
+      //
+      // we should not fail here.
+      //
+      ASSERT_EFI_ERROR (Status);
+  }
+
+  *HandleBufferLength = TempBufferLength;
+
+  return Status;
+
+}
+#endif
+
+VOID
+EFIAPI
+BdsSetMemoryTypeInformationVariable (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+/*++
+
+Routine Description:
+
+  This routine is a notification function for legayc boot or exit boot
+  service event. It will adjust the memory information for different
+  memory type and save them into the variables for next boot
+
+Arguments:
+
+  Event    - The event that triggered this notification function
+  Context  - Pointer to the notification functions context
+
+Returns:
+
+  None.
+
+--*/
+{
+  EFI_STATUS                   Status;
+  EFI_MEMORY_TYPE_INFORMATION  *PreviousMemoryTypeInformation;
+  EFI_MEMORY_TYPE_INFORMATION  *CurrentMemoryTypeInformation;
+  UINTN                        VariableSize;
+  BOOLEAN                      UpdateRequired;
+  UINTN                        Index;
+  UINTN                        Index1;
+  UINT32                       Previous;
+  UINT32                       Current;
+  UINT32                       Next;
+  VOID                         *HobList;
+
+  UpdateRequired = FALSE;
+
+  //
+  // Retrieve the current memory usage statistics.  If they are not found, then
+  // no adjustments can be made to the Memory Type Information variable.
+  //
+  Status = EfiGetSystemConfigurationTable (
+             &gEfiMemoryTypeInformationGuid,
+             (VOID **) &CurrentMemoryTypeInformation
+             );
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Get the Memory Type Information settings from Hob if they exist,
+  // PEI is responsible for getting them from variable and build a Hob to save them.
+  // If the previous Memory Type Information is not available, then set defaults
+  //
+  EfiGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+  Status = R8_GetNextGuidHob (&HobList, &gEfiMemoryTypeInformationGuid, (VOID **) &PreviousMemoryTypeInformation, &VariableSize);
+  if (EFI_ERROR (Status) || PreviousMemoryTypeInformation == NULL) {
+    //
+    // If Platform has not built Memory Type Info into the Hob, just return.
+    //
+    return;
+  }
+
+  //
+  // Use a heuristic to adjust the Memory Type Information for the next boot
+  //
+  for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
+
+    Current = 0;
+    for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) {
+      if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) {
+        Current = CurrentMemoryTypeInformation[Index1].NumberOfPages;
+        break;
+      }
+    }
+
+    if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) {
+      continue;
+    }
+
+    Previous = PreviousMemoryTypeInformation[Index].NumberOfPages;
+
+    //
+    // Write next varible to 125% * current and Inconsistent Memory Reserved across bootings may lead to S4 fail
+    //
+    if (Current > Previous) {
+      Next = Current + (Current >> 2);
+    } else {
+      Next = Previous;
+    }
+    if (Next > 0 && Next < 4) {
+      Next = 4;
+    }
+
+    if (Next != Previous) {
+      PreviousMemoryTypeInformation[Index].NumberOfPages = Next;
+      UpdateRequired = TRUE;
+    }
+
+  }
+
+  //
+  // If any changes were made to the Memory Type Information settings, then set the new variable value
+  //
+  if (UpdateRequired) {
+    Status = gRT->SetVariable (
+          EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+          &gEfiMemoryTypeInformationGuid,
+          EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+          VariableSize,
+          PreviousMemoryTypeInformation
+          );
+  }
+
+  return;
+}
+
+
+/**
+  This routine register a function to adjust the different type memory page number just before booting
+  and save the updated info into the variable for next boot to use
+
+  None
+
+  @return None.
+
+**/
+VOID
+EFIAPI
+BdsLibSaveMemoryTypeInformation (
+  VOID
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_EVENT                    ReadyToBootEvent;
+
+  Status = EfiCreateEventReadyToBootEx (
+           TPL_CALLBACK,
+           BdsSetMemoryTypeInformationVariable,
+           NULL,
+           &ReadyToBootEvent
+           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,"Bds Set Memory Type Informationa Variable Fails\n"));
+  }
+
+}
+
+
+/**
+  return the current TPL, copied from the EDKII glue lib.
+
+  VOID
+
+  @return Current TPL
+
+**/
+EFI_TPL
+BdsLibGetCurrentTpl (
+  VOID
+  )
+{
+  EFI_TPL                 Tpl;
+
+  Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  gBS->RestoreTPL (Tpl);
+
+  return Tpl;
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/DevicePath.c b/edk2/MdeModulePkg/Library/GenericBdsLib/DevicePath.c
new file mode 100644 (file)
index 0000000..96a3c5d
--- /dev/null
@@ -0,0 +1,1321 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  DevicePath.c
+
+Abstract:
+
+  BDS internal function define the default device path string, it can be
+  replaced by platform device path.
+
+
+**/
+
+#include "InternalBdsLib.h"
+
+//
+// Platform Code should implement the Vendor specific Device Path display routine.
+//
+extern
+VOID
+DevPathVendor (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+;
+
+EFI_GUID  mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
+
+EFI_GUID mEfiDevicePathMessagingSASGuid = DEVICE_PATH_MESSAGING_SAS;
+
+
+VOID *
+ReallocatePool (
+  IN VOID                 *OldPool,
+  IN UINTN                OldSize,
+  IN UINTN                NewSize
+  )
+/*++
+
+Routine Description:
+
+  Adjusts the size of a previously allocated buffer.
+
+Arguments:
+
+  OldPool               - A pointer to the buffer whose size is being adjusted.
+
+  OldSize               - The size of the current buffer.
+
+  NewSize               - The size of the new buffer.
+
+Returns:
+
+  EFI_SUCEESS           - The requested number of bytes were allocated.
+
+  EFI_OUT_OF_RESOURCES  - The pool requested could not be allocated.
+
+  EFI_INVALID_PARAMETER - The buffer was invalid.
+
+--*/
+{
+  VOID  *NewPool;
+
+  NewPool = NULL;
+  if (NewSize) {
+    NewPool = AllocateZeroPool (NewSize);
+  }
+
+  if (OldPool) {
+    if (NewPool) {
+      CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
+    }
+
+    gBS->FreePool (OldPool);
+  }
+
+  return NewPool;
+}
+
+
+/**
+  Concatenates a formatted unicode string to allocated pool.
+  The caller must free the resulting buffer.
+
+  @param  Str      Tracks the allocated pool, size in use, and  amount of pool
+                   allocated.
+  @param  fmt      The format string
+
+  @return Allocated buffer with the formatted string printed in it.
+  @return The caller must free the allocated buffer.   The buffer
+  @return allocation is not packed.
+
+**/
+CHAR16 *
+CatPrint (
+  IN OUT POOL_PRINT   *Str,
+  IN CHAR16           *fmt,
+  ...
+  )
+{
+  UINT16  *AppendStr;
+  VA_LIST args;
+  UINTN   strsize;
+
+  AppendStr = AllocateZeroPool (0x1000);
+  if (AppendStr == NULL) {
+    return Str->str;
+  }
+
+  VA_START (args, fmt);
+  UnicodeVSPrint (AppendStr, 0x1000, fmt, args);
+  VA_END (args);
+  if (NULL == Str->str) {
+    strsize   = StrSize (AppendStr);
+    Str->str  = AllocateZeroPool (strsize);
+    ASSERT (Str->str != NULL);
+  } else {
+    strsize = StrSize (AppendStr);
+    strsize += (StrSize (Str->str) - sizeof (UINT16));
+
+    Str->str = ReallocatePool (
+                Str->str,
+                StrSize (Str->str),
+                strsize
+                );
+    ASSERT (Str->str != NULL);
+  }
+
+  Str->maxlen = MAX_CHAR * sizeof (UINT16);
+  if (strsize < Str->maxlen) {
+    StrCat (Str->str, AppendStr);
+    Str->len = strsize - sizeof (UINT16);
+  }
+
+  gBS->FreePool (AppendStr);
+  return Str->str;
+}
+
+
+/**
+  Function unpacks a device path data structure so that all the nodes
+  of a device path are naturally aligned.
+
+  @param  DevPath  A pointer to a device path data structure
+
+  @return If the memory for the device path is successfully allocated, then a
+  @return pointer to the new device path is returned.  Otherwise, NULL is returned.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+BdsLibUnpackDevicePath (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Src;
+  EFI_DEVICE_PATH_PROTOCOL  *Dest;
+  EFI_DEVICE_PATH_PROTOCOL  *NewPath;
+  UINTN                     Size;
+
+  //
+  // Walk device path and round sizes to valid boundries
+  //
+  Src   = DevPath;
+  Size  = 0;
+  for (;;) {
+    Size += DevicePathNodeLength (Src);
+    Size += ALIGN_SIZE (Size);
+
+    if (IsDevicePathEnd (Src)) {
+      break;
+    }
+
+    Src = NextDevicePathNode (Src);
+  }
+  //
+  // Allocate space for the unpacked path
+  //
+  NewPath = AllocateZeroPool (Size);
+  if (NewPath) {
+
+    ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
+
+    //
+    // Copy each node
+    //
+    Src   = DevPath;
+    Dest  = NewPath;
+    for (;;) {
+      Size = DevicePathNodeLength (Src);
+      CopyMem (Dest, Src, Size);
+      Size += ALIGN_SIZE (Size);
+      SetDevicePathNodeLength (Dest, Size);
+      Dest->Type |= EFI_DP_TYPE_UNPACKED;
+      Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
+
+      if (IsDevicePathEnd (Src)) {
+        break;
+      }
+
+      Src = NextDevicePathNode (Src);
+    }
+  }
+
+  return NewPath;
+}
+
+VOID
+DevPathPci (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  PCI_DEVICE_PATH *Pci;
+
+  Pci = DevPath;
+  CatPrint (Str, L"Pci(%x|%x)", (UINTN) Pci->Device, (UINTN) Pci->Function);
+}
+
+VOID
+DevPathPccard (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  PCCARD_DEVICE_PATH  *Pccard;
+
+  Pccard = DevPath;
+  CatPrint (Str, L"Pcmcia(Function%x)", (UINTN) Pccard->FunctionNumber);
+}
+
+VOID
+DevPathMemMap (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MEMMAP_DEVICE_PATH  *MemMap;
+
+  MemMap = DevPath;
+  CatPrint (
+    Str,
+    L"MemMap(%d:%lx-%lx)",
+    MemMap->MemoryType,
+    MemMap->StartingAddress,
+    MemMap->EndingAddress
+    );
+}
+
+VOID
+DevPathController (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  CONTROLLER_DEVICE_PATH  *Controller;
+
+  Controller = DevPath;
+  CatPrint (Str, L"Ctrl(%d)", (UINTN) Controller->ControllerNumber);
+}
+
+
+/**
+  Convert Vendor device path to device name
+
+  @param  Str      The buffer store device name
+  @param  DevPath  Pointer to vendor device path
+
+  @return When it return, the device name have been stored in *Str.
+
+**/
+VOID
+DevPathVendor (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+  CHAR16              *Type;
+  UINTN               DataLength;
+  UINTN               Index;
+  UINT32              FlowControlMap;
+
+  UINT16              Info;
+
+  Vendor  = DevPath;
+
+  switch (DevicePathType (&Vendor->Header)) {
+  case HARDWARE_DEVICE_PATH:
+    Type = L"Hw";
+// bugbug: nt 32 specific definition
+#if 0
+    //
+    // If the device is a winntbus device, we will give it a readable device name.
+    //
+    if (CompareGuid (&Vendor->Guid, &mEfiWinNtThunkProtocolGuid)) {
+      CatPrint (Str, L"%s", L"WinNtBus");
+      return ;
+    } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtGopGuid)) {
+      CatPrint (Str, L"%s", L"GOP");
+      return ;
+    } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtSerialPortGuid)) {
+      CatPrint (Str, L"%s", L"Serial");
+      return ;
+    }
+#endif
+    break;
+
+  case MESSAGING_DEVICE_PATH:
+    Type = L"Msg";
+    if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
+      CatPrint (Str, L"VenPcAnsi()");
+      return ;
+    } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+      CatPrint (Str, L"VenVt100()");
+      return ;
+    } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+      CatPrint (Str, L"VenVt100Plus()");
+      return ;
+    } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+      CatPrint (Str, L"VenUft8()");
+      return ;
+    } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {
+      FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+      switch (FlowControlMap & 0x00000003) {
+      case 0:
+        CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
+        break;
+
+      case 1:
+        CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
+        break;
+
+      case 2:
+        CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
+        break;
+
+      default:
+        break;
+      }
+
+      return ;
+
+    } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {
+      CatPrint (
+        Str,
+        L"SAS(%lx,%lx,%x,",
+        ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
+        ((SAS_DEVICE_PATH *) Vendor)->Lun,
+        ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
+        );
+      Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
+      if ((Info & 0x0f) == 0) {
+        CatPrint (Str, L"NoTopology,0,0,0,");
+      } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
+        CatPrint (
+          Str,
+          L"%s,%s,%s,",
+          (Info & (0x1 << 4)) ? L"SATA" : L"SAS",
+          (Info & (0x1 << 5)) ? L"External" : L"Internal",
+          (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"
+          );
+        if ((Info & 0x0f) == 1) {
+          CatPrint (Str, L"0,");
+        } else {
+          CatPrint (Str, L"%x,", (UINTN) ((Info >> 8) & 0xff));
+        }
+      } else {
+        CatPrint (Str, L"0,0,0,0,");
+      }
+
+      CatPrint (Str, L"%x)", (UINTN) ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+      return ;
+
+    } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+      CatPrint (Str, L"DebugPort()");
+      return ;
+    }
+    break;
+
+  case MEDIA_DEVICE_PATH:
+    Type = L"Media";
+    break;
+
+  default:
+    Type = L"?";
+    break;
+  }
+
+  CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
+  DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
+  if (DataLength > 0) {
+    CatPrint (Str, L",");
+    for (Index = 0; Index < DataLength; Index++) {
+      CatPrint (Str, L"%02x", (UINTN) ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+    }
+  }
+  CatPrint (Str, L")");
+}
+
+
+VOID
+DevPathAcpi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  Acpi = DevPath;
+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+    CatPrint (Str, L"Acpi(PNP%04x,%x)", (UINTN)  EISA_ID_TO_NUM (Acpi->HID), (UINTN) Acpi->UID);
+  } else {
+    CatPrint (Str, L"Acpi(%08x,%x)", (UINTN) Acpi->HID, (UINTN) Acpi->UID);
+  }
+}
+
+VOID
+DevPathExtendedAcpi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ACPI_EXTENDED_HID_DEVICE_PATH   *ExtendedAcpi;
+  //
+  // Index for HID, UID and CID strings, 0 for non-exist
+  //
+  UINT16                          HIDSTRIdx;
+  UINT16                          UIDSTRIdx;
+  UINT16                          CIDSTRIdx;
+  UINT16                          Index;
+  UINT16                          Length;
+  UINT16                          Anchor;
+  CHAR8                           *AsChar8Array;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  HIDSTRIdx    = 0;
+  UIDSTRIdx    = 0;
+  CIDSTRIdx    = 0;
+  ExtendedAcpi = DevPath;
+  Length       = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) ExtendedAcpi);
+
+  ASSERT (Length >= 19);
+  AsChar8Array = (CHAR8 *) ExtendedAcpi;
+
+  //
+  // find HIDSTR
+  //
+  Anchor = 16;
+  for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
+    ;
+  }
+  if (Index > Anchor) {
+    HIDSTRIdx = Anchor;
+  }
+  //
+  // find UIDSTR
+  //
+  Anchor = (UINT16) (Index + 1);
+  for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
+    ;
+  }
+  if (Index > Anchor) {
+    UIDSTRIdx = Anchor;
+  }
+  //
+  // find CIDSTR
+  //
+  Anchor = (UINT16) (Index + 1);
+  for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
+    ;
+  }
+  if (Index > Anchor) {
+    CIDSTRIdx = Anchor;
+  }
+
+  if (HIDSTRIdx == 0 && CIDSTRIdx == 0 && ExtendedAcpi->UID == 0) {
+    CatPrint (Str, L"AcpiExp(");
+    if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+      CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
+    } else {
+      CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
+    }
+    if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+      CatPrint (Str, L"PNP%04x,", (UINTN)  EISA_ID_TO_NUM (ExtendedAcpi->CID));
+    } else {
+      CatPrint (Str, L"%08x,", (UINTN)  ExtendedAcpi->CID);
+    }
+    if (UIDSTRIdx != 0) {
+      CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
+    } else {
+      CatPrint (Str, L"\"\")");
+    }
+  } else {
+    CatPrint (Str, L"AcpiEx(");
+    if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+      CatPrint (Str, L"PNP%04x,", (UINTN)  EISA_ID_TO_NUM (ExtendedAcpi->HID));
+    } else {
+      CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
+    }
+    if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+      CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
+    } else {
+      CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
+    }
+    CatPrint (Str, L"%x,", (UINTN) ExtendedAcpi->UID);
+
+    if (HIDSTRIdx != 0) {
+      CatPrint (Str, L"%a,", AsChar8Array + HIDSTRIdx);
+    } else {
+      CatPrint (Str, L"\"\",");
+    }
+    if (CIDSTRIdx != 0) {
+      CatPrint (Str, L"%a,", AsChar8Array + CIDSTRIdx);
+    } else {
+      CatPrint (Str, L"\"\",");
+    }
+    if (UIDSTRIdx != 0) {
+      CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
+    } else {
+      CatPrint (Str, L"\"\")");
+    }
+  }
+
+}
+
+VOID
+DevPathAdrAcpi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ACPI_ADR_DEVICE_PATH    *AcpiAdr;
+  UINT16                  Index;
+  UINT16                  Length;
+  UINT16                  AdditionalAdrCount;
+
+  AcpiAdr            = DevPath;
+  Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
+  AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
+
+  CatPrint (Str, L"AcpiAdr(%x", (UINTN) AcpiAdr->ADR);
+  for (Index = 0; Index < AdditionalAdrCount; Index++) {
+    CatPrint (Str, L",%x", (UINTN) *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
+  }
+  CatPrint (Str, L")");
+}
+
+VOID
+DevPathAtapi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ATAPI_DEVICE_PATH *Atapi;
+
+  Atapi = DevPath;
+  CatPrint (
+    Str,
+    L"Ata(%s,%s)",
+    Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
+    Atapi->SlaveMaster ? L"Slave" : L"Master"
+    );
+}
+
+VOID
+DevPathScsi (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  SCSI_DEVICE_PATH  *Scsi;
+
+  Scsi = DevPath;
+  CatPrint (Str, L"Scsi(Pun%x,Lun%x)", (UINTN) Scsi->Pun, (UINTN) Scsi->Lun);
+}
+
+VOID
+DevPathFibre (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  Fibre = DevPath;
+  CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);
+}
+
+VOID
+DevPath1394 (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  F1394_DEVICE_PATH *F1394;
+
+  F1394 = DevPath;
+  CatPrint (Str, L"1394(%g)", &F1394->Guid);
+}
+
+VOID
+DevPathUsb (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  USB_DEVICE_PATH *Usb;
+
+  Usb = DevPath;
+  CatPrint (Str, L"Usb(%x,%x)", (UINTN) Usb->ParentPortNumber, (UINTN) Usb->InterfaceNumber);
+}
+
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+VOID
+DevPathUsbWWID (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  USB_WWID_DEVICE_PATH  *UsbWWId;
+
+  UsbWWId = DevPath;
+  CatPrint (
+    Str,
+    L"UsbWwid(%x,%x,%x,\"WWID\")",
+    (UINTN) UsbWWId->VendorId,
+    (UINTN) UsbWWId->ProductId,
+    (UINTN) UsbWWId->InterfaceNumber
+    );
+}
+
+VOID
+DevPathLogicalUnit (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+  LogicalUnit = DevPath;
+  CatPrint (Str, L"Unit(%x)", (UINTN) LogicalUnit->Lun);
+}
+#endif
+
+VOID
+DevPathUsbClass (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  USB_CLASS_DEVICE_PATH *UsbClass;
+
+  UsbClass = DevPath;
+  CatPrint (
+    Str,
+    L"Usb Class(%x,%x,%x,%x,%x)",
+    (UINTN) UsbClass->VendorId,
+    (UINTN) UsbClass->ProductId,
+    (UINTN) UsbClass->DeviceClass,
+    (UINTN) UsbClass->DeviceSubClass,
+    (UINTN) UsbClass->DeviceProtocol
+    );
+}
+
+VOID
+DevPathSata (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  SATA_DEVICE_PATH *Sata;
+
+  Sata = DevPath;
+  CatPrint (
+    Str,
+    L"Sata(%x,%x,%x)",
+    (UINTN) Sata->HBAPortNumber,
+    (UINTN) Sata->PortMultiplierPortNumber,
+    (UINTN) Sata->Lun
+    );
+}
+
+VOID
+DevPathI2O (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  I2O_DEVICE_PATH *I2O;
+
+  I2O = DevPath;
+  CatPrint (Str, L"I2O(%x)", (UINTN) I2O->Tid);
+}
+
+VOID
+DevPathMacAddr (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MAC_ADDR_DEVICE_PATH  *MAC;
+  UINTN                 HwAddressSize;
+  UINTN                 Index;
+
+  MAC           = DevPath;
+
+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+  if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+    HwAddressSize = 6;
+  }
+
+  CatPrint (Str, L"Mac(");
+
+  for (Index = 0; Index < HwAddressSize; Index++) {
+    CatPrint (Str, L"%02x", (UINTN) MAC->MacAddress.Addr[Index]);
+  }
+
+  CatPrint (Str, L")");
+}
+
+VOID
+DevPathIPv4 (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  IPv4_DEVICE_PATH  *IP;
+
+  IP = DevPath;
+  CatPrint (
+    Str,
+    L"IPv4(%d.%d.%d.%d:%d)",
+    (UINTN) IP->RemoteIpAddress.Addr[0],
+    (UINTN) IP->RemoteIpAddress.Addr[1],
+    (UINTN) IP->RemoteIpAddress.Addr[2],
+    (UINTN) IP->RemoteIpAddress.Addr[3],
+    (UINTN) IP->RemotePort
+    );
+}
+
+VOID
+DevPathIPv6 (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  IPv6_DEVICE_PATH  *IP;
+
+  IP = DevPath;
+  CatPrint (
+    Str,
+    L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+    (UINTN) IP->RemoteIpAddress.Addr[0],
+    (UINTN) IP->RemoteIpAddress.Addr[1],
+    (UINTN) IP->RemoteIpAddress.Addr[2],
+    (UINTN) IP->RemoteIpAddress.Addr[3],
+    (UINTN) IP->RemoteIpAddress.Addr[4],
+    (UINTN) IP->RemoteIpAddress.Addr[5],
+    (UINTN) IP->RemoteIpAddress.Addr[6],
+    (UINTN) IP->RemoteIpAddress.Addr[7],
+    (UINTN) IP->RemoteIpAddress.Addr[8],
+    (UINTN) IP->RemoteIpAddress.Addr[9],
+    (UINTN) IP->RemoteIpAddress.Addr[10],
+    (UINTN) IP->RemoteIpAddress.Addr[11],
+    (UINTN) IP->RemoteIpAddress.Addr[12],
+    (UINTN) IP->RemoteIpAddress.Addr[13],
+    (UINTN) IP->RemoteIpAddress.Addr[14],
+    (UINTN) IP->RemoteIpAddress.Addr[15]
+    );
+}
+
+VOID
+DevPathInfiniBand (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  INFINIBAND_DEVICE_PATH  *InfiniBand;
+
+  InfiniBand = DevPath;
+  CatPrint (
+    Str,
+    L"Infiniband(%x,%g,%lx,%lx,%lx)",
+    (UINTN) InfiniBand->ResourceFlags,
+    InfiniBand->PortGid,
+    InfiniBand->ServiceId,
+    InfiniBand->TargetPortId,
+    InfiniBand->DeviceId
+    );
+}
+
+VOID
+DevPathUart (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  UART_DEVICE_PATH  *Uart;
+  CHAR8             Parity;
+
+  Uart = DevPath;
+  switch (Uart->Parity) {
+  case 0:
+    Parity = 'D';
+    break;
+
+  case 1:
+    Parity = 'N';
+    break;
+
+  case 2:
+    Parity = 'E';
+    break;
+
+  case 3:
+    Parity = 'O';
+    break;
+
+  case 4:
+    Parity = 'M';
+    break;
+
+  case 5:
+    Parity = 'S';
+    break;
+
+  default:
+    Parity = 'x';
+    break;
+  }
+
+  if (Uart->BaudRate == 0) {
+    CatPrint (Str, L"Uart(DEFAULT,%c,", Parity);
+  } else {
+    CatPrint (Str, L"Uart(%d,%c,", Uart->BaudRate, Parity);
+  }
+
+  if (Uart->DataBits == 0) {
+    CatPrint (Str, L"D,");
+  } else {
+    CatPrint (Str, L"%d,", (UINTN) Uart->DataBits);
+  }
+
+  switch (Uart->StopBits) {
+  case 0:
+    CatPrint (Str, L"D)");
+    break;
+
+  case 1:
+    CatPrint (Str, L"1)");
+    break;
+
+  case 2:
+    CatPrint (Str, L"1.5)");
+    break;
+
+  case 3:
+    CatPrint (Str, L"2)");
+    break;
+
+  default:
+    CatPrint (Str, L"x)");
+    break;
+  }
+}
+
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+VOID
+DevPathiSCSI (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+  UINT16                      Options;
+
+  ASSERT (Str != NULL);
+  ASSERT (DevPath != NULL);
+
+  iSCSI = DevPath;
+  CatPrint (
+    Str,
+    L"iSCSI(%s,%x,%lx,",
+    iSCSI->iSCSITargetName,
+    iSCSI->TargetPortalGroupTag,
+    iSCSI->Lun
+    );
+
+  Options = iSCSI->LoginOption;
+  CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");
+  CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");
+  if ((Options >> 11) & 0x0001) {
+    CatPrint (Str, L"%s,", L"None");
+  } else if ((Options >> 12) & 0x0001) {
+    CatPrint (Str, L"%s,", L"CHAP_UNI");
+  } else {
+    CatPrint (Str, L"%s,", L"CHAP_BI");
+
+  }
+
+  CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");
+}
+#endif
+
+VOID
+DevPathHardDrive (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  HARDDRIVE_DEVICE_PATH *Hd;
+
+  Hd = DevPath;
+  switch (Hd->SignatureType) {
+  case SIGNATURE_TYPE_MBR:
+    CatPrint (
+      Str,
+      L"HD(Part%d,Sig%08x)",
+      (UINTN) Hd->PartitionNumber,
+      (UINTN) *((UINT32 *) (&(Hd->Signature[0])))
+      );
+    break;
+
+  case SIGNATURE_TYPE_GUID:
+    CatPrint (
+      Str,
+      L"HD(Part%d,Sig%g)",
+      (UINTN) Hd->PartitionNumber,
+      (EFI_GUID *) &(Hd->Signature[0])
+      );
+    break;
+
+  default:
+    CatPrint (
+      Str,
+      L"HD(Part%d,MBRType=%02x,SigType=%02x)",
+      (UINTN) Hd->PartitionNumber,
+      (UINTN) Hd->MBRType,
+      (UINTN) Hd->SignatureType
+      );
+    break;
+  }
+}
+
+VOID
+DevPathCDROM (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  CDROM_DEVICE_PATH *Cd;
+
+  Cd = DevPath;
+  CatPrint (Str, L"CDROM(Entry%x)", (UINTN) Cd->BootEntry);
+}
+
+VOID
+DevPathFilePath (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  FILEPATH_DEVICE_PATH  *Fp;
+
+  Fp = DevPath;
+  CatPrint (Str, L"%s", Fp->PathName);
+}
+
+VOID
+DevPathMediaProtocol (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;
+
+  MediaProt = DevPath;
+  CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
+}
+
+VOID
+DevPathFvFilePath (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
+
+  FvFilePath = DevPath;
+  CatPrint (Str, L"%g", &FvFilePath->FvFileName);
+}
+
+VOID
+DevPathBssBss (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  BBS_BBS_DEVICE_PATH *Bbs;
+  CHAR16              *Type;
+
+  Bbs = DevPath;
+  switch (Bbs->DeviceType) {
+  case BBS_TYPE_FLOPPY:
+    Type = L"Floppy";
+    break;
+
+  case BBS_TYPE_HARDDRIVE:
+    Type = L"Harddrive";
+    break;
+
+  case BBS_TYPE_CDROM:
+    Type = L"CDROM";
+    break;
+
+  case BBS_TYPE_PCMCIA:
+    Type = L"PCMCIA";
+    break;
+
+  case BBS_TYPE_USB:
+    Type = L"Usb";
+    break;
+
+  case BBS_TYPE_EMBEDDED_NETWORK:
+    Type = L"Net";
+    break;
+
+  case BBS_TYPE_BEV:
+    Type = L"BEV";
+    break;
+
+  default:
+    Type = L"?";
+    break;
+  }
+  CatPrint (Str, L"Legacy-%s", Type);
+}
+
+VOID
+DevPathEndInstance (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  CatPrint (Str, L",");
+}
+
+VOID
+DevPathNodeUnknown (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath
+  )
+{
+  CatPrint (Str, L"?");
+}
+
+DEVICE_PATH_STRING_TABLE  DevPathTable[] = {
+  HARDWARE_DEVICE_PATH,
+  HW_PCI_DP,
+  DevPathPci,
+  HARDWARE_DEVICE_PATH,
+  HW_PCCARD_DP,
+  DevPathPccard,
+  HARDWARE_DEVICE_PATH,
+  HW_MEMMAP_DP,
+  DevPathMemMap,
+  HARDWARE_DEVICE_PATH,
+  HW_VENDOR_DP,
+  DevPathVendor,
+  HARDWARE_DEVICE_PATH,
+  HW_CONTROLLER_DP,
+  DevPathController,
+  ACPI_DEVICE_PATH,
+  ACPI_DP,
+  DevPathAcpi,
+  ACPI_DEVICE_PATH,
+  ACPI_EXTENDED_DP,
+  DevPathExtendedAcpi,
+  ACPI_DEVICE_PATH,
+  ACPI_ADR_DP,
+  DevPathAdrAcpi,
+  MESSAGING_DEVICE_PATH,
+  MSG_ATAPI_DP,
+  DevPathAtapi,
+  MESSAGING_DEVICE_PATH,
+  MSG_SCSI_DP,
+  DevPathScsi,
+  MESSAGING_DEVICE_PATH,
+  MSG_FIBRECHANNEL_DP,
+  DevPathFibre,
+  MESSAGING_DEVICE_PATH,
+  MSG_1394_DP,
+  DevPath1394,
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_DP,
+  DevPathUsb,
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_WWID_DP,
+  DevPathUsbWWID,
+  MESSAGING_DEVICE_PATH,
+  MSG_DEVICE_LOGICAL_UNIT_DP,
+  DevPathLogicalUnit,
+#endif
+  MESSAGING_DEVICE_PATH,
+  MSG_USB_CLASS_DP,
+  DevPathUsbClass,
+  MESSAGING_DEVICE_PATH,
+  MSG_SATA_DP,
+  DevPathSata,
+  MESSAGING_DEVICE_PATH,
+  MSG_I2O_DP,
+  DevPathI2O,
+  MESSAGING_DEVICE_PATH,
+  MSG_MAC_ADDR_DP,
+  DevPathMacAddr,
+  MESSAGING_DEVICE_PATH,
+  MSG_IPv4_DP,
+  DevPathIPv4,
+  MESSAGING_DEVICE_PATH,
+  MSG_IPv6_DP,
+  DevPathIPv6,
+  MESSAGING_DEVICE_PATH,
+  MSG_INFINIBAND_DP,
+  DevPathInfiniBand,
+  MESSAGING_DEVICE_PATH,
+  MSG_UART_DP,
+  DevPathUart,
+  MESSAGING_DEVICE_PATH,
+  MSG_VENDOR_DP,
+  DevPathVendor,
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+  MESSAGING_DEVICE_PATH,
+  MSG_ISCSI_DP,
+  DevPathiSCSI,
+#endif
+  MEDIA_DEVICE_PATH,
+  MEDIA_HARDDRIVE_DP,
+  DevPathHardDrive,
+  MEDIA_DEVICE_PATH,
+  MEDIA_CDROM_DP,
+  DevPathCDROM,
+  MEDIA_DEVICE_PATH,
+  MEDIA_VENDOR_DP,
+  DevPathVendor,
+  MEDIA_DEVICE_PATH,
+  MEDIA_FILEPATH_DP,
+  DevPathFilePath,
+  MEDIA_DEVICE_PATH,
+  MEDIA_PROTOCOL_DP,
+  DevPathMediaProtocol,
+#if (EFI_SPECIFICATION_VERSION != 0x00020000)
+  MEDIA_DEVICE_PATH,
+  MEDIA_PIWG_FW_FILE_DP,
+  DevPathFvFilePath,
+#endif
+  BBS_DEVICE_PATH,
+  BBS_BBS_DP,
+  DevPathBssBss,
+  END_DEVICE_PATH_TYPE,
+  END_INSTANCE_DEVICE_PATH_SUBTYPE,
+  DevPathEndInstance,
+  0,
+  0,
+  NULL
+};
+
+
+/**
+
+**/
+CHAR16 *
+DevicePathToStr (
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
+  )
+{
+  POOL_PRINT                Str;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;
+  VOID (*DumpNode) (POOL_PRINT *, VOID *);
+
+  UINTN Index;
+  UINTN NewSize;
+
+  EFI_STATUS                       Status;
+  CHAR16                           *ToText;
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
+
+  ZeroMem (&Str, sizeof (Str));
+
+  if (DevPath == NULL) {
+    goto Done;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiDevicePathToTextProtocolGuid,
+                  NULL,
+                  (VOID **) &DevPathToText
+                  );
+  if (!EFI_ERROR (Status)) {
+    ToText = DevPathToText->ConvertDevicePathToText (
+                              DevPath,
+                              FALSE,
+                              TRUE
+                              );
+    ASSERT (ToText != NULL);
+    return ToText;
+  }
+
+  //
+  // Unpacked the device path
+  //
+  DevPath = BdsLibUnpackDevicePath (DevPath);
+  ASSERT (DevPath);
+
+  //
+  // Process each device path node
+  //
+  DevPathNode = DevPath;
+  while (!IsDevicePathEnd (DevPathNode)) {
+    //
+    // Find the handler to dump this device path node
+    //
+    DumpNode = NULL;
+    for (Index = 0; DevPathTable[Index].Function; Index += 1) {
+
+      if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&
+          DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType
+          ) {
+        DumpNode = DevPathTable[Index].Function;
+        break;
+      }
+    }
+    //
+    // If not found, use a generic function
+    //
+    if (!DumpNode) {
+      DumpNode = DevPathNodeUnknown;
+    }
+    //
+    //  Put a path seperator in if needed
+    //
+    if (Str.len && DumpNode != DevPathEndInstance) {
+      CatPrint (&Str, L"/");
+    }
+    //
+    // Print this node of the device path
+    //
+    DumpNode (&Str, DevPathNode);
+
+    //
+    // Next device path node
+    //
+    DevPathNode = NextDevicePathNode (DevPathNode);
+  }
+  //
+  // Shrink pool used for string allocation
+  //
+  gBS->FreePool (DevPath);
+
+Done:
+  NewSize = (Str.len + 1) * sizeof (CHAR16);
+  Str.str = ReallocatePool (Str.str, NewSize, NewSize);
+  ASSERT (Str.str != NULL);
+  Str.str[Str.len] = 0;
+  return Str.str;
+}
+
+
+/**
+  Function creates a device path data structure that identically matches the
+  device path passed in.
+
+  @param  DevPath  A pointer to a device path data structure.
+
+  @return The new copy of DevPath is created to identically match the input.
+  @return Otherwise, NULL is returned.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+LibDuplicateDevicePathInstance (
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevPath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
+  EFI_DEVICE_PATH_PROTOCOL  *Temp;
+  UINTN                     Size;
+
+  //
+  // get the size of an instance from the input
+  //
+  Temp            = DevPath;
+  DevicePathInst  = GetNextDevicePathInstance (&Temp, &Size);
+
+  //
+  // Make a copy
+  //
+  NewDevPath = NULL;
+  if (Size) {
+    NewDevPath = AllocateZeroPool (Size);
+    ASSERT (NewDevPath != NULL);
+  }
+
+  if (NewDevPath) {
+    CopyMem (NewDevPath, DevicePathInst, Size);
+  }
+
+  return NewDevPath;
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/Ebc/BmMachine.h b/edk2/MdeModulePkg/Library/GenericBdsLib/Ebc/BmMachine.h
new file mode 100644 (file)
index 0000000..dc4d728
--- /dev/null
@@ -0,0 +1,35 @@
+/** @file
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BmMachine.h
+
+Abstract:
+
+  Boot Manager Machine type
+
+
+
+Revision History
+
+
+**/
+
+#ifndef _BM_MACHINE_H
+#define _BM_MACHINE_H
+
+//
+// NOTE: This is not defined in UEFI spec.
+//
+#define DEFAULT_REMOVABLE_FILE_NAME L"\\EFI\\BOOT\\BOOTEBC.EFI"
+
+#endif
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf b/edk2/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
new file mode 100644 (file)
index 0000000..ebaed91
--- /dev/null
@@ -0,0 +1,119 @@
+#/** @file\r
+# Component name for module GenericBdsLib\r
+#\r
+# FIX ME!\r
+# Copyright (c) 2007, Intel Corporation. All rights reserved.\r
+#\r
+#  All rights reserved. This program and the accompanying materials       \r
+#  are licensed and made available under the terms and conditions of the BSD License   \r
+#  which accompanies this distribution. The full text of the license may be found at  \r
+#  http://opensource.org/licenses/bsd-license.php           \r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,      \r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = GenericBdsLib\r
+  FILE_GUID                      = e405ec31-ccaa-4dd4-83e8-0aec01703f7e\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = GenericBdsLib|DXE_DRIVER   \r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x0002000A\r
+\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  DevicePath.c\r
+  Performance.c\r
+  BdsConnect.c\r
+  BdsMisc.c\r
+  R8Lib.c\r
+  BdsConsole.c\r
+  BdsBoot.c\r
+  InternalBdsLib.h\r
+  R8Lib.h\r
+\r
+[Sources.Ia32]\r
+  Ia32\ClearDr.asm\r
+  Ia32\BmMachine.h\r
+\r
+[Sources.X64]\r
+  x64\ClearDr.asm\r
+  x64\BmMachine.h\r
+\r
+[Sources.IPF]\r
+  Ipf\ShadowRom.c\r
+  Ipf\BmMachine.h\r
+\r
+[Sources.EBC]\r
+  Ebc\BmMachine.h\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  #\r
+  #This dependency is because of gEfiLegacyBiosProtocolGuid. It may be removed if a Library class is created to\r
+  #abstract away definition in Framework specification or PI spec incorporates the Legacy Booting Protocols.\r
+  #\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  DevicePathLib\r
+  PeCoffGetEntryPointLib\r
+  BaseLib\r
+  HobLib\r
+  UefiRuntimeServicesTableLib\r
+  DxeServicesTableLib\r
+  MemoryAllocationLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  PrintLib\r
+  PcdLib\r
+  PerformanceLib\r
+  TimerLib\r
+\r
+\r
+[Guids]\r
+  gEfiVT100PlusGuid                             # ALWAYS_CONSUMED\r
+  gEfiMemoryTypeInformationGuid                 # ALWAYS_CONSUMED\r
+  gEfiVTUTF8Guid                                # ALWAYS_CONSUMED\r
+  gEfiHobListGuid                               # ALWAYS_CONSUMED\r
+  gEfiShellFileGuid                             # ALWAYS_CONSUMED\r
+  gEfiGlobalVariableGuid                        # ALWAYS_CONSUMED\r
+  gEfiVT100Guid                                 # ALWAYS_CONSUMED\r
+  gEfiFileInfoGuid                              # ALWAYS_CONSUMED\r
+  gEfiPcAnsiGuid                                # ALWAYS_CONSUMED\r
+  gEfiGenericPlatformVariableGuid               # ALWAYS_CONSUMED\r
+\r
+\r
+[Protocols]\r
+  gEfiSimpleFileSystemProtocolGuid              # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiSimpleTextOutProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiPciIoProtocolGuid                         # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDevicePathToTextProtocolGuid              # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiSimpleNetworkProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDebugPortProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiSimpleTextInProtocolGuid                  # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiBlockIoProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiFirmwareVolume2ProtocolGuid                # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiLegacyBiosProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiCpuArchProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPlatformBootTimeOutDefault
\ No newline at end of file
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.msa b/edk2/MdeModulePkg/Library/GenericBdsLib/GenericBdsLib.msa
new file mode 100644 (file)
index 0000000..076d7b9
--- /dev/null
@@ -0,0 +1,159 @@
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>GenericBdsLib</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>e405ec31-ccaa-4dd4-83e8-0aec01703f7e</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component name for module GenericBdsLib</Abstract>\r
+    <Description>FIX ME!</Description>\r
+    <Copyright>Copyright (c) 2007, Intel Corporation. All rights reserved.</Copyright>\r
+    <License>All rights reserved. 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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>GenericBdsLib</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PrintLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DxeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>HobLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DevicePathLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename SupArchList="IPF">Ipf\BmMachine.h</Filename>\r
+    <Filename>R8Lib.h</Filename>\r
+    <Filename SupArchList="X64">x64\BmMachine.h</Filename>\r
+    <Filename>BdsLib.h</Filename>\r
+    <Filename>BdsBoot.c</Filename>\r
+    <Filename SupArchList="IA32">Ia32\BmMachine.h</Filename>\r
+    <Filename SupArchList="X64">x64\ClearDr.asm</Filename>\r
+    <Filename SupArchList="EBC">Ebc\BmMachine.h</Filename>\r
+    <Filename>BdsConsole.c</Filename>\r
+    <Filename>R8Lib.c</Filename>\r
+    <Filename SupArchList="IA32">Ia32\ClearDr.asm</Filename>\r
+    <Filename>BdsMisc.c</Filename>\r
+    <Filename>BdsConnect.c</Filename>\r
+    <Filename>Performance.c</Filename>\r
+    <Filename>DevicePath.c</Filename>\r
+    <Filename SupArchList="IPF">Ipf\ShadowRom.c</Filename>\r
+    <Filename>Performance.h</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiCpuArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiLegacyBiosProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiFirmwareVolumeProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiBlockIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSimpleTextInProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDebugPortProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSimpleNetworkProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiFormBrowserProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDevicePathToTextProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSimpleTextOutProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSimpleFileSystemProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Guids>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiPcAnsiGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiFileInfoGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiVT100Guid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiGlobalVariableGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiShellFileGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiHobListGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiVTUTF8Guid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiMemoryTypeInformationGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiVT100PlusGuid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/Ia32/BmMachine.h b/edk2/MdeModulePkg/Library/GenericBdsLib/Ia32/BmMachine.h
new file mode 100644 (file)
index 0000000..e0b1fca
--- /dev/null
@@ -0,0 +1,34 @@
+/** @file
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BmMachine.h
+
+Abstract:
+
+  Boot Manager Machine type
+
+
+
+Revision History
+
+
+**/
+
+#ifndef _BM_MACHINE_H
+#define _BM_MACHINE_H
+
+//@MT:#include "CpuIA32.h"
+
+#define DEFAULT_REMOVABLE_FILE_NAME L"\\EFI\\BOOT\\BOOTIA32.EFI"
+
+#endif
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/Ia32/ClearDr.asm b/edk2/MdeModulePkg/Library/GenericBdsLib/Ia32/ClearDr.asm
new file mode 100644 (file)
index 0000000..c4c1665
--- /dev/null
@@ -0,0 +1,43 @@
+  title   ClearDr.asm
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2004, Intel Corporation                                                         
+; All rights reserved. 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.             
+; 
+; Module Name:
+;
+;   ClearDr.asm
+; 
+; Abstract:
+; 
+;   Clear dr0 dr1 register
+;
+;------------------------------------------------------------------------------
+
+  .686
+  .MODEL FLAT,C
+  .CODE
+
+;------------------------------------------------------------------------------
+;  VOID
+;  ClearDebugRegisters (
+;    VOID
+;    )
+;------------------------------------------------------------------------------
+ClearDebugRegisters PROC    PUBLIC
+    push   eax
+    xor    eax, eax
+    mov    dr0, eax
+    mov    dr1, eax
+    pop    eax
+    ret
+ClearDebugRegisters ENDP
+
+END
+
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h b/edk2/MdeModulePkg/Library/GenericBdsLib/InternalBdsLib.h
new file mode 100644 (file)
index 0000000..cae57b9
--- /dev/null
@@ -0,0 +1,102 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  InternalBdsLib.h
+
+Abstract:
+
+  BDS library definition, include the file and data structure
+
+
+**/
+
+#ifndef _INTERNAL_BDS_LIB_H_
+#define _INTERNAL_BDS_LIB_H_
+
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci22.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/DebugPort.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/Performance.h>
+
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/FileInfo.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/PcAnsi.h>
+#include <Guid/ShellFile.h>
+#include <Guid/HobList.h>
+#include <Guid/GenericPlatformVariable.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/DxeServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IfrSupportLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/TimerLib.h>
+
+#include "BmMachine.h"
+
+#include "R8Lib.h"
+
+#define PERFORMANCE_SIGNATURE   EFI_SIGNATURE_32 ('P', 'e', 'r', 'f')
+#define PERF_TOKEN_SIZE         28
+#define PERF_TOKEN_LENGTH       (PERF_TOKEN_SIZE - 1)
+#define PERF_PEI_ENTRY_MAX_NUM  50
+
+typedef struct {
+  CHAR8   Token[PERF_TOKEN_SIZE];
+  UINT32  Duration;
+} PERF_DATA;
+
+typedef struct {
+  UINT64        BootToOs;
+  UINT64        S3Resume;
+  UINT32        S3EntryNum;
+  PERF_DATA     S3Entry[PERF_PEI_ENTRY_MAX_NUM];
+  UINT64        CpuFreq;
+  UINT64        BDSRaw;
+  UINT32        Count;
+  UINT32        Signiture;
+} PERF_HEADER;
+
+VOID
+WriteBootToOsPerformanceData (
+  VOID
+  );
+
+#endif // _BDS_LIB_H_
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/Ipf/BmMachine.h b/edk2/MdeModulePkg/Library/GenericBdsLib/Ipf/BmMachine.h
new file mode 100644 (file)
index 0000000..e9afc8a
--- /dev/null
@@ -0,0 +1,34 @@
+/** @file
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BmMachine.h
+
+Abstract:
+
+  Boot Manager Machine type
+
+
+
+Revision History
+
+
+**/
+
+#ifndef _BM_MACHINE_H
+#define _BM_MACHINE_H
+
+//@MT:#include "CpuIA64.h"
+
+#define DEFAULT_REMOVABLE_FILE_NAME L"\\EFI\\BOOT\\BOOTIA64.EFI"
+
+#endif
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/Ipf/ShadowRom.c b/edk2/MdeModulePkg/Library/GenericBdsLib/Ipf/ShadowRom.c
new file mode 100644 (file)
index 0000000..b1bec9d
--- /dev/null
@@ -0,0 +1,56 @@
+/** @file
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  ShadowRom.c
+
+Abstract:
+
+  Shadow all option rom
+
+Revision History
+
+
+**/
+
+//@MT:#include "Tiano.h"
+//@MT:#include "EfiDriverLib.h"
+
+//@MT:#include EFI_PROTOCOL_DEFINITION (LegacyBios)
+
+#include "InternalBdsLib.h"
+
+UINT8 mShadowRomFlag = 0;
+
+VOID
+ShadowAllOptionRom()
+{
+  EFI_STATUS                Status;
+  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
+  //
+  // Rom shadow only do once.
+  //
+  if (mShadowRomFlag == 0) {
+    Status = gBS->LocateProtocol (
+                    &gEfiLegacyBiosProtocolGuid,
+                    NULL,
+                    (VOID **) &LegacyBios
+                    );
+    if (!EFI_ERROR (Status)) {
+      LegacyBios->PrepareToBootEfi (LegacyBios, NULL, NULL);
+    }
+
+    mShadowRomFlag = 1;
+  }
+
+  return ;
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/Performance.c b/edk2/MdeModulePkg/Library/GenericBdsLib/Performance.c
new file mode 100644 (file)
index 0000000..0a42428
--- /dev/null
@@ -0,0 +1,326 @@
+/** @file
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  Performance.c
+
+Abstract:
+
+  This file include the file which can help to get the system
+  performance, all the function will only include if the performance
+  switch is set.
+
+
+**/
+
+#include "InternalBdsLib.h"
+
+STATIC PERF_HEADER               mPerfHeader;
+STATIC PERF_DATA                 mPerfData;
+
+STATIC
+VOID
+GetShortPdbFileName (
+  CHAR8  *PdbFileName,
+  CHAR8  *GaugeString
+  )
+/*++
+
+Routine Description:
+  
+Arguments:
+
+Returns:
+
+--*/
+{
+  UINTN Index;
+  UINTN Index1;
+  UINTN StartIndex;
+  UINTN EndIndex;
+
+  if (PdbFileName == NULL) {
+    AsciiStrCpy (GaugeString, " ");
+  } else {
+    StartIndex = 0;
+    for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
+      ;
+
+    for (Index = 0; PdbFileName[Index] != 0; Index++) {
+      if (PdbFileName[Index] == '\\') {
+        StartIndex = Index + 1;
+      }
+
+      if (PdbFileName[Index] == '.') {
+        EndIndex = Index;
+      }
+    }
+
+    Index1 = 0;
+    for (Index = StartIndex; Index < EndIndex; Index++) {
+      GaugeString[Index1] = PdbFileName[Index];
+      Index1++;
+      if (Index1 == PERF_TOKEN_LENGTH - 1) {
+        break;
+      }
+    }
+
+    GaugeString[Index1] = 0;
+  }
+
+  return ;
+}
+
+STATIC
+VOID
+GetNameFromHandle (
+  IN  EFI_HANDLE     Handle,
+  OUT CHAR8          *GaugeString
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_LOADED_IMAGE_PROTOCOL   *Image;
+  CHAR8                       *PdbFileName;
+  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+
+  AsciiStrCpy (GaugeString, " ");
+
+  //
+  // Get handle name from image protocol
+  //
+  Status = gBS->HandleProtocol (
+                  Handle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **) &Image
+                  );
+
+  if (EFI_ERROR (Status)) {
+    Status = gBS->OpenProtocol (
+                    Handle,
+                    &gEfiDriverBindingProtocolGuid,
+                    (VOID **) &DriverBinding,
+                    NULL,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return ;
+    }
+    //
+    // Get handle name from image protocol
+    //
+    Status = gBS->HandleProtocol (
+                    DriverBinding->ImageHandle,
+                    &gEfiLoadedImageProtocolGuid,
+                    (VOID **) &Image
+                    );
+  }
+
+  PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);
+
+  if (PdbFileName != NULL) {
+    GetShortPdbFileName (PdbFileName, GaugeString);
+  }
+
+  return ;
+}
+
+VOID
+WriteBootToOsPerformanceData (
+  VOID
+  )
+/*++
+
+Routine Description:
+  
+  Allocates a block of memory and writes performance data of booting to OS into it.
+
+Arguments:
+  
+  None
+  
+Returns:
+
+  None
+
+--*/
+{
+  EFI_STATUS                Status;
+  EFI_PHYSICAL_ADDRESS      AcpiLowMemoryBase;
+  UINT32                    AcpiLowMemoryLength;
+  UINT32                    LimitCount;
+  EFI_HANDLE                *Handles;
+  UINTN                     NoHandles;
+  CHAR8                     GaugeString[PERF_TOKEN_LENGTH];
+  UINT8                     *Ptr;
+  UINT32                    Index;
+  UINT64                    Ticker;
+  UINT64                    Freq;
+  UINT32                    Duration;
+  UINTN                     LogEntryKey;
+  CONST VOID                *Handle;
+  CONST CHAR8               *Token;
+  CONST CHAR8               *Module;
+  UINT64                    StartTicker;
+  UINT64                    EndTicker;
+  UINT64                    StartValue;
+  UINT64                    EndValue;
+  BOOLEAN                   CountUp;
+
+  //
+  // Retrive time stamp count as early as possilbe
+  //
+  Ticker  = GetPerformanceCounter ();
+
+  Freq    = GetPerformanceCounterProperties (&StartValue, &EndValue);
+  
+  Freq    = DivU64x32 (Freq, 1000);
+
+  mPerfHeader.CpuFreq = Freq;
+
+  //
+  // Record BDS raw performance data
+  //
+  if (EndValue >= StartValue) {
+    mPerfHeader.BDSRaw = Ticker - StartValue;
+    CountUp            = TRUE;
+  } else {
+    mPerfHeader.BDSRaw = StartValue - Ticker;
+    CountUp            = FALSE;
+  }
+
+  AcpiLowMemoryLength   = 0x2000;
+
+  //
+  // Allocate a block of memory that contain performance data to OS
+  //
+  Status = gBS->AllocatePages (
+                  AllocateAnyPages,
+                  EfiACPIReclaimMemory,
+                  EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),
+                  &AcpiLowMemoryBase
+                  );
+  if (EFI_ERROR (Status)) {
+    return ;
+  }
+
+
+  Ptr                   = (UINT8 *) ((UINT32) AcpiLowMemoryBase + sizeof (PERF_HEADER));
+  LimitCount            = (AcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
+
+  //
+  // Put Detailed performance data into memory
+  //
+  Handles = NULL;
+  Status = gBS->LocateHandleBuffer (
+                  AllHandles,
+                  NULL,
+                  NULL,
+                  &NoHandles,
+                  &Handles
+                  );
+  if (EFI_ERROR (Status)) {
+    gBS->FreePages (AcpiLowMemoryBase, 1);
+    return ;
+  }
+  //
+  // Get DXE drivers performance
+  //
+  for (Index = 0; Index < NoHandles; Index++) {
+    Ticker = 0;
+    LogEntryKey = 0;
+    while ((LogEntryKey = GetPerformanceMeasurement (
+                            LogEntryKey,
+                            &Handle,
+                            &Token,
+                            &Module,
+                            &StartTicker,
+                            &EndTicker)) != 0) {
+      if ((Handle == Handles[Index]) && (EndTicker != 0)) {
+        Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
+      }
+    }
+
+    Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
+
+    if (Duration > 0) {
+
+      GetNameFromHandle (Handles[Index], GaugeString);
+
+      AsciiStrCpy (mPerfData.Token, GaugeString);
+      mPerfData.Duration = Duration;
+
+      CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
+      Ptr += sizeof (PERF_DATA);
+
+      mPerfHeader.Count++;
+      if (mPerfHeader.Count == LimitCount) {
+        goto Done;
+      }
+    }
+  }
+
+  FreePool (Handles);
+
+  //
+  // Get inserted performance data
+  //
+  LogEntryKey = 0;
+  while ((LogEntryKey = GetPerformanceMeasurement (
+                          LogEntryKey,
+                          &Handle,
+                          &Token,
+                          &Module,
+                          &StartTicker,
+                          &EndTicker)) != 0) {
+    if (Handle == NULL && EndTicker != 0) {
+
+      ZeroMem (&mPerfData, sizeof (PERF_DATA));
+
+      AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);
+      Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
+
+      mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
+
+      CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
+      Ptr += sizeof (PERF_DATA);
+
+      mPerfHeader.Count++;
+      if (mPerfHeader.Count == LimitCount) {
+        goto Done;
+      }
+    }
+  }
+
+Done:
+
+  mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
+
+  //
+  // Put performance data to memory
+  //
+  CopyMem (
+    (UINTN *) (UINTN) AcpiLowMemoryBase,
+    &mPerfHeader,
+    sizeof (PERF_HEADER)
+    );
+
+  gRT->SetVariable (
+        L"PerfDataMemAddr",
+        &gEfiGenericPlatformVariableGuid,
+        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+        sizeof (EFI_PHYSICAL_ADDRESS),
+        &AcpiLowMemoryBase
+        );
+
+  return ;
+}
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/R8Lib.c b/edk2/MdeModulePkg/Library/GenericBdsLib/R8Lib.c
new file mode 100644 (file)
index 0000000..537dc12
--- /dev/null
@@ -0,0 +1,114 @@
+/**@file
+  Copyright (c) 2007, Intel Corporation
+
+  All rights reserved. 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 "InternalBdsLib.h"
+
+/**
+  Get current boot mode.
+
+  @param  HobStart               Start pointer of hob list
+  @param  BootMode               Current boot mode recorded in PHIT hob
+
+  @retval EFI_NOT_FOUND          Invalid hob header
+  @retval EFI_SUCCESS            Boot mode found
+
+**/
+EFI_STATUS
+R8_GetHobBootMode (
+  IN  VOID           *HobStart,
+  OUT EFI_BOOT_MODE  *BootMode
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  // In fact, since EFI_HANDOFF_HOB must be the first Hob,
+  // the following code can retrieve boot mode.
+  //
+  // EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+  //
+  // HandOffHob = GetHobList ();
+  // ASSERT (HandOffHob->Header.HobType == EFI_HOB_TYPE_HANDOFF);
+  //
+  // BootMode = HandOffHob->BootMode;
+  //
+  EFI_PEI_HOB_POINTERS  Hob;
+
+  Hob.Raw = HobStart;
+  if (Hob.Header->HobType != EFI_HOB_TYPE_HANDOFF) {
+    return EFI_NOT_FOUND;
+  }
+
+  *BootMode = Hob.HandoffInformationTable->BootMode;
+  return EFI_SUCCESS;
+}
+
+
+
+
+/**
+  Get the next guid hob.
+
+  @param  HobStart               A pointer to the start hob.
+  @param  Guid                   A pointer to a guid.
+  @param  Buffer                 A pointer to the buffer.
+  @param  BufferSize             Buffer size.
+
+  @retval EFI_NOT_FOUND          Next Guid hob not found
+  @retval EFI_SUCCESS            Next Guid hob found and data for this Guid got
+  @retval EFI_INVALID_PARAMETER  invalid parameter
+
+**/
+EFI_STATUS
+R8_GetNextGuidHob (
+  IN OUT VOID      **HobStart,
+  IN     EFI_GUID  * Guid,
+  OUT    VOID      **Buffer,
+  OUT    UINTN     *BufferSize OPTIONAL
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is changed substantially with R9 counerpart GetNextGuidHob ().
+  // 1. R9 GetNextGuidHob has two parameters and returns the matched GUID HOB from the StartHob.
+  // 2. R9 GetNextGuidHob does not strip the HOB header, so caller is required to apply
+  //    GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE () to extract the data section and its
+  //    size info respectively.
+  // 3. this function does not skip the starting HOB pointer unconditionally:
+  //    it returns HobStart back if HobStart itself meets the requirement;
+  //    caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+  //
+  EFI_PEI_HOB_POINTERS  GuidHob;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GuidHob.Raw = GetNextGuidHob (Guid, *HobStart);
+  if (GuidHob.Raw == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  *Buffer = GET_GUID_HOB_DATA (GuidHob.Guid);
+  if (BufferSize != NULL) {
+    *BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob.Guid);
+  }
+
+  *HobStart = GET_NEXT_HOB (GuidHob);
+
+  return EFI_SUCCESS;
+}
+
+
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/R8Lib.h b/edk2/MdeModulePkg/Library/GenericBdsLib/R8Lib.h
new file mode 100644 (file)
index 0000000..f62de99
--- /dev/null
@@ -0,0 +1,59 @@
+/**@file
+  Copyright (c) 2007, Intel Corporation
+
+  All rights reserved. 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.
+
+
+**/
+
+
+
+/**
+  Get current boot mode.
+
+  @param  HobStart               Start pointer of hob list
+  @param  BootMode               Current boot mode recorded in PHIT hob
+
+  @retval EFI_NOT_FOUND          Invalid hob header
+  @retval EFI_SUCCESS            Boot mode found
+
+**/
+EFI_STATUS
+R8_GetHobBootMode (
+  IN  VOID           *HobStart,
+  OUT EFI_BOOT_MODE  *BootMode
+  )
+;
+
+
+
+
+/**
+  Get the next guid hob.
+
+  @param  HobStart               A pointer to the start hob.
+  @param  Guid                   A pointer to a guid.
+  @param  Buffer                 A pointer to the buffer.
+  @param  BufferSize             Buffer size.
+
+  @retval EFI_NOT_FOUND          Next Guid hob not found
+  @retval EFI_SUCCESS            Next Guid hob found and data for this Guid got
+  @retval EFI_INVALID_PARAMETER  invalid parameter
+
+**/
+EFI_STATUS
+R8_GetNextGuidHob (
+  IN OUT VOID      **HobStart,
+  IN     EFI_GUID  * Guid,
+  OUT    VOID      **Buffer,
+  OUT    UINTN     *BufferSize OPTIONAL
+  )
+;
+
+
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/x64/BmMachine.h b/edk2/MdeModulePkg/Library/GenericBdsLib/x64/BmMachine.h
new file mode 100644 (file)
index 0000000..a646371
--- /dev/null
@@ -0,0 +1,34 @@
+/** @file
+
+Copyright (c) 2005 - 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  BmMachine.h
+
+Abstract:
+
+  Boot Manager Machine type
+
+
+
+Revision History
+
+
+**/
+
+#ifndef _BM_MACHINE_H
+#define _BM_MACHINE_H
+
+//@MT:#include "CpuIA32.h"
+
+#define DEFAULT_REMOVABLE_FILE_NAME L"\\EFI\\BOOT\\BOOTX64.EFI"
+
+#endif
diff --git a/edk2/MdeModulePkg/Library/GenericBdsLib/x64/ClearDr.asm b/edk2/MdeModulePkg/Library/GenericBdsLib/x64/ClearDr.asm
new file mode 100644 (file)
index 0000000..83d198d
--- /dev/null
@@ -0,0 +1,41 @@
+  title   ClearDr.asm
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2005, Intel Corporation                                                         
+; All rights reserved. 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.             
+; 
+; Module Name:
+;
+;   ClearDr.asm
+; 
+; Abstract:
+; 
+;   Clear dr0 dr1 register
+;
+;------------------------------------------------------------------------------
+
+text SEGMENT
+
+;------------------------------------------------------------------------------
+;  VOID
+;  ClearDebugRegisters (
+;    VOID
+;    )
+;------------------------------------------------------------------------------
+ClearDebugRegisters PROC    PUBLIC
+    push   rax
+    xor    rax, rax
+    mov    dr0, rax
+    mov    dr1, rax
+    pop    rax
+    ret
+ClearDebugRegisters ENDP
+
+END
+
diff --git a/edk2/MdeModulePkg/Library/GraphicsLib/Graphics.c b/edk2/MdeModulePkg/Library/GraphicsLib/Graphics.c
new file mode 100644 (file)
index 0000000..10b144c
--- /dev/null
@@ -0,0 +1,892 @@
+/**@file\r
+  Support for Basic Graphics operations.\r
+\r
+  BugBug: Currently *.BMP files are supported. This will be replaced\r
+          when Tiano graphics format is supported.\r
+\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/SimpleTextOut.h>\r
+#include <Protocol/OEMBadging.h>\r
+#include <Protocol/ConsoleControl.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/UgaDraw.h>\r
+#include <Protocol/HiiFont.h>\r
+#include <Protocol/HiiImage.h>\r
+\r
+#include <Guid/Bmp.h>\r
+\r
+#include <Library/GraphicsLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DxePiLib.h>\r
+\r
+STATIC EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {\r
+  { 0x00, 0x00, 0x00, 0x00 },\r
+  { 0x98, 0x00, 0x00, 0x00 },\r
+  { 0x00, 0x98, 0x00, 0x00 },\r
+  { 0x98, 0x98, 0x00, 0x00 },\r
+  { 0x00, 0x00, 0x98, 0x00 },\r
+  { 0x98, 0x00, 0x98, 0x00 },\r
+  { 0x00, 0x98, 0x98, 0x00 },\r
+  { 0x98, 0x98, 0x98, 0x00 },\r
+  { 0x10, 0x10, 0x10, 0x00 },\r
+  { 0xff, 0x10, 0x10, 0x00 },\r
+  { 0x10, 0xff, 0x10, 0x00 },\r
+  { 0xff, 0xff, 0x10, 0x00 },\r
+  { 0x10, 0x10, 0xff, 0x00 },\r
+  { 0xf0, 0x10, 0xff, 0x00 },\r
+  { 0x10, 0xff, 0xff, 0x00 },\r
+  { 0xff, 0xff, 0xff, 0x00 }\r
+};\r
+\r
+\r
+EFI_STATUS\r
+GetGraphicsBitMapFromFV (\r
+  IN  EFI_GUID      *FileNameGuid,\r
+  OUT VOID          **Image,\r
+  OUT UINTN         *ImageSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the graphics image file named FileNameGuid into Image and return it's\r
+  size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
+  file name.\r
+\r
+Arguments:\r
+\r
+  FileNameGuid  - File Name of graphics file in the FV(s).\r
+\r
+  Image         - Pointer to pointer to return graphics image.  If NULL, a\r
+                  buffer will be allocated.\r
+\r
+  ImageSize     - Size of the graphics Image in bytes. Zero if no image found.\r
+\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS          - Image and ImageSize are valid.\r
+  EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
+  EFI_NOT_FOUND        - FileNameGuid not found\r
+\r
+--*/\r
+{\r
+  return GetGraphicsBitMapFromFVEx (NULL, FileNameGuid, Image, ImageSize);\r
+}\r
+\r
+EFI_STATUS\r
+GetGraphicsBitMapFromFVEx (\r
+  IN  EFI_HANDLE    ImageHandle,\r
+  IN  EFI_GUID      *FileNameGuid,\r
+  OUT VOID          **Image,\r
+  OUT UINTN         *ImageSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return the graphics image file named FileNameGuid into Image and return it's\r
+  size in ImageSize. All Firmware Volumes (FV) in the system are searched for the\r
+  file name.\r
+\r
+Arguments:\r
+\r
+  ImageHandle   - The driver image handle of the caller. The parameter is used to\r
+                  optimize the loading of the image file so that the FV from which\r
+                  the driver image is loaded will be tried first. \r
+\r
+  FileNameGuid  - File Name of graphics file in the FV(s).\r
+\r
+  Image         - Pointer to pointer to return graphics image.  If NULL, a \r
+                  buffer will be allocated.\r
+\r
+  ImageSize     - Size of the graphics Image in bytes. Zero if no image found.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS          - Image and ImageSize are valid. \r
+  EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size\r
+  EFI_NOT_FOUND        - FileNameGuid not found\r
+\r
+--*/\r
+{\r
+  return PiLibGetSectionFromCurrentFv (\r
+           FileNameGuid,\r
+           EFI_SECTION_RAW,\r
+           0,\r
+           Image,\r
+           ImageSize\r
+           );\r
+}\r
+\r
+\r
+EFI_STATUS\r
+ConvertBmpToGopBlt (\r
+  IN  VOID      *BmpImage,\r
+  IN  UINTN     BmpImageSize,\r
+  IN OUT VOID   **GopBlt,\r
+  IN OUT UINTN  *GopBltSize,\r
+  OUT UINTN     *PixelHeight,\r
+  OUT UINTN     *PixelWidth\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer\r
+  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt\r
+  buffer is passed in it will be used if it is big enough.\r
+\r
+Arguments:\r
+\r
+  BmpImage      - Pointer to BMP file\r
+\r
+  BmpImageSize  - Number of bytes in BmpImage\r
+\r
+  GopBlt        - Buffer containing GOP version of BmpImage.\r
+\r
+  GopBltSize    - Size of GopBlt in bytes.\r
+\r
+  PixelHeight   - Height of GopBlt/BmpImage in pixels\r
+\r
+  PixelWidth    - Width of GopBlt/BmpImage in pixels\r
+\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - GopBlt and GopBltSize are returned.\r
+  EFI_UNSUPPORTED       - BmpImage is not a valid *.BMP image\r
+  EFI_BUFFER_TOO_SMALL  - The passed in GopBlt buffer is not big enough.\r
+                          GopBltSize will contain the required size.\r
+  EFI_OUT_OF_RESOURCES  - No enough buffer to allocate\r
+\r
+--*/\r
+{\r
+  UINT8             *Image;\r
+  UINT8             *ImageHeader;\r
+  BMP_IMAGE_HEADER  *BmpHeader;\r
+  BMP_COLOR_MAP     *BmpColorMap;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+  UINTN             BltBufferSize;\r
+  UINTN             Index;\r
+  UINTN             Height;\r
+  UINTN             Width;\r
+  UINTN             ImageIndex;\r
+  BOOLEAN           IsAllocated;\r
+\r
+  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;\r
+  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (BmpHeader->CompressionType != 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Calculate Color Map offset in the image.\r
+  //\r
+  Image       = BmpImage;\r
+  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));\r
+\r
+  //\r
+  // Calculate graphics image data address in the image\r
+  //\r
+  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;\r
+  ImageHeader   = Image;\r
+\r
+  BltBufferSize = BmpHeader->PixelWidth * BmpHeader->PixelHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
+  IsAllocated   = FALSE;\r
+  if (*GopBlt == NULL) {\r
+    *GopBltSize = BltBufferSize;\r
+    *GopBlt     = AllocatePool (*GopBltSize);\r
+    IsAllocated = TRUE;\r
+    if (*GopBlt == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  } else {\r
+    if (*GopBltSize < BltBufferSize) {\r
+      *GopBltSize = BltBufferSize;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+  }\r
+\r
+  *PixelWidth   = BmpHeader->PixelWidth;\r
+  *PixelHeight  = BmpHeader->PixelHeight;\r
+\r
+  //\r
+  // Convert image from BMP to Blt buffer format\r
+  //\r
+  BltBuffer = *GopBlt;\r
+  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {\r
+    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];\r
+    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {\r
+      switch (BmpHeader->BitPerPixel) {\r
+      case 1:\r
+        //\r
+        // Convert 1bit BMP to 24-bit color\r
+        //\r
+        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {\r
+          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;\r
+          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;\r
+          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;\r
+          Blt++;\r
+          Width++;\r
+        }\r
+\r
+        Blt --;\r
+        Width --;\r
+        break;\r
+\r
+      case 4:\r
+        //\r
+        // Convert BMP Palette to 24-bit color\r
+        //\r
+        Index       = (*Image) >> 4;\r
+        Blt->Red    = BmpColorMap[Index].Red;\r
+        Blt->Green  = BmpColorMap[Index].Green;\r
+        Blt->Blue   = BmpColorMap[Index].Blue;\r
+        if (Width < (BmpHeader->PixelWidth - 1)) {\r
+          Blt++;\r
+          Width++;\r
+          Index       = (*Image) & 0x0f;\r
+          Blt->Red    = BmpColorMap[Index].Red;\r
+          Blt->Green  = BmpColorMap[Index].Green;\r
+          Blt->Blue   = BmpColorMap[Index].Blue;\r
+        }\r
+        break;\r
+\r
+      case 8:\r
+        //\r
+        // Convert BMP Palette to 24-bit color\r
+        //\r
+        Blt->Red    = BmpColorMap[*Image].Red;\r
+        Blt->Green  = BmpColorMap[*Image].Green;\r
+        Blt->Blue   = BmpColorMap[*Image].Blue;\r
+        break;\r
+\r
+      case 24:\r
+        Blt->Blue   = *Image++;\r
+        Blt->Green  = *Image++;\r
+        Blt->Red    = *Image;\r
+        break;\r
+\r
+      default:\r
+        if (IsAllocated) {\r
+          gBS->FreePool (*GopBlt);\r
+          *GopBlt = NULL;\r
+        }\r
+        return EFI_UNSUPPORTED;\r
+        break;\r
+      };\r
+\r
+    }\r
+\r
+    ImageIndex = (UINTN) (Image - ImageHeader);\r
+    if ((ImageIndex % 4) != 0) {\r
+      //\r
+      // Bmp Image starts each row on a 32-bit boundary!\r
+      //\r
+      Image = Image + (4 - (ImageIndex % 4));\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+LockKeyboards (\r
+  IN  CHAR16    *Password\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Use Console Control Protocol to lock the Console In Spliter virtual handle.\r
+  This is the ConInHandle and ConIn handle in the EFI system table. All key\r
+  presses will be ignored until the Password is typed in. The only way to\r
+  disable the password is to type it in to a ConIn device.\r
+\r
+Arguments:\r
+  Password - Password used to lock ConIn device\r
+\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS     - ConsoleControl has been flipped to graphics and logo\r
+                          displayed.\r
+  EFI_UNSUPPORTED - Logo not found\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = ConsoleControl->LockStdIn (ConsoleControl, Password);\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EnableQuietBoot (\r
+  IN  EFI_GUID  *LogoFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use Console Control to turn off UGA based Simple Text Out consoles from going\r
+  to the UGA device. Put up LogoFile on every UGA device that is a console\r
+\r
+Arguments:\r
+\r
+  LogoFile - File name of logo to display on the center of the screen.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo\r
+                          displayed.\r
+  EFI_UNSUPPORTED       - Logo not found\r
+\r
+--*/\r
+{\r
+  return EnableQuietBootEx (LogoFile, NULL);\r
+}\r
+\r
+EFI_STATUS\r
+EnableQuietBootEx (\r
+  IN  EFI_GUID    *LogoFile,\r
+  IN  EFI_HANDLE  ImageHandle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use Console Control to turn off GOP/UGA based Simple Text Out consoles from going\r
+  to the GOP/UGA device. Put up LogoFile on every GOP/UGA device that is a console\r
+\r
+Arguments:\r
+\r
+  LogoFile    - File name of logo to display on the center of the screen.\r
+  ImageHandle - The driver image handle of the caller. The parameter is used to\r
+                optimize the loading of the logo file so that the FV from which\r
+                the driver image is loaded will be tried first.\r
+\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS           - ConsoleControl has been flipped to graphics and logo\r
+                          displayed.\r
+  EFI_UNSUPPORTED       - Logo not found\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+  EFI_OEM_BADGING_PROTOCOL      *Badging;\r
+  UINT32                        SizeOfX;\r
+  UINT32                        SizeOfY;\r
+  INTN                          DestX;\r
+  INTN                          DestY;\r
+  UINT8                         *ImageData;\r
+  UINTN                         ImageSize;\r
+  UINTN                         BltSize;\r
+  UINT32                        Instance;\r
+  EFI_BADGING_FORMAT            Format;\r
+  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;\r
+  UINTN                         CoordinateX;\r
+  UINTN                         CoordinateY;\r
+  UINTN                         Height;\r
+  UINTN                         Width;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
+  UINT32                        ColorDepth;\r
+  UINT32                        RefreshRate;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  UgaDraw = NULL;\r
+  //\r
+  // Try to open GOP first\r
+  //\r
+  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput);\r
+  if (EFI_ERROR (Status)) {\r
+    GraphicsOutput = NULL;\r
+    //\r
+    // Open GOP failed, try to open UGA\r
+    //\r
+    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID**)&UgaDraw);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  Badging = NULL;\r
+  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID**)&Badging);\r
+\r
+  ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenGraphics);\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;\r
+  } else {\r
+    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+\r
+  Instance = 0;\r
+  while (1) {\r
+    ImageData = NULL;\r
+    ImageSize = 0;\r
+\r
+    if (Badging != NULL) {\r
+      Status = Badging->GetImage (\r
+                          Badging,\r
+                          &Instance,\r
+                          &Format,\r
+                          &ImageData,\r
+                          &ImageSize,\r
+                          &Attribute,\r
+                          &CoordinateX,\r
+                          &CoordinateY\r
+                          );\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Currently only support BMP format\r
+      //\r
+      if (Format != EfiBadgingFormatBMP) {\r
+        gBS->FreePool (ImageData);\r
+        continue;\r
+      }\r
+    } else {\r
+      Status = GetGraphicsBitMapFromFVEx (ImageHandle, LogoFile, (VOID **) &ImageData, &ImageSize);\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      CoordinateX = 0;\r
+      CoordinateY = 0;\r
+      Attribute   = EfiBadgingDisplayAttributeCenter;\r
+    }\r
+\r
+    Blt = NULL;\r
+    Status = ConvertBmpToGopBlt (\r
+              ImageData,\r
+              ImageSize,\r
+              (VOID**)&Blt,\r
+              &BltSize,\r
+              &Height,\r
+              &Width\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePool (ImageData);\r
+      if (Badging == NULL) {\r
+        return Status;\r
+      } else {\r
+        continue;\r
+      }\r
+    }\r
+\r
+    switch (Attribute) {\r
+    case EfiBadgingDisplayAttributeLeftTop:\r
+      DestX = CoordinateX;\r
+      DestY = CoordinateY;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterTop:\r
+      DestX = (SizeOfX - Width) / 2;\r
+      DestY = CoordinateY;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeRightTop:\r
+      DestX = (SizeOfX - Width - CoordinateX);\r
+      DestY = CoordinateY;;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterRight:\r
+      DestX = (SizeOfX - Width - CoordinateX);\r
+      DestY = (SizeOfY - Height) / 2;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeRightBottom:\r
+      DestX = (SizeOfX - Width - CoordinateX);\r
+      DestY = (SizeOfY - Height - CoordinateY);\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterBottom:\r
+      DestX = (SizeOfX - Width) / 2;\r
+      DestY = (SizeOfY - Height - CoordinateY);\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeLeftBottom:\r
+      DestX = CoordinateX;\r
+      DestY = (SizeOfY - Height - CoordinateY);\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenterLeft:\r
+      DestX = CoordinateX;\r
+      DestY = (SizeOfY - Height) / 2;\r
+      break;\r
+\r
+    case EfiBadgingDisplayAttributeCenter:\r
+      DestX = (SizeOfX - Width) / 2;\r
+      DestY = (SizeOfY - Height) / 2;\r
+      break;\r
+\r
+    default:\r
+      DestX = CoordinateX;\r
+      DestY = CoordinateY;\r
+      break;\r
+    }\r
+\r
+    if ((DestX >= 0) && (DestY >= 0)) {\r
+      if (GraphicsOutput != NULL) {\r
+        Status = GraphicsOutput->Blt (\r
+                            GraphicsOutput,\r
+                            Blt,\r
+                            EfiBltBufferToVideo,\r
+                            0,\r
+                            0,\r
+                            (UINTN) DestX,\r
+                            (UINTN) DestY,\r
+                            Width,\r
+                            Height,\r
+                            Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+                            );\r
+      } else {\r
+        Status = UgaDraw->Blt (\r
+                            UgaDraw,\r
+                            (EFI_UGA_PIXEL *) Blt,\r
+                            EfiUgaBltBufferToVideo,\r
+                            0,\r
+                            0,\r
+                            (UINTN) DestX,\r
+                            (UINTN) DestY,\r
+                            Width,\r
+                            Height,\r
+                            Width * sizeof (EFI_UGA_PIXEL)\r
+                            );\r
+      }\r
+    }\r
+\r
+    gBS->FreePool (ImageData);\r
+    gBS->FreePool (Blt);\r
+\r
+    if (Badging == NULL) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+DisableQuietBoot (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use Console Control to turn on GOP/UGA based Simple Text Out consoles. The GOP/UGA\r
+  Simple Text Out screens will now be synced up with all non GOP/UGA output devices\r
+\r
+Arguments:\r
+\r
+  NONE\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS           - GOP/UGA devices are back in text mode and synced up.\r
+  EFI_UNSUPPORTED       - Logo not found\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_CONSOLE_CONTROL_PROTOCOL  *ConsoleControl;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID **) &ConsoleControl);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);\r
+}\r
+\r
+UINTN\r
+_IPrint (\r
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL     *GraphicsOutput,\r
+  IN EFI_UGA_DRAW_PROTOCOL            *UgaDraw,\r
+  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL     *Sto,\r
+  IN UINTN                            X,\r
+  IN UINTN                            Y,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Foreground,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Background,\r
+  IN CHAR16                           *fmt,\r
+  IN VA_LIST                          args\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Display string worker for: Print, PrintAt, IPrint, IPrintAt\r
+\r
+Arguments:\r
+\r
+  GraphicsOutput  - Graphics output protocol interface\r
+\r
+  UgaDraw         - UGA draw protocol interface\r
+  \r
+  Sto             - Simple text out protocol interface\r
+  \r
+  X               - X coordinate to start printing\r
+  \r
+  Y               - Y coordinate to start printing\r
+  \r
+  Foreground      - Foreground color\r
+  \r
+  Background      - Background color\r
+  \r
+  fmt             - Format string\r
+  \r
+  args            - Print arguments\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS             -  success\r
+  EFI_OUT_OF_RESOURCES    -  out of resources\r
+\r
+--*/\r
+{\r
+  VOID                           *Buffer;\r
+  EFI_STATUS                     Status;\r
+  UINTN                          Index;\r
+  CHAR16                         *UnicodeWeight;\r
+  UINT32                         HorizontalResolution;\r
+  UINT32                         VerticalResolution;\r
+  UINT32                         ColorDepth;\r
+  UINT32                         RefreshRate;\r
+  UINTN                          BufferLen;\r
+  UINTN                          LineBufferLen;\r
+  EFI_HII_FONT_PROTOCOL          *HiiFont;\r
+  EFI_IMAGE_OUTPUT               *Blt;\r
+  EFI_FONT_DISPLAY_INFO          *FontInfo;  \r
+\r
+  //\r
+  // For now, allocate an arbitrarily long buffer\r
+  //\r
+  Buffer = AllocateZeroPool (0x10000);\r
+  if (Buffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (GraphicsOutput != NULL) {\r
+    HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;\r
+    VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;\r
+  } else {\r
+    UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);\r
+  }\r
+  ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0)); \r
+\r
+  Blt      = NULL;\r
+  FontInfo = NULL;\r
+  ASSERT (GraphicsOutput != NULL);\r
+  Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }  \r
+\r
+  UnicodeVSPrint (Buffer, 0x10000, fmt, args);\r
+  \r
+  UnicodeWeight = (CHAR16 *) Buffer;\r
+\r
+  for (Index = 0; UnicodeWeight[Index] != 0; Index++) {\r
+    if (UnicodeWeight[Index] == CHAR_BACKSPACE ||\r
+        UnicodeWeight[Index] == CHAR_LINEFEED  ||\r
+        UnicodeWeight[Index] == CHAR_CARRIAGE_RETURN) {\r
+      UnicodeWeight[Index] = 0;\r
+    }\r
+  }\r
+\r
+  BufferLen = StrLen (Buffer);\r
\r
+\r
+  LineBufferLen = sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * HorizontalResolution * EFI_GLYPH_HEIGHT;\r
+  if (EFI_GLYPH_WIDTH * EFI_GLYPH_HEIGHT * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * BufferLen > LineBufferLen) {\r
+     Status = EFI_INVALID_PARAMETER;\r
+     goto Error;\r
+  }\r
+\r
+  Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));\r
+  if (Blt == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Error;\r
+  }\r
+\r
+  Blt->Width        = (UINT16) (HorizontalResolution);\r
+  Blt->Height       = (UINT16) (VerticalResolution);\r
+  Blt->Image.Screen = GraphicsOutput;\r
+   \r
+  FontInfo = (EFI_FONT_DISPLAY_INFO *) AllocateZeroPool (sizeof (EFI_FONT_DISPLAY_INFO));\r
+  if (FontInfo == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Error;\r
+  }\r
+  if (Foreground != NULL) {\r
+    CopyMem (&FontInfo->ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+  } else {\r
+    CopyMem (\r
+      &FontInfo->ForegroundColor, \r
+      &mEfiColors[Sto->Mode->Attribute & 0x0f], \r
+      sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+      );\r
+  }\r
+  if (Background != NULL) {\r
+    CopyMem (&FontInfo->BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
+  } else {\r
+    CopyMem (\r
+      &FontInfo->BackgroundColor, \r
+      &mEfiColors[Sto->Mode->Attribute >> 4], \r
+      sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+      );\r
+  }\r
+\r
+  Status = HiiFont->StringToImage (\r
+                       HiiFont,\r
+                       EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_DIRECT_TO_SCREEN,\r
+                       Buffer,\r
+                       FontInfo,\r
+                       &Blt,\r
+                       X,\r
+                       Y,\r
+                       NULL,\r
+                       NULL,\r
+                       NULL\r
+                       );\r
+  \r
+\r
+Error:\r
+  SafeFreePool (Blt);\r
+  SafeFreePool (FontInfo);\r
+  gBS->FreePool (Buffer);\r
+  return Status;\r
+}\r
+\r
+UINTN\r
+PrintXY (\r
+  IN UINTN                            X,\r
+  IN UINTN                            Y,\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *ForeGround, OPTIONAL\r
+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *BackGround, OPTIONAL\r
+  IN CHAR16                           *Fmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+    Prints a formatted unicode string to the default console\r
+\r
+Arguments:\r
+\r
+    X           - X coordinate to start printing\r
+    \r
+    Y           - Y coordinate to start printing\r
+    \r
+    ForeGround  - Foreground color\r
+    \r
+    BackGround  - Background color\r
+\r
+    Fmt         - Format string\r
+\r
+    ...         - Print arguments\r
+\r
+Returns:\r
+\r
+    Length of string printed to the console\r
+\r
+--*/\r
+{\r
+  EFI_HANDLE                    Handle;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;\r
+  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;\r
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Sto;\r
+  EFI_STATUS                    Status;\r
+  VA_LIST                       Args;\r
+\r
+  VA_START (Args, Fmt);\r
+\r
+  Handle = gST->ConsoleOutHandle;\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  (VOID**)&GraphicsOutput\r
+                  );\r
+\r
+  UgaDraw = NULL;\r
+  if (EFI_ERROR (Status)) {\r
+    GraphicsOutput = NULL;\r
+\r
+    Status = gBS->HandleProtocol (\r
+                    Handle,\r
+                    &gEfiUgaDrawProtocolGuid,\r
+                    (VOID**)&UgaDraw\r
+                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEfiSimpleTextOutProtocolGuid,\r
+                  (VOID**)&Sto\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return _IPrint (GraphicsOutput, UgaDraw, Sto, X, Y, ForeGround, BackGround, Fmt, Args);\r
+}\r
+\r
diff --git a/edk2/MdeModulePkg/Library/GraphicsLib/GraphicsLib.inf b/edk2/MdeModulePkg/Library/GraphicsLib/GraphicsLib.inf
new file mode 100644 (file)
index 0000000..c7cb0af
--- /dev/null
@@ -0,0 +1,57 @@
+#/** @file\r
+# Graphics Library for UEFI drivers\r
+#\r
+# This library provides supports for basic graphic functions.\r
+# Copyright (c) 2006 - 2007, Intel Corporation.\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = EdkGraphicsLib\r
+  FILE_GUID                      = 08c1a0e4-1208-47f8-a2c5-f42eabee653a\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = GraphicsLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  Graphics.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  PrintLib\r
+  DebugLib\r
+  DxePiLib\r
+  BaseMemoryLib\r
+\r
+[Protocols]\r
+  gEfiSimpleTextOutProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiGraphicsOutputProtocolGuid                # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiUgaDrawProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiConsoleControlProtocolGuid                # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiFirmwareVolume2ProtocolGuid                # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiOEMBadgingProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiHiiFontProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED   
\ No newline at end of file
diff --git a/edk2/MdeModulePkg/Library/GraphicsLib/GraphicsLib.msa b/edk2/MdeModulePkg/Library/GraphicsLib/GraphicsLib.msa
new file mode 100644 (file)
index 0000000..2007ba0
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>EdkGraphicsLib</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>08c1a0e4-1208-47f8-a2c5-f42eabee653a</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Graphics Library for UEFI drivers</Abstract>\r
+    <Description>This library provides supports for basic graphic functions.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation.</Copyright>\r
+    <License>All rights reserved. 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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>EdkGraphicsLib</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_PRODUCED" SupModuleList="DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER">\r
+      <Keyword>EdkGraphicsLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PrintLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Graphics.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiOEMBadgingProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiFirmwareVolumeProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiConsoleControlProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiUgaDrawProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiGraphicsOutputProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiSimpleTextOutProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/edk2/MdeModulePkg/Library/IfrSupportLib/IfrSupportLib.inf b/edk2/MdeModulePkg/Library/IfrSupportLib/IfrSupportLib.inf
new file mode 100644 (file)
index 0000000..74b7c10
--- /dev/null
@@ -0,0 +1,71 @@
+#/** @file\r
+# Component name for module UefiEfiIfrSupportLib\r
+#\r
+# FIX ME!\r
+# Copyright (c) 2007, Intel Corporation. All rights reserved.\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = IfrSupportLib\r
+  FILE_GUID                      = bf38668e-e231-4baa-99e4-8c0e4c35dca6\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = IfrSupportLib\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  UefiIfrCommon.c\r
+  UefiIfrForm.c\r
+  UefiIfrLibraryInternal.h\r
+  UefiIfrOpCodeCreation.c\r
+  UefiIfrString.c\r
+  R8Lib.h\r
+  R8Lib.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  DevicePathLib\r
+  BaseLib\r
+  UefiBootServicesTableLib\r
+  UefiRuntimeServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  PcdLib\r
+\r
+[Guids]\r
+  gEfiGlobalVariableGuid                        # ALWAYS_CONSUMED\r
+\r
+[Protocols]\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiHiiDatabaseProtocolGuid\r
+  gEfiHiiStringProtocolGuid\r
+  gEfiHiiConfigRoutingProtocolGuid\r
+  gEfiFormBrowser2ProtocolGuid   \r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang
\ No newline at end of file
diff --git a/edk2/MdeModulePkg/Library/IfrSupportLib/IfrSupportLib.msa b/edk2/MdeModulePkg/Library/IfrSupportLib/IfrSupportLib.msa
new file mode 100644 (file)
index 0000000..dc9d665
--- /dev/null
@@ -0,0 +1,74 @@
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>UefiEfiIfrSupportLib</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>bf38668e-e231-4baa-99e4-8c0e4c35dca6</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component name for module UefiEfiIfrSupportLib</Abstract>\r
+    <Description>FIX ME!</Description>\r
+    <Copyright>Copyright (c) 2007, Intel Corporation. All rights reserved.</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      \r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>UefiEfiIfrSupportLib</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DevicePathLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>R8Lib.c</Filename>\r
+    <Filename>R8Lib.h</Filename>\r
+    <Filename>UefiIfrString.c</Filename>\r
+    <Filename>UefiIfrOpCodeCreation.c</Filename>\r
+    <Filename>UefiIfrLibraryInternal.h</Filename>\r
+    <Filename>UefiIfrForm.c</Filename>\r
+    <Filename>UefiIfrCommon.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Guids>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiGlobalVariableGuid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/edk2/MdeModulePkg/Library/IfrSupportLib/R8Lib.c b/edk2/MdeModulePkg/Library/IfrSupportLib/R8Lib.c
new file mode 100644 (file)
index 0000000..634bdb6
--- /dev/null
@@ -0,0 +1,241 @@
+/**@file
+  Copyright (c) 2007, Intel Corporation
+
+  All rights reserved. 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 "UefiIfrLibraryInternal.h"
+
+
+CHAR16
+InternalNibbleToHexChar (
+  IN UINT8      Nibble
+  )
+/*++
+
+  Routine Description:
+    Converts the low nibble of a byte  to hex unicode character.
+
+  Arguments:
+    Nibble - lower nibble of a byte.
+
+  Returns:
+    Hex unicode character.
+
+--*/
+{
+  Nibble &= 0x0F;
+  if (Nibble <= 0x9) {
+    return (CHAR16)(Nibble + L'0');
+  }
+
+  return (CHAR16)(Nibble - 0xA + L'A');
+}
+
+
+/**
+  Converts binary buffer to Unicode string.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Str                    Pointer to the string.
+  @param  HexStringBufferLength  Length in bytes of buffer to hold the hex string.
+                                 Includes tailing '\0' character. If routine return
+                                 with EFI_SUCCESS, containing length of hex string
+                                 buffer. If routine return with
+                                 EFI_BUFFER_TOO_SMALL, containg length of hex
+                                 string buffer desired.
+  @param  Buf                    Buffer to be converted from.
+  @param  Len                    Length in bytes of the buffer to be converted.
+
+  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_BUFFER_TOO_SMALL   The hex string buffer is too small.
+
+**/
+EFI_STATUS
+R8_BufToHexString (
+  IN OUT CHAR16                    *Str,
+  IN OUT UINTN                     *HexStringBufferLength,
+  IN     UINT8                     *Buf,
+  IN     UINTN                      Len
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  //
+  UINTN       Idx;
+  UINT8       Byte;
+  UINTN       StrLen;
+
+  //
+  // Make sure string is either passed or allocate enough.
+  // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+  // Plus the Unicode termination character.
+  //
+  StrLen = Len * 2;
+  if (StrLen > ((*HexStringBufferLength) - 1)) {
+    *HexStringBufferLength = StrLen + 1;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *HexStringBufferLength = StrLen + 1;
+  //
+  // Ends the string.
+  //
+  Str[StrLen] = L'\0';
+
+  for (Idx = 0; Idx < Len; Idx++) {
+
+    Byte = Buf[Idx];
+    Str[StrLen - 1 - Idx * 2] = InternalNibbleToHexChar (Byte);
+    Str[StrLen - 2 - Idx * 2] = InternalNibbleToHexChar ((UINT8)(Byte >> 4));
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+
+/**
+  Converts Unicode string to binary buffer.
+  The conversion may be partial.
+  The first character in the string that is not hex digit stops the conversion.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Buf                    Pointer to buffer that receives the data.
+  @param  Len                    Length in bytes of the buffer to hold converted
+                                 data. If routine return with EFI_SUCCESS,
+                                 containing length of converted data. If routine
+                                 return with EFI_BUFFER_TOO_SMALL, containg length
+                                 of buffer desired.
+  @param  Str                    String to be converted from.
+  @param  ConvertedStrLen        Length of the Hex String consumed.
+
+  @retval EFI_SUCCESS            Routine Success.
+  @retval EFI_BUFFER_TOO_SMALL   The buffer is too small to hold converted data.
+
+**/
+EFI_STATUS
+R8_HexStringToBuf (
+  IN OUT UINT8                     *Buf,
+  IN OUT UINTN                    *Len,
+  IN     CHAR16                    *Str,
+  OUT    UINTN                     *ConvertedStrLen  OPTIONAL
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  //
+
+  UINTN       HexCnt;
+  UINTN       Idx;
+  UINTN       BufferLength;
+  UINT8       Digit;
+  UINT8       Byte;
+
+  //
+  // Find out how many hex characters the string has.
+  //
+  for (Idx = 0, HexCnt = 0; R8_IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+  if (HexCnt == 0) {
+    *Len = 0;
+    return EFI_SUCCESS;
+  }
+  //
+  // Two Unicode characters make up 1 buffer byte. Round up.
+  //
+  BufferLength = (HexCnt + 1) / 2;
+
+  //
+  // Test if  buffer is passed enough.
+  //
+  if (BufferLength > (*Len)) {
+    *Len = BufferLength;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *Len = BufferLength;
+
+  for (Idx = 0; Idx < HexCnt; Idx++) {
+
+    R8_IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+    //
+    // For odd charaters, write the lower nibble for each buffer byte,
+    // and for even characters, the upper nibble.
+    //
+    if ((Idx & 1) == 0) {
+      Byte = Digit;
+    } else {
+      Byte = Buf[Idx / 2];
+      Byte &= 0x0F;
+      Byte = (UINT8) (Byte | Digit << 4);
+    }
+
+    Buf[Idx / 2] = Byte;
+  }
+
+  if (ConvertedStrLen != NULL) {
+    *ConvertedStrLen = HexCnt;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Determines if a Unicode character is a hexadecimal digit.
+  The test is case insensitive.
+
+  @param  Digit                  Pointer to byte that receives the value of the hex
+                                 character.
+  @param  Char                   Unicode character to test.
+
+  @retval TRUE                   If the character is a hexadecimal digit.
+  @retval FALSE                  Otherwise.
+
+**/
+BOOLEAN
+R8_IsHexDigit (
+  OUT UINT8      *Digit,
+  IN  CHAR16      Char
+  )
+{
+  //
+  // Porting Guide:
+  // This library interface is simply obsolete.
+  // Include the source code to user code.
+  //
+
+  if ((Char >= L'0') && (Char <= L'9')) {
+    *Digit = (UINT8) (Char - L'0');
+    return TRUE;
+  }
+
+  if ((Char >= L'A') && (Char <= L'F')) {
+    *Digit = (UINT8) (Char - L'A' + 0x0A);
+    return TRUE;
+  }
+
+  if ((Char >= L'a') && (Char <= L'f')) {
+    *Digit = (UINT8) (Char - L'a' + 0x0A);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
diff --git a/edk2/MdeModulePkg/Library/IfrSupportLib/R8Lib.h b/edk2/MdeModulePkg/Library/IfrSupportLib/R8Lib.h
new file mode 100644 (file)
index 0000000..ca9b939
--- /dev/null
@@ -0,0 +1,93 @@
+/**@file
+  Copyright (c) 2007, Intel Corporation
+
+  All rights reserved. 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.
+
+
+**/
+
+
+
+/**
+  Converts binary buffer to Unicode string.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Str                    Pointer to the string.
+  @param  HexStringBufferLength  Length in bytes of buffer to hold the hex string.
+                                 Includes tailing '\0' character. If routine return
+                                 with EFI_SUCCESS, containing length of hex string
+                                 buffer. If routine return with
+                                 EFI_BUFFER_TOO_SMALL, containg length of hex
+                                 string buffer desired.
+  @param  Buf                    Buffer to be converted from.
+  @param  Len                    Length in bytes of the buffer to be converted.
+
+  @retval EFI_SUCCESS            Routine success.
+  @retval EFI_BUFFER_TOO_SMALL   The hex string buffer is too small.
+
+**/
+EFI_STATUS
+R8_BufToHexString (
+  IN OUT CHAR16                    *Str,
+  IN OUT UINTN                     *HexStringBufferLength,
+  IN     UINT8                     *Buf,
+  IN     UINTN                      Len
+  )
+;
+
+
+
+
+/**
+  Converts Unicode string to binary buffer.
+  The conversion may be partial.
+  The first character in the string that is not hex digit stops the conversion.
+  At a minimum, any blob of data could be represented as a hex string.
+
+  @param  Buf                    Pointer to buffer that receives the data.
+  @param  Len                    Length in bytes of the buffer to hold converted
+                                 data. If routine return with EFI_SUCCESS,
+                                 containing length of converted data. If routine
+                                 return with EFI_BUFFER_TOO_SMALL, containg length
+                                 of buffer desired.
+  @param  Str                    String to be converted from.
+  @param  ConvertedStrLen        Length of the Hex String consumed.
+
+  @retval EFI_SUCCESS            Routine Success.
+  @retval EFI_BUFFER_TOO_SMALL   The buffer is too small to hold converted data.
+
+**/
+EFI_STATUS
+R8_HexStringToBuf (
+  IN OUT UINT8                     *Buf,
+  IN OUT UINTN                    *Len,
+  IN     CHAR16                    *Str,
+  OUT    UINTN                     *ConvertedStrLen  OPTIONAL
+  )
+;
+
+/**
+  Determines if a Unicode character is a hexadecimal digit.
+  The test is case insensitive.
+
+  @param  Digit                  Pointer to byte that receives the value of the hex
+                                 character.
+  @param  Char                   Unicode character to test.
+
+  @retval TRUE                   If the character is a hexadecimal digit.
+  @retval FALSE                  Otherwise.
+
+**/
+BOOLEAN
+R8_IsHexDigit (
+  OUT UINT8      *Digit,
+  IN  CHAR16      Char
+  )
+;
+
diff --git a/edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrCommon.c b/edk2/MdeModulePkg/Library/IfrSupportLib/UefiIfrCommon.c
new file mode 100644 (file)
index 0000000..b2b92d1
--- /dev/null
@@ -0,0 +1,369 @@
+/** @file
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+  UefiIfrCommon.c
+
+Abstract:
+
+  Common Library Routines to assist handle HII elements.
+
+
+**/
+
+#include "UefiIfrLibraryInternal.h"
+
+//
+// Hii relative protocols
+//
+BOOLEAN  mHiiProtocolsInitialized = FALSE;
+
+EFI_HII_DATABASE_PROTOCOL *gIfrLibHiiDatabase;
+EFI_HII_STRING_PROTOCOL   *gIfrLibHiiString;
+
+
+/**
+  This function locate Hii relative protocols for later usage.
+
+  None.
+
+  @return None.
+
+**/
+VOID
+LocateHiiProtocols (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  if (mHiiProtocolsInitialized) {
+    return;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gIfrLibHiiDatabase);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gIfrLibHiiString);
+  ASSERT_EFI_ERROR (Status);
+
+  mHiiProtocolsInitialized = TRUE;
+}
+
+
+/**
+  Assemble EFI_HII_PACKAGE_LIST according to the passed in packages.
+
+  @param  NumberOfPackages       Number of packages.
+  @param  GuidId                 Package GUID.
+
+  @return Pointer of EFI_HII_PACKAGE_LIST_HEADER.
+
+**/
+EFI_HII_PACKAGE_LIST_HEADER *
+PreparePackageList (
+  IN UINTN                    NumberOfPackages,
+  IN EFI_GUID                 *GuidId,
+  ...
+  )
+{
+  VA_LIST                     Marker;
+  EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader;
+  UINT8                       *PackageListData;
+  UINT32                      PackageListLength;
+  UINT32                      PackageLength;
+  EFI_HII_PACKAGE_HEADER      PackageHeader;
+  UINT8                       *PackageArray;
+  UINTN                       Index;
+
+  PackageListLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+  VA_START (Marker, GuidId);
+  for (Index = 0; Index < NumberOfPackages; Index++) {
+    CopyMem (&PackageLength, VA_ARG (Marker, VOID *), sizeof (UINT32));
+    PackageListLength += (PackageLength - sizeof (UINT32));
+  }
+  VA_END (Marker);
+
+  //
+  // Include the lenght of EFI_HII_PACKAGE_END
+  //
+  PackageListLength += sizeof (EFI_HII_PACKAGE_HEADER);
+  PackageListHeader = AllocateZeroPool (PackageListLength);
+  ASSERT (PackageListHeader != NULL);
+  CopyMem (&PackageListHeader->PackageListGuid, GuidId, sizeof (EFI_GUID));
+  PackageListHeader->PackageLength = PackageListLength;
+
+  PackageListData = ((UINT8 *) PackageListHeader) + sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+  VA_START (Marker, GuidId);
+  for (Index = 0; Index < NumberOfPackages; Index++) {
+    PackageArray = (UINT8 *) VA_ARG (Marker, VOID *);
+    CopyMem (&PackageLength, PackageArray, sizeof (UINT32));
+    PackageLength  -= sizeof (UINT32);
+    PackageArray += sizeof (UINT32);
+    CopyMem (PackageListData, PackageArray, PackageLength);
+    PackageListData += PackageLength;
+  }
+  VA_END (Marker);
+
+  //
+  // Append EFI_HII_PACKAGE_END
+  //
+  PackageHeader.Type = EFI_HII_PACKAGE_END;
+  PackageHeader.Length = sizeof (EFI_HII_PACKAGE_HEADER);
+  CopyMem (PackageListData, &PackageHeader, PackageHeader.Length);
+
+  return PackageListHeader;
+}
+
+
+/**
+  Find HII Handle associated with given Device Path.
+
+  @param  HiiDatabase            Point to EFI_HII_DATABASE_PROTOCOL instance.
+  @param  DevicePath             Device Path associated with the HII package list
+                                 handle.
+
+  @retval Handle                 HII package list Handle associated with the Device
+                                 Path.
+  @retval NULL                   Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+DevicePathToHiiHandle (
+  IN EFI_HII_DATABASE_PROTOCOL  *HiiDatabase,
+  IN EFI_DEVICE_PATH_PROTOCOL   *DevicePath
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_DEVICE_PATH_PROTOCOL    *TmpDevicePath;
+  UINTN                       BufferSize;
+  UINTN                       HandleCount;
+  UINTN                       Index;
+  EFI_HANDLE                  *Handles;
+  EFI_HANDLE                  Handle;
+  UINTN                       Size;
+  EFI_HANDLE                  DriverHandle;
+  EFI_HII_HANDLE              *HiiHandles;
+  EFI_HII_HANDLE              HiiHandle;
+
+  //
+  // Locate Device Path Protocol handle buffer
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiDevicePathProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &Handles
+                  );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  //
+  // Search Driver Handle by Device Path
+  //
+  DriverHandle = NULL;
+  BufferSize = GetDevicePathSize (DevicePath);
+  for(Index = 0; Index < HandleCount; Index++) {
+    Handle = Handles[Index];
+    gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **) &TmpDevicePath);
+
+    //
+    // Check whether DevicePath match
+    //
+    Size = GetDevicePathSize (TmpDevicePath);
+    if ((Size == BufferSize) && CompareMem (DevicePath, TmpDevicePath, Size) == 0) {
+      DriverHandle = Handle;
+      break;
+    }
+  }
+  gBS->FreePool (Handles);
+
+  if (DriverHandle == NULL) {
+    return NULL;
+  }
+
+  //
+  // Retrieve all Hii Handles from HII database
+  //
+  BufferSize = 0x1000;
+  HiiHandles = AllocatePool (BufferSize);
+  ASSERT (HiiHandles != NULL);
+  Status = HiiDatabase->ListPackageLists (
+                          HiiDatabase,
+                          EFI_HII_PACKAGE_TYPE_ALL,
+                          NULL,
+                          &BufferSize,
+                          HiiHandles
+                          );
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    gBS->FreePool (HiiHandles);
+    HiiHandles = AllocatePool (BufferSize);
+    ASSERT (HiiHandles != NULL);
+
+    Status = HiiDatabase->ListPackageLists (
+                            HiiDatabase,
+                            EFI_HII_PACKAGE_TYPE_ALL,
+                            NULL,
+                            &BufferSize,
+                            HiiHandles
+                            );
+  }
+
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (HiiHandles);
+    return NULL;
+  }
+
+  //
+  // Search Hii Handle by Driver Handle
+  //
+  HiiHandle = NULL;
+  HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = HiiDatabase->GetPackageListHandle (
+                            HiiDatabase,
+                            HiiHandles[Index],
+                            &Handle
+                            );