From 6e1e46c8a5f8b7abcd1e505ac92eb336ecad088d Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Wed, 31 May 2017 21:15:21 +0200
Subject: [PATCH] WIP efidp(8) etc.

---
 lib/libefivar/FreeBSD-update                       |   40 +
 lib/libefivar/Makefile                             |   18 +-
 lib/libefivar/ProcessorBind.h                      |    4 +
 lib/libefivar/efi-osdep.h                          |  111 +
 lib/libefivar/efivar-dp-format.c                   | 2427 ++++++
 lib/libefivar/efivar-dp-parse.c                    | 3715 ++++++++
 lib/libefivar/efivar-dp.h                          |   65 +
 lib/libefivar/efivar.3                             |    3 +-
 lib/libefivar/efivar.c                             |   44 +-
 lib/libefivar/efivar.h                             |   16 +-
 lib/libefivar/uefi-dplib.h                         |  635 ++
 lib/libefivar/uefi-dputil.c                        |  636 ++
 lib/libefivar/uefi-guid.c                          |   36 +
 lib/libefivar/uefi-guid.dat                        |   11 +
 .../boot/efi/include/efichar.h                     |   12 +-
 .../libefivar.c => sys/boot/efi/libefi/efichar.c   |   10 +-
 sys/contrib/edk2/Include/Base.h                    | 1270 +++
 .../edk2/Include/Guid/HiiFormMapMethodGuid.h       |   25 +
 sys/contrib/edk2/Include/Guid/WinCertificate.h     |  128 +
 sys/contrib/edk2/Include/Library/BaseLib.h         | 8910 ++++++++++++++++++++
 sys/contrib/edk2/Include/Library/BaseMemoryLib.h   |  489 ++
 sys/contrib/edk2/Include/Library/DebugLib.h        |  529 ++
 sys/contrib/edk2/Include/Library/DevicePathLib.h   |  566 ++
 .../edk2/Include/Library/MemoryAllocationLib.h     |  493 ++
 sys/contrib/edk2/Include/Library/PcdLib.h          | 2260 +++++
 sys/contrib/edk2/Include/Library/PrintLib.h        | 1051 +++
 .../Include/Library/UefiBootServicesTableLib.h     |   34 +
 sys/contrib/edk2/Include/Protocol/DebugPort.h      |  146 +
 sys/contrib/edk2/Include/Protocol/DevicePath.h     | 1331 +++
 .../edk2/Include/Protocol/DevicePathFromText.h     |   72 +
 .../edk2/Include/Protocol/DevicePathToText.h       |   85 +
 .../edk2/Include/Protocol/DevicePathUtilities.h    |  192 +
 sys/contrib/edk2/Include/Protocol/SimpleTextInEx.h |  325 +
 sys/contrib/edk2/Include/Uefi.h                    |   27 +
 sys/contrib/edk2/Include/Uefi/UefiBaseType.h       |  299 +
 sys/contrib/edk2/Include/Uefi/UefiGpt.h            |  141 +
 .../Include/Uefi/UefiInternalFormRepresentation.h  | 2135 +++++
 sys/contrib/edk2/Include/Uefi/UefiMultiPhase.h     |  231 +
 sys/contrib/edk2/Include/Uefi/UefiPxe.h            | 1792 ++++
 sys/contrib/edk2/Include/Uefi/UefiSpec.h           | 2194 +++++
 usr.sbin/Makefile                                  |    1 +
 usr.sbin/efidp/Makefile                            |    9 +
 usr.sbin/efidp/efidp.8                             |   56 +
 usr.sbin/efidp/efidp.c                             |  148 +
 usr.sbin/efivar/efivar.8                           |   64 +-
 usr.sbin/efivar/efivar.c                           |   81 +-
 46 files changed, 32795 insertions(+), 72 deletions(-)
 create mode 100644 lib/libefivar/FreeBSD-update
 create mode 100644 lib/libefivar/ProcessorBind.h
 create mode 100644 lib/libefivar/efi-osdep.h
 create mode 100644 lib/libefivar/efivar-dp-format.c
 create mode 100644 lib/libefivar/efivar-dp-parse.c
 create mode 100644 lib/libefivar/efivar-dp.h
 create mode 100644 lib/libefivar/uefi-dplib.h
 create mode 100644 lib/libefivar/uefi-dputil.c
 create mode 100644 lib/libefivar/uefi-guid.c
 create mode 100644 lib/libefivar/uefi-guid.dat
 rename lib/libefivar/libefivar_int.h => sys/boot/efi/include/efichar.h (83%)
 rename lib/libefivar/libefivar.c => sys/boot/efi/libefi/efichar.c (93%)
 create mode 100644 sys/contrib/edk2/Include/Base.h
 create mode 100644 sys/contrib/edk2/Include/Guid/HiiFormMapMethodGuid.h
 create mode 100644 sys/contrib/edk2/Include/Guid/WinCertificate.h
 create mode 100644 sys/contrib/edk2/Include/Library/BaseLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/BaseMemoryLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/DebugLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/DevicePathLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/MemoryAllocationLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/PcdLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/PrintLib.h
 create mode 100644 sys/contrib/edk2/Include/Library/UefiBootServicesTableLib.h
 create mode 100644 sys/contrib/edk2/Include/Protocol/DebugPort.h
 create mode 100644 sys/contrib/edk2/Include/Protocol/DevicePath.h
 create mode 100644 sys/contrib/edk2/Include/Protocol/DevicePathFromText.h
 create mode 100644 sys/contrib/edk2/Include/Protocol/DevicePathToText.h
 create mode 100644 sys/contrib/edk2/Include/Protocol/DevicePathUtilities.h
 create mode 100644 sys/contrib/edk2/Include/Protocol/SimpleTextInEx.h
 create mode 100644 sys/contrib/edk2/Include/Uefi.h
 create mode 100644 sys/contrib/edk2/Include/Uefi/UefiBaseType.h
 create mode 100644 sys/contrib/edk2/Include/Uefi/UefiGpt.h
 create mode 100644 sys/contrib/edk2/Include/Uefi/UefiInternalFormRepresentation.h
 create mode 100644 sys/contrib/edk2/Include/Uefi/UefiMultiPhase.h
 create mode 100644 sys/contrib/edk2/Include/Uefi/UefiPxe.h
 create mode 100644 sys/contrib/edk2/Include/Uefi/UefiSpec.h
 create mode 100644 usr.sbin/efidp/Makefile
 create mode 100644 usr.sbin/efidp/efidp.8
 create mode 100644 usr.sbin/efidp/efidp.c

diff --git a/lib/libefivar/FreeBSD-update b/lib/libefivar/FreeBSD-update
new file mode 100644
index 0000000000..1f513af40b
--- /dev/null
+++ b/lib/libefivar/FreeBSD-update
@@ -0,0 +1,40 @@
+$FreeBSD: head/lib/libefivar/FreeBSD-update 314926 2017-03-09 00:31:31Z imp $
+
+For the printing and parsing functionality, we use the Tianocore routines
+directly.
+
+efivar-dp-format.c is a copy of MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+efivar-dp-parse.c is a copy of MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+
+These files are first mechanically processed with
+
+sed -e "s/L'/'/g;"'s/L"/"/g;s/%g/%36s/g;s/%a/%s/g;s/^VOID/static VOID/g;s/ *$//g'
+
+for several reasons. We're moving from wide routines to narrow
+routines. The UTC-2 this code is written for is a bad match for
+wchar_t which is an int. It's a much better match for plain narrow
+characters on FreeBSD. So we pretend that CHAR16 for these files is
+really char * (ASCII).
+
+Next, we have have to convert the Unicode printf that this code
+expects to FreeBSD's printf. %g means "Print the GUID" and %a means
+"print the ASCII string." so we mechanically convert them. Once we've
+done that we can compare efivar-dp-*.c to its source to see what's
+changed. Because we go through this indirection, I've done that
+outside of svn. To upgrade you have to do these files by hand. You
+have to go through and make routines static.
+
+uefi-*.[ch] are internal routines to support this. They've been copied
+from EDK2 as well, but in a more haphazard manner. This was a trade
+off between ease of implementation / upgrade vs pulling in too much
+since less than half of any file was needed.
+
+efi-osdep.h shims the EDK2 types to FreeBSD's types. It's included by
+ProcessorBind.h which EDK2 uses to define the CPU. We keep it separate
+from uefi-dplib.h to allow better sharing.
+
+uefi-dplib.h shims the EDK2 routines that are needed to FreeBSD's
+routines. This is relatively easy since we map all the UCS-2 routines
+to simple char * routines.
+
+RESIST THE URGE TO CLEAN UP THESE FILES.
diff --git a/lib/libefivar/Makefile b/lib/libefivar/Makefile
index d4df2e5ba2..cc2f15e178 100644
--- a/lib/libefivar/Makefile
+++ b/lib/libefivar/Makefile
@@ -22,15 +22,25 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# $FreeBSD: head/lib/libefivar/Makefile 307071 2016-10-11 22:30:41Z imp $
+# $FreeBSD: head/lib/libefivar/Makefile 314926 2017-03-09 00:31:31Z imp $
+
+EFIBOOT=${.CURDIR}/../../sys/boot/efi
+EDK2INC=${.CURDIR}/../../sys/contrib/edk2/Include
+
+.PATH:	${EFIBOOT}/libefi
 
 PACKAGE=lib${LIB}
 LIB=		efivar
-SRCS=		efivar.c libefivar.c
-INCS=		efivar.h
+SRCS=		efivar.c efichar.c efivar-dp-format.c \
+		efivar-dp-parse.c \
+		uefi-guid.c uefi-dputil.c
+INCS=		efivar.h efivar-dp.h
 SHLIB_MAJOR=	1
 MAN=		efivar.3
 
+CFLAGS+=	-I${EFIBOOT}/include
+CFLAGS+=	-I${.CURDIR} -I${EDK2INC}
+
 MLINKS+=efivar.3 efi_variables_supported.3 \
 	efivar.3 efi_del_variable.3 \
 	efivar.3 efi_get_variable.3 \
@@ -46,4 +56,6 @@ MLINKS+=efivar.3 efi_variables_supported.3 \
 	efivar.3 efi_guid_to_symbol.3 \
 	efivar.3 libefivar.3
 
+WARNS?=		3
+
 .include <bsd.lib.mk>
diff --git a/lib/libefivar/ProcessorBind.h b/lib/libefivar/ProcessorBind.h
new file mode 100644
index 0000000000..9576ae2cf1
--- /dev/null
+++ b/lib/libefivar/ProcessorBind.h
@@ -0,0 +1,4 @@
+/* File in public domain */
+/* Brings in the glue for UEFI/EDK2 Tianocore code to run on this OS */
+/* $FreeBSD: head/lib/libefivar/ProcessorBind.h 314926 2017-03-09 00:31:31Z imp $ */
+#include "efi-osdep.h"
diff --git a/lib/libefivar/efi-osdep.h b/lib/libefivar/efi-osdep.h
new file mode 100644
index 0000000000..8f8d807d59
--- /dev/null
+++ b/lib/libefivar/efi-osdep.h
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/libefivar/efi-osdep.h 314926 2017-03-09 00:31:31Z imp $
+ */
+
+#ifndef	_EFI_OSDEP_H_
+#define	_EFI_OSDEP_H_
+
+/*
+ * Defines to adjust the types that EDK2 uses for FreeBSD so we can
+ * use the code and headers mostly unchanged. The headers are imported
+ * all into one directory to avoid case issues with filenames and
+ * included. The actual code is heavily modified since it has too many
+ * annoying dependencies that are difficult to satisfy.
+ */
+
+#include <sys/cdefs.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <uuid.h>
+
+typedef int8_t INT8;
+typedef int16_t INT16;
+typedef int32_t INT32;
+typedef int64_t INT64;
+typedef intptr_t INTN;
+typedef uint8_t UINT8;
+typedef uint16_t UINT16;
+typedef uint32_t UINT32;
+typedef uint64_t UINT64;
+typedef uintptr_t UINTN;
+//typedef uintptr_t EFI_PHYSICAL_ADDRESS;
+//typedef uint32_t EFI_IPv4_ADDRESS;
+//typedef uint8_t EFI_MAC_ADDRESS[6];
+//typedef uint8_t EFI_IPv6_ADDRESS[16];
+typedef uint8_t CHAR8;
+typedef uint16_t CHAR16;
+typedef UINT8 BOOLEAN;
+typedef void VOID;
+//typedef uuid_t GUID;
+//typedef uuid_t EFI_GUID;
+
+/* We can't actually call this stuff, so snip out API syntactic sugar */
+#define INTERFACE_DECL(x)
+#define EFIAPI
+#define IN
+#define OUT
+#define CONST const
+#define OPTIONAL
+//#define TRUE 1
+//#define FALSE 0
+
+/*
+ * EDK2 has fine definitions for these, so let it define them.
+ */
+#undef NULL
+#undef EFI_PAGE_SIZE
+#undef EFI_PAGE_MASK
+
+/*
+ * Note: the EDK2 code assumed #pragma packed works and PACKED is a
+ * workaround for some old toolchain issues for EDK2 that aren't
+ * relevent to FreeBSD.
+ */
+#define PACKED
+
+/*
+ * Since we're not compiling for the UEFI boot time (which use ms abi
+ * conventions), tell EDK2 to define VA_START correctly. For the boot
+ * loader, this likely needs to be different.
+ */
+#define NO_MSABI_VA_FUNCS 1
+
+/*
+ * Finally, we need to define the processor we are in EDK2 terms.
+ */
+#if defined(__i386__)
+#define MDE_CPU_IA32
+#elif defined(__amd64__)
+#define MDE_CPU_X64
+#elif defined(__arm__)
+#define MDE_CPU_ARM
+#elif defined(__aarch64__)
+#define MDE_CPU_AARCH64
+#endif
+/* FreeBSD doesn't have/use MDE_CPU_EBC or MDE_CPU_IPF (ia64) */
+
+#endif /* _EFI_OSDEP_H_ */
diff --git a/lib/libefivar/efivar-dp-format.c b/lib/libefivar/efivar-dp-format.c
new file mode 100644
index 0000000000..32e406564f
--- /dev/null
+++ b/lib/libefivar/efivar-dp-format.c
@@ -0,0 +1,2427 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
+ * this file is taken from EDK2 and rototilled.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/lib/libefivar/efivar-dp-format.c 314926 2017-03-09 00:31:31Z imp $");
+
+#include <efivar.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "efi-osdep.h"
+#include "efivar-dp.h"
+
+#include "uefi-dplib.h"
+
+/*
+ * This is a lie, but since we have converted everything
+ * from wide to narrow, it's the right lie now.
+ */
+#define UnicodeSPrint snprintf
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ * heavily modified:
+ *	wide strings converted to narrow
+ *	Low level printing code redone for narrow strings
+ *	Routines made static
+ *	%s -> %S in spots (where it is still UCS-2)
+ *	%a (ascii) -> %s
+ *	%g -> %36s hack to print guid (see above for caveat)
+ *	some tidying up of const and deconsting. It's evil, but const
+ *	  poisoning the whole file was too much.
+ */
+
+/** @file
+  DevicePathToText protocol as defined in the UEFI 2.0 specification.
+
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+// #include "UefiDevicePathLib.h"
+
+/**
+  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
+  @param ...             Variable arguments based on the format string.
+
+  @return Allocated buffer with the formatted string printed in it.
+          The caller must free the allocated buffer. The buffer
+          allocation is not packed.
+
+**/
+static char *
+EFIAPI
+UefiDevicePathLibCatPrint (
+  IN OUT POOL_PRINT   *Str,
+  IN const char       *Fmt,
+  ...
+  )
+{
+  UINTN   Count;
+  VA_LIST Args;
+
+  VA_START (Args, Fmt);
+  Count = vsnprintf(NULL, 0, Fmt, Args);
+  VA_END(Args);
+
+  if ((Str->Count + (Count + 1)) > Str->Capacity) {
+    Str->Capacity = (Str->Count + (Count + 1) * 2);
+    Str->Str = reallocf(Str->Str, Str->Capacity);
+    ASSERT (Str->Str != NULL);
+  }
+  VA_START (Args, Fmt);
+  vsnprintf(Str->Str + Str->Count, Str->Capacity - Str->Count, Fmt, Args);
+  Str->Count += Count;
+
+  VA_END (Args);
+  return Str->Str;
+}
+
+/**
+  Converts a PCI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextPci (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  PCI_DEVICE_PATH *Pci;
+
+  Pci = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
+}
+
+/**
+  Converts a PC Card device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextPccard (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  PCCARD_DEVICE_PATH  *Pccard;
+
+  Pccard = DevPath;
+  UefiDevicePathLibCatPrint (Str, "PcCard(0x%x)", Pccard->FunctionNumber);
+}
+
+/**
+  Converts a Memory Map device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextMemMap (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  MEMMAP_DEVICE_PATH  *MemMap;
+
+  MemMap = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "MemoryMapped(0x%x,0x%lx,0x%lx)",
+    MemMap->MemoryType,
+    MemMap->StartingAddress,
+    MemMap->EndingAddress
+    );
+}
+
+/**
+  Converts a Vendor device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextVendor (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+  const char          *Type;
+  UINTN               Index;
+  UINTN               DataLength;
+  UINT32              FlowControlMap;
+  UINT16              Info;
+
+  Vendor = (VENDOR_DEVICE_PATH *) DevPath;
+  switch (DevicePathType (&Vendor->Header)) {
+  case HARDWARE_DEVICE_PATH:
+    Type = "Hw";
+    break;
+
+  case MESSAGING_DEVICE_PATH:
+    Type = "Msg";
+    if (AllowShortcuts) {
+      if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
+        UefiDevicePathLibCatPrint (Str, "VenPcAnsi()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+        UefiDevicePathLibCatPrint (Str, "VenVt100()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+        UefiDevicePathLibCatPrint (Str, "VenVt100Plus()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+        UefiDevicePathLibCatPrint (Str, "VenUft8()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
+        FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+        switch (FlowControlMap & 0x00000003) {
+        case 0:
+          UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "None");
+          break;
+
+        case 1:
+          UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "Hardware");
+          break;
+
+        case 2:
+          UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "XonXoff");
+          break;
+
+        default:
+          break;
+        }
+
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
+        UefiDevicePathLibCatPrint (
+          Str,
+          "SAS(0x%lx,0x%lx,0x%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) && ((Info & BIT7) == 0)) {
+          UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0,");
+        } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {
+          UefiDevicePathLibCatPrint (
+            Str,
+            "%s,%s,%s,",
+            ((Info & BIT4) != 0) ? "SATA" : "SAS",
+            ((Info & BIT5) != 0) ? "External" : "Internal",
+            ((Info & BIT6) != 0) ? "Expanded" : "Direct"
+            );
+          if ((Info & 0x0f) == 1) {
+            UefiDevicePathLibCatPrint (Str, "0,");
+          } else {
+            //
+            // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
+            //
+            UefiDevicePathLibCatPrint (Str, "0x%x,", ((Info >> 8) & 0xff) + 1);
+          }
+        } else {
+          UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0,", Info);
+        }
+
+        UefiDevicePathLibCatPrint (Str, "0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+        UefiDevicePathLibCatPrint (Str, "DebugPort()");
+        return ;
+      }
+    }
+    break;
+
+  case MEDIA_DEVICE_PATH:
+    Type = "Media";
+    break;
+
+  default:
+    Type = "?";
+    break;
+  }
+
+  DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
+  UefiDevicePathLibCatPrint (Str, "Ven%s(%36s", Type, G(&Vendor->Guid));
+  if (DataLength != 0) {
+    UefiDevicePathLibCatPrint (Str, ",");
+    for (Index = 0; Index < DataLength; Index++) {
+      UefiDevicePathLibCatPrint (Str, "%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+    }
+  }
+
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a Controller device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextController (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  CONTROLLER_DEVICE_PATH  *Controller;
+
+  Controller = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "Ctrl(0x%x)",
+    Controller->ControllerNumber
+    );
+}
+
+/**
+  Converts a BMC device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextBmc (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  BMC_DEVICE_PATH    *Bmc;
+
+  Bmc = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "BMC(0x%x,0x%lx)",
+    Bmc->InterfaceType,
+    ReadUnaligned64 ((&Bmc->BaseAddress))
+    );
+}
+
+/**
+  Converts a ACPI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAcpi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  Acpi = DevPath;
+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+    switch (EISA_ID_TO_NUM (Acpi->HID)) {
+    case 0x0a03:
+      UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0a08:
+      UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0604:
+      UefiDevicePathLibCatPrint (Str, "Floppy(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0301:
+      UefiDevicePathLibCatPrint (Str, "Keyboard(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0501:
+      UefiDevicePathLibCatPrint (Str, "Serial(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0401:
+      UefiDevicePathLibCatPrint (Str, "ParallelPort(0x%x)", Acpi->UID);
+      break;
+
+    default:
+      UefiDevicePathLibCatPrint (Str, "Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+      break;
+    }
+  } else {
+    UefiDevicePathLibCatPrint (Str, "Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
+  }
+}
+
+/**
+  Converts a ACPI extended HID device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAcpiEx (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
+  CHAR8                          *HIDStr;
+  CHAR8                          *UIDStr;
+  CHAR8                          *CIDStr;
+  char                           HIDText[11];
+  char                           CIDText[11];
+
+  AcpiEx = DevPath;
+  HIDStr = (CHAR8 *) (((UINT8 *) AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+  UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;
+  CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;
+
+  //
+  // Converts EISA identification to string.
+  //
+  UnicodeSPrint (
+    HIDText,
+    sizeof (HIDText),
+    "%c%c%c%04X",
+    ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,
+    ((AcpiEx->HID >>  5) & 0x1f) + 'A' - 1,
+    ((AcpiEx->HID >>  0) & 0x1f) + 'A' - 1,
+    (AcpiEx->HID >> 16) & 0xFFFF
+    );
+  UnicodeSPrint (
+    CIDText,
+    sizeof (CIDText),
+    "%c%c%c%04X",
+    ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,
+    ((AcpiEx->CID >>  5) & 0x1f) + 'A' - 1,
+    ((AcpiEx->CID >>  0) & 0x1f) + 'A' - 1,
+    (AcpiEx->CID >> 16) & 0xFFFF
+    );
+
+  if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {
+    //
+    // use AcpiExp()
+    //
+    UefiDevicePathLibCatPrint (
+      Str,
+      "AcpiExp(%s,%s,%s)",
+      HIDText,
+      CIDText,
+      UIDStr
+      );
+  } else {
+    if (AllowShortcuts) {
+      //
+      // display only
+      //
+      if (AcpiEx->HID == 0) {
+        UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDStr);
+      } else {
+        UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDText);
+      }
+
+      if (AcpiEx->UID == 0) {
+        UefiDevicePathLibCatPrint (Str, "%s,", UIDStr);
+      } else {
+        UefiDevicePathLibCatPrint (Str, "0x%x,", AcpiEx->UID);
+      }
+
+      if (AcpiEx->CID == 0) {
+        UefiDevicePathLibCatPrint (Str, "%s)", CIDStr);
+      } else {
+        UefiDevicePathLibCatPrint (Str, "%s)", CIDText);
+      }
+    } else {
+      UefiDevicePathLibCatPrint (
+        Str,
+        "AcpiEx(%s,%s,0x%x,%s,%s,%s)",
+        HIDText,
+        CIDText,
+        AcpiEx->UID,
+        HIDStr,
+        CIDStr,
+        UIDStr
+        );
+    }
+  }
+}
+
+/**
+  Converts a ACPI address device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAcpiAdr (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ACPI_ADR_DEVICE_PATH    *AcpiAdr;
+  UINT32                  *Addr;
+  UINT16                  Index;
+  UINT16                  Length;
+  UINT16                  AdditionalAdrCount;
+
+  AcpiAdr            = DevPath;
+  Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
+  AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
+
+  UefiDevicePathLibCatPrint (Str, "AcpiAdr(0x%x", AcpiAdr->ADR);
+  Addr = &AcpiAdr->ADR + 1;
+  for (Index = 0; Index < AdditionalAdrCount; Index++) {
+    UefiDevicePathLibCatPrint (Str, ",0x%x", Addr[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a ATAPI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAtapi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ATAPI_DEVICE_PATH *Atapi;
+
+  Atapi = DevPath;
+
+  if (DisplayOnly) {
+    UefiDevicePathLibCatPrint (Str, "Ata(0x%x)", Atapi->Lun);
+  } else {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "Ata(%s,%s,0x%x)",
+      (Atapi->PrimarySecondary == 1) ? "Secondary" : "Primary",
+      (Atapi->SlaveMaster == 1) ? "Slave" : "Master",
+      Atapi->Lun
+      );
+  }
+}
+
+/**
+  Converts a SCSI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextScsi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  SCSI_DEVICE_PATH  *Scsi;
+
+  Scsi = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
+}
+
+/**
+  Converts a Fibre device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFibre (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  Fibre = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+/**
+  Converts a FibreEx device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFibreEx (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  FIBRECHANNELEX_DEVICE_PATH  *FibreEx;
+  UINTN                       Index;
+
+  FibreEx = DevPath;
+  UefiDevicePathLibCatPrint (Str, "FibreEx(0x");
+  for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->WWN[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ",0x");
+  for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->Lun[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a Sas Ex device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextSasEx (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  SASEX_DEVICE_PATH  *SasEx;
+  UINTN              Index;
+
+  SasEx = DevPath;
+  UefiDevicePathLibCatPrint (Str, "SasEx(0x");
+
+  for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", SasEx->SasAddress[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ",0x");
+  for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", SasEx->Lun[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ",0x%x,", SasEx->RelativeTargetPort);
+
+  if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {
+    UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0");
+  } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "%s,%s,%s,",
+      ((SasEx->DeviceTopology & BIT4) != 0) ? "SATA" : "SAS",
+      ((SasEx->DeviceTopology & BIT5) != 0) ? "External" : "Internal",
+      ((SasEx->DeviceTopology & BIT6) != 0) ? "Expanded" : "Direct"
+      );
+    if ((SasEx->DeviceTopology & 0x0f) == 1) {
+      UefiDevicePathLibCatPrint (Str, "0");
+    } else {
+      //
+      // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
+      //
+      UefiDevicePathLibCatPrint (Str, "0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
+    }
+  } else {
+    UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0", SasEx->DeviceTopology);
+  }
+
+  UefiDevicePathLibCatPrint (Str, ")");
+  return ;
+
+}
+
+/**
+  Converts a NVM Express Namespace device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextNVMe (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  NVME_NAMESPACE_DEVICE_PATH *Nvme;
+  UINT8                      *Uuid;
+
+  Nvme = DevPath;
+  Uuid = (UINT8 *) &Nvme->NamespaceUuid;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "NVMe(0x%x,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
+    Nvme->NamespaceId,
+    Uuid[7], Uuid[6], Uuid[5], Uuid[4],
+    Uuid[3], Uuid[2], Uuid[1], Uuid[0]
+    );
+}
+
+/**
+  Converts a UFS device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextUfs (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  UFS_DEVICE_PATH  *Ufs;
+
+  Ufs = DevPath;
+  UefiDevicePathLibCatPrint (Str, "UFS(0x%x,0x%x)", Ufs->Pun, Ufs->Lun);
+}
+
+/**
+  Converts a SD (Secure Digital) device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextSd (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  SD_DEVICE_PATH             *Sd;
+
+  Sd = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "SD(0x%x)",
+    Sd->SlotNumber
+    );
+}
+
+/**
+  Converts a EMMC (Embedded MMC) device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextEmmc (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  EMMC_DEVICE_PATH             *Emmc;
+
+  Emmc = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "eMMC(0x%x)",
+    Emmc->SlotNumber
+    );
+}
+
+/**
+  Converts a 1394 device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToText1394 (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  F1394_DEVICE_PATH *F1394DevPath;
+
+  F1394DevPath = DevPath;
+  //
+  // Guid has format of IEEE-EUI64
+  //
+  UefiDevicePathLibCatPrint (Str, "I1394(%016lx)", F1394DevPath->Guid);
+}
+
+/**
+  Converts a USB device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextUsb (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  USB_DEVICE_PATH *Usb;
+
+  Usb = DevPath;
+  UefiDevicePathLibCatPrint (Str, "USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+/**
+  Converts a USB WWID device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextUsbWWID (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  USB_WWID_DEVICE_PATH  *UsbWWId;
+  CHAR16                *SerialNumberStr;
+  CHAR16                *NewStr;
+  UINT16                Length;
+
+  UsbWWId = DevPath;
+
+  SerialNumberStr = (CHAR16 *) (&UsbWWId + 1);
+  Length = (UINT16) ((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));
+  if (SerialNumberStr [Length - 1] != 0) {
+    //
+    // In case no NULL terminator in SerialNumber, create a new one with NULL terminator
+    //
+    NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);
+    ASSERT (NewStr != NULL);
+    NewStr [Length] = 0;
+    SerialNumberStr = NewStr;
+  }
+
+  UefiDevicePathLibCatPrint (
+    Str,
+    "UsbWwid(0x%x,0x%x,0x%x,\"%S\")",
+    UsbWWId->VendorId,
+    UsbWWId->ProductId,
+    UsbWWId->InterfaceNumber,
+    SerialNumberStr
+    );
+}
+
+/**
+  Converts a Logic Unit device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextLogicalUnit (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+  LogicalUnit = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Unit(0x%x)", LogicalUnit->Lun);
+}
+
+/**
+  Converts a USB class device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextUsbClass (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  USB_CLASS_DEVICE_PATH *UsbClass;
+  BOOLEAN               IsKnownSubClass;
+
+
+  UsbClass = DevPath;
+
+  IsKnownSubClass = TRUE;
+  switch (UsbClass->DeviceClass) {
+  case USB_CLASS_AUDIO:
+    UefiDevicePathLibCatPrint (Str, "UsbAudio");
+    break;
+
+  case USB_CLASS_CDCCONTROL:
+    UefiDevicePathLibCatPrint (Str, "UsbCDCControl");
+    break;
+
+  case USB_CLASS_HID:
+    UefiDevicePathLibCatPrint (Str, "UsbHID");
+    break;
+
+  case USB_CLASS_IMAGE:
+    UefiDevicePathLibCatPrint (Str, "UsbImage");
+    break;
+
+  case USB_CLASS_PRINTER:
+    UefiDevicePathLibCatPrint (Str, "UsbPrinter");
+    break;
+
+  case USB_CLASS_MASS_STORAGE:
+    UefiDevicePathLibCatPrint (Str, "UsbMassStorage");
+    break;
+
+  case USB_CLASS_HUB:
+    UefiDevicePathLibCatPrint (Str, "UsbHub");
+    break;
+
+  case USB_CLASS_CDCDATA:
+    UefiDevicePathLibCatPrint (Str, "UsbCDCData");
+    break;
+
+  case USB_CLASS_SMART_CARD:
+    UefiDevicePathLibCatPrint (Str, "UsbSmartCard");
+    break;
+
+  case USB_CLASS_VIDEO:
+    UefiDevicePathLibCatPrint (Str, "UsbVideo");
+    break;
+
+  case USB_CLASS_DIAGNOSTIC:
+    UefiDevicePathLibCatPrint (Str, "UsbDiagnostic");
+    break;
+
+  case USB_CLASS_WIRELESS:
+    UefiDevicePathLibCatPrint (Str, "UsbWireless");
+    break;
+
+  default:
+    IsKnownSubClass = FALSE;
+    break;
+  }
+
+  if (IsKnownSubClass) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "(0x%x,0x%x,0x%x,0x%x)",
+      UsbClass->VendorId,
+      UsbClass->ProductId,
+      UsbClass->DeviceSubClass,
+      UsbClass->DeviceProtocol
+      );
+    return;
+  }
+
+  if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {
+    if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {
+      UefiDevicePathLibCatPrint (
+        Str,
+        "UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",
+        UsbClass->VendorId,
+        UsbClass->ProductId,
+        UsbClass->DeviceProtocol
+        );
+      return;
+    } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {
+      UefiDevicePathLibCatPrint (
+        Str,
+        "UsbIrdaBridge(0x%x,0x%x,0x%x)",
+        UsbClass->VendorId,
+        UsbClass->ProductId,
+        UsbClass->DeviceProtocol
+        );
+      return;
+    } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {
+      UefiDevicePathLibCatPrint (
+        Str,
+        "UsbTestAndMeasurement(0x%x,0x%x,0x%x)",
+        UsbClass->VendorId,
+        UsbClass->ProductId,
+        UsbClass->DeviceProtocol
+        );
+      return;
+    }
+  }
+
+  UefiDevicePathLibCatPrint (
+    Str,
+    "UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
+    UsbClass->VendorId,
+    UsbClass->ProductId,
+    UsbClass->DeviceClass,
+    UsbClass->DeviceSubClass,
+    UsbClass->DeviceProtocol
+    );
+}
+
+/**
+  Converts a SATA device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextSata (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  SATA_DEVICE_PATH *Sata;
+
+  Sata = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "Sata(0x%x,0x%x,0x%x)",
+    Sata->HBAPortNumber,
+    Sata->PortMultiplierPortNumber,
+    Sata->Lun
+    );
+}
+
+/**
+  Converts a I20 device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextI2O (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  I2O_DEVICE_PATH *I2ODevPath;
+
+  I2ODevPath = DevPath;
+  UefiDevicePathLibCatPrint (Str, "I2O(0x%x)", I2ODevPath->Tid);
+}
+
+/**
+  Converts a MAC address device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextMacAddr (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  MAC_ADDR_DEVICE_PATH  *MacDevPath;
+  UINTN                 HwAddressSize;
+  UINTN                 Index;
+
+  MacDevPath = DevPath;
+
+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+  if (MacDevPath->IfType == 0x01 || MacDevPath->IfType == 0x00) {
+    HwAddressSize = 6;
+  }
+
+  UefiDevicePathLibCatPrint (Str, "MAC(");
+
+  for (Index = 0; Index < HwAddressSize; Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", MacDevPath->MacAddress.Addr[Index]);
+  }
+
+  UefiDevicePathLibCatPrint (Str, ",0x%x)", MacDevPath->IfType);
+}
+
+/**
+  Converts network protocol string to its text representation.
+
+  @param Str             The string representative of input device.
+  @param Protocol        The network protocol ID.
+
+**/
+static VOID
+CatNetworkProtocol (
+  IN OUT POOL_PRINT  *Str,
+  IN UINT16          Protocol
+  )
+{
+  if (Protocol == RFC_1700_TCP_PROTOCOL) {
+    UefiDevicePathLibCatPrint (Str, "TCP");
+  } else if (Protocol == RFC_1700_UDP_PROTOCOL) {
+    UefiDevicePathLibCatPrint (Str, "UDP");
+  } else {
+    UefiDevicePathLibCatPrint (Str, "0x%x", Protocol);
+  }
+}
+
+/**
+  Converts IP v4 address to its text representation.
+
+  @param Str             The string representative of input device.
+  @param Address         The IP v4 address.
+**/
+static VOID
+CatIPv4Address (
+  IN OUT POOL_PRINT   *Str,
+  IN EFI_IPv4_ADDRESS *Address
+  )
+{
+  UefiDevicePathLibCatPrint (Str, "%d.%d.%d.%d", Address->Addr[0], Address->Addr[1], Address->Addr[2], Address->Addr[3]);
+}
+
+/**
+  Converts IP v6 address to its text representation.
+
+  @param Str             The string representative of input device.
+  @param Address         The IP v6 address.
+**/
+static VOID
+CatIPv6Address (
+  IN OUT POOL_PRINT   *Str,
+  IN EFI_IPv6_ADDRESS *Address
+  )
+{
+  UefiDevicePathLibCatPrint (
+    Str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+    Address->Addr[0],  Address->Addr[1],
+    Address->Addr[2],  Address->Addr[3],
+    Address->Addr[4],  Address->Addr[5],
+    Address->Addr[6],  Address->Addr[7],
+    Address->Addr[8],  Address->Addr[9],
+    Address->Addr[10], Address->Addr[11],
+    Address->Addr[12], Address->Addr[13],
+    Address->Addr[14], Address->Addr[15]
+  );
+}
+
+/**
+  Converts a IPv4 device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextIPv4 (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  IPv4_DEVICE_PATH  *IPDevPath;
+
+  IPDevPath = DevPath;
+  UefiDevicePathLibCatPrint (Str, "IPv4(");
+  CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);
+
+  if (DisplayOnly) {
+    UefiDevicePathLibCatPrint (Str, ")");
+    return ;
+  }
+
+  UefiDevicePathLibCatPrint (Str, ",");
+  CatNetworkProtocol (Str, IPDevPath->Protocol);
+
+  UefiDevicePathLibCatPrint (Str, ",%s,", IPDevPath->StaticIpAddress ? "Static" : "DHCP");
+  CatIPv4Address (Str, &IPDevPath->LocalIpAddress);
+  if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {
+    UefiDevicePathLibCatPrint (Str, ",");
+    CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);
+    UefiDevicePathLibCatPrint (Str, ",");
+    CatIPv4Address (Str, &IPDevPath->SubnetMask);
+  }
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a IPv6 device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextIPv6 (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  IPv6_DEVICE_PATH  *IPDevPath;
+
+  IPDevPath = DevPath;
+  UefiDevicePathLibCatPrint (Str, "IPv6(");
+  CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);
+  if (DisplayOnly) {
+    UefiDevicePathLibCatPrint (Str, ")");
+    return ;
+  }
+
+  UefiDevicePathLibCatPrint (Str, ",");
+  CatNetworkProtocol (Str, IPDevPath->Protocol);
+
+  switch (IPDevPath->IpAddressOrigin) {
+    case 0:
+      UefiDevicePathLibCatPrint (Str, ",Static,");
+      break;
+    case 1:
+      UefiDevicePathLibCatPrint (Str, ",StatelessAutoConfigure,");
+      break;
+    default:
+      UefiDevicePathLibCatPrint (Str, ",StatefulAutoConfigure,");
+      break;
+  }
+
+  CatIPv6Address (Str, &IPDevPath->LocalIpAddress);
+
+  if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {
+    UefiDevicePathLibCatPrint (Str, ",0x%x,", IPDevPath->PrefixLength);
+    CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);
+  }
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts an Infini Band device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextInfiniBand (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  INFINIBAND_DEVICE_PATH  *InfiniBand;
+
+  InfiniBand = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "Infiniband(0x%x,%36s,0x%lx,0x%lx,0x%lx)",
+    InfiniBand->ResourceFlags,
+    G(InfiniBand->PortGid),
+    InfiniBand->ServiceId,
+    InfiniBand->TargetPortId,
+    InfiniBand->DeviceId
+    );
+}
+
+/**
+  Converts a UART device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextUart (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  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) {
+    UefiDevicePathLibCatPrint (Str, "Uart(DEFAULT,");
+  } else {
+    UefiDevicePathLibCatPrint (Str, "Uart(%ld,", Uart->BaudRate);
+  }
+
+  if (Uart->DataBits == 0) {
+    UefiDevicePathLibCatPrint (Str, "DEFAULT,");
+  } else {
+    UefiDevicePathLibCatPrint (Str, "%d,", Uart->DataBits);
+  }
+
+  UefiDevicePathLibCatPrint (Str, "%c,", Parity);
+
+  switch (Uart->StopBits) {
+  case 0:
+    UefiDevicePathLibCatPrint (Str, "D)");
+    break;
+
+  case 1:
+    UefiDevicePathLibCatPrint (Str, "1)");
+    break;
+
+  case 2:
+    UefiDevicePathLibCatPrint (Str, "1.5)");
+    break;
+
+  case 3:
+    UefiDevicePathLibCatPrint (Str, "2)");
+    break;
+
+  default:
+    UefiDevicePathLibCatPrint (Str, "x)");
+    break;
+  }
+}
+
+/**
+  Converts an iSCSI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextiSCSI (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+  UINT16                      Options;
+
+  ISCSIDevPath = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "iSCSI(%s,0x%x,0x%lx,",
+    ISCSIDevPath->TargetName,
+    ISCSIDevPath->TargetPortalGroupTag,
+    ISCSIDevPath->Lun
+    );
+
+  Options = ISCSIDevPath->LoginOption;
+  UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 1) & 0x0001) != 0) ? "CRC32C" : "None");
+  UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 3) & 0x0001) != 0) ? "CRC32C" : "None");
+  if (((Options >> 11) & 0x0001) != 0) {
+    UefiDevicePathLibCatPrint (Str, "%s,", "None");
+  } else if (((Options >> 12) & 0x0001) != 0) {
+    UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_UNI");
+  } else {
+    UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_BI");
+
+  }
+
+  UefiDevicePathLibCatPrint (Str, "%s)", (ISCSIDevPath->NetworkProtocol == 0) ? "TCP" : "reserved");
+}
+
+/**
+  Converts a VLAN device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextVlan (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  VLAN_DEVICE_PATH  *Vlan;
+
+  Vlan = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Vlan(%d)", Vlan->VlanId);
+}
+
+/**
+  Converts a Bluetooth device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextBluetooth (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  BLUETOOTH_DEVICE_PATH  *Bluetooth;
+
+  Bluetooth = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "Bluetooth(%02x%02x%02x%02x%02x%02x)",
+    Bluetooth->BD_ADDR.Address[5],
+    Bluetooth->BD_ADDR.Address[4],
+    Bluetooth->BD_ADDR.Address[3],
+    Bluetooth->BD_ADDR.Address[2],
+    Bluetooth->BD_ADDR.Address[1],
+    Bluetooth->BD_ADDR.Address[0]
+    );
+}
+
+/**
+  Converts a Wi-Fi device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextWiFi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  WIFI_DEVICE_PATH      *WiFi;
+  UINT8                 SSId[33];
+
+  WiFi = DevPath;
+
+  SSId[32] = '\0';
+  CopyMem (SSId, WiFi->SSId, 32);
+
+  UefiDevicePathLibCatPrint (Str, "Wi-Fi(%s)", SSId);
+}
+
+/**
+  Converts a URI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextUri (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  URI_DEVICE_PATH    *Uri;
+  UINTN              UriLength;
+  CHAR8              *UriStr;
+
+  //
+  // Uri in the device path may not be null terminated.
+  //
+  Uri       = DevPath;
+  UriLength = DevicePathNodeLength (Uri) - sizeof (URI_DEVICE_PATH);
+  UriStr = AllocatePool (UriLength + 1);
+  ASSERT (UriStr != NULL);
+
+  CopyMem (UriStr, Uri->Uri, UriLength);
+  UriStr[UriLength] = '\0';
+  UefiDevicePathLibCatPrint (Str, "Uri(%s)", UriStr);
+  FreePool (UriStr);
+}
+
+/**
+  Converts a Hard drive device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextHardDrive (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  HARDDRIVE_DEVICE_PATH *Hd;
+
+  Hd = DevPath;
+  switch (Hd->SignatureType) {
+  case SIGNATURE_TYPE_MBR:
+    UefiDevicePathLibCatPrint (
+      Str,
+      "HD(%d,%s,0x%08x,",
+      Hd->PartitionNumber,
+      "MBR",
+//      *((UINT32 *) (&(Hd->Signature[0])))
+      le32dec(&(Hd->Signature[0]))
+      );
+    break;
+
+  case SIGNATURE_TYPE_GUID:
+    UefiDevicePathLibCatPrint (
+      Str,
+      "HD(%d,%s,%36s,",
+      Hd->PartitionNumber,
+      "GPT",
+      G(&(Hd->Signature[0]))
+      );
+    break;
+
+  default:
+    UefiDevicePathLibCatPrint (
+      Str,
+      "HD(%d,%d,0,",
+      Hd->PartitionNumber,
+      Hd->SignatureType
+      );
+    break;
+  }
+
+  UefiDevicePathLibCatPrint (Str, "0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
+}
+
+/**
+  Converts a CDROM device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextCDROM (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  CDROM_DEVICE_PATH *Cd;
+
+  Cd = DevPath;
+  if (DisplayOnly) {
+    UefiDevicePathLibCatPrint (Str, "CDROM(0x%x)", Cd->BootEntry);
+    return ;
+  }
+
+  UefiDevicePathLibCatPrint (Str, "CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+}
+
+/**
+  Converts a File device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFilePath (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  FILEPATH_DEVICE_PATH  *Fp;
+
+  Fp = DevPath;
+  UefiDevicePathLibCatPrint (Str, "%s", Fp->PathName);
+}
+
+/**
+  Converts a Media protocol device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextMediaProtocol (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;
+
+  MediaProt = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Media(%36s)", G(&MediaProt->Protocol));
+}
+
+/**
+  Converts a Firmware Volume device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFv (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  MEDIA_FW_VOL_DEVICE_PATH  *Fv;
+
+  Fv = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Fv(%36s)", G(&Fv->FvName));
+}
+
+/**
+  Converts a Firmware Volume File device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFvFile (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFile;
+
+  FvFile = DevPath;
+  UefiDevicePathLibCatPrint (Str, "FvFile(%36s)", G(&FvFile->FvFileName));
+}
+
+/**
+  Converts a Relative Offset device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathRelativeOffsetRange (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath,
+  IN BOOLEAN              DisplayOnly,
+  IN BOOLEAN              AllowShortcuts
+  )
+{
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+  Offset = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "Offset(0x%lx,0x%lx)",
+    Offset->StartingOffset,
+    Offset->EndingOffset
+    );
+}
+
+/**
+  Converts a Ram Disk device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextRamDisk (
+  IN OUT POOL_PRINT       *Str,
+  IN VOID                 *DevPath,
+  IN BOOLEAN              DisplayOnly,
+  IN BOOLEAN              AllowShortcuts
+  )
+{
+  MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+
+  RamDisk = DevPath;
+
+  if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid)) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "VirtualDisk(0x%lx,0x%lx,%d)",
+      LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+      LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+      RamDisk->Instance
+      );
+  } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid)) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "VirtualCD(0x%lx,0x%lx,%d)",
+      LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+      LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+      RamDisk->Instance
+      );
+  } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid)) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "PersistentVirtualDisk(0x%lx,0x%lx,%d)",
+      LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+      LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+      RamDisk->Instance
+      );
+  } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid)) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "PersistentVirtualCD(0x%lx,0x%lx,%d)",
+      LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+      LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+      RamDisk->Instance
+      );
+  } else {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "RamDisk(0x%lx,0x%lx,%d,%36s)",
+      LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+      LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+      RamDisk->Instance,
+      G(&RamDisk->TypeGuid)
+      );
+  }
+}
+
+/**
+  Converts a BIOS Boot Specification device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextBBS (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  BBS_BBS_DEVICE_PATH *Bbs;
+  const char          *Type;
+
+  Bbs = DevPath;
+  switch (Bbs->DeviceType) {
+  case BBS_TYPE_FLOPPY:
+    Type = "Floppy";
+    break;
+
+  case BBS_TYPE_HARDDRIVE:
+    Type = "HD";
+    break;
+
+  case BBS_TYPE_CDROM:
+    Type = "CDROM";
+    break;
+
+  case BBS_TYPE_PCMCIA:
+    Type = "PCMCIA";
+    break;
+
+  case BBS_TYPE_USB:
+    Type = "USB";
+    break;
+
+  case BBS_TYPE_EMBEDDED_NETWORK:
+    Type = "Network";
+    break;
+
+  default:
+    Type = NULL;
+    break;
+  }
+
+  if (Type != NULL) {
+    UefiDevicePathLibCatPrint (Str, "BBS(%s,%s", Type, Bbs->String);
+  } else {
+    UefiDevicePathLibCatPrint (Str, "BBS(0x%x,%s", Bbs->DeviceType, Bbs->String);
+  }
+
+  if (DisplayOnly) {
+    UefiDevicePathLibCatPrint (Str, ")");
+    return ;
+  }
+
+  UefiDevicePathLibCatPrint (Str, ",0x%x)", Bbs->StatusFlag);
+}
+
+/**
+  Converts an End-of-Device-Path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextEndInstance (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  UefiDevicePathLibCatPrint (Str, ",");
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_GENERIC_TABLE mUefiDevicePathLibToTextTableGeneric[] = {
+  {HARDWARE_DEVICE_PATH,  "HardwarePath"   },
+  {ACPI_DEVICE_PATH,      "AcpiPath"       },
+  {MESSAGING_DEVICE_PATH, "Msg"            },
+  {MEDIA_DEVICE_PATH,     "MediaPath"      },
+  {BBS_DEVICE_PATH,       "BbsPath"        },
+  {0, NULL}
+};
+
+/**
+  Converts an unknown device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextNodeGeneric (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL *Node;
+  UINTN                    Index;
+
+  Node = DevPath;
+
+  for (Index = 0; mUefiDevicePathLibToTextTableGeneric[Index].Text != NULL; Index++) {
+    if (DevicePathType (Node) == mUefiDevicePathLibToTextTableGeneric[Index].Type) {
+      break;
+    }
+  }
+
+  if (mUefiDevicePathLibToTextTableGeneric[Index].Text == NULL) {
+    //
+    // It's a node whose type cannot be recognized
+    //
+    UefiDevicePathLibCatPrint (Str, "Path(%d,%d", DevicePathType (Node), DevicePathSubType (Node));
+  } else {
+    //
+    // It's a node whose type can be recognized
+    //
+    UefiDevicePathLibCatPrint (Str, "%s(%d", mUefiDevicePathLibToTextTableGeneric[Index].Text, DevicePathSubType (Node));
+  }
+
+  Index = sizeof (EFI_DEVICE_PATH_PROTOCOL);
+  if (Index < DevicePathNodeLength (Node)) {
+    UefiDevicePathLibCatPrint (Str, ",");
+    for (; Index < DevicePathNodeLength (Node); Index++) {
+      UefiDevicePathLibCatPrint (Str, "%02x", ((UINT8 *) Node)[Index]);
+    }
+  }
+
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+static const DEVICE_PATH_TO_TEXT_TABLE mUefiDevicePathLibToTextTable[] = {
+  {HARDWARE_DEVICE_PATH,  HW_PCI_DP,                        DevPathToTextPci            },
+  {HARDWARE_DEVICE_PATH,  HW_PCCARD_DP,                     DevPathToTextPccard         },
+  {HARDWARE_DEVICE_PATH,  HW_MEMMAP_DP,                     DevPathToTextMemMap         },
+  {HARDWARE_DEVICE_PATH,  HW_VENDOR_DP,                     DevPathToTextVendor         },
+  {HARDWARE_DEVICE_PATH,  HW_CONTROLLER_DP,                 DevPathToTextController     },
+  {HARDWARE_DEVICE_PATH,  HW_BMC_DP,                        DevPathToTextBmc            },
+  {ACPI_DEVICE_PATH,      ACPI_DP,                          DevPathToTextAcpi           },
+  {ACPI_DEVICE_PATH,      ACPI_EXTENDED_DP,                 DevPathToTextAcpiEx         },
+  {ACPI_DEVICE_PATH,      ACPI_ADR_DP,                      DevPathToTextAcpiAdr        },
+  {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP,                     DevPathToTextAtapi          },
+  {MESSAGING_DEVICE_PATH, MSG_SCSI_DP,                      DevPathToTextScsi           },
+  {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP,              DevPathToTextFibre          },
+  {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP,            DevPathToTextFibreEx        },
+  {MESSAGING_DEVICE_PATH, MSG_SASEX_DP,                     DevPathToTextSasEx          },
+  {MESSAGING_DEVICE_PATH, MSG_NVME_NAMESPACE_DP,            DevPathToTextNVMe           },
+  {MESSAGING_DEVICE_PATH, MSG_UFS_DP,                       DevPathToTextUfs            },
+  {MESSAGING_DEVICE_PATH, MSG_SD_DP,                        DevPathToTextSd             },
+  {MESSAGING_DEVICE_PATH, MSG_EMMC_DP,                      DevPathToTextEmmc           },
+  {MESSAGING_DEVICE_PATH, MSG_1394_DP,                      DevPathToText1394           },
+  {MESSAGING_DEVICE_PATH, MSG_USB_DP,                       DevPathToTextUsb            },
+  {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP,                  DevPathToTextUsbWWID        },
+  {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP,       DevPathToTextLogicalUnit    },
+  {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,                 DevPathToTextUsbClass       },
+  {MESSAGING_DEVICE_PATH, MSG_SATA_DP,                      DevPathToTextSata           },
+  {MESSAGING_DEVICE_PATH, MSG_I2O_DP,                       DevPathToTextI2O            },
+  {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP,                  DevPathToTextMacAddr        },
+  {MESSAGING_DEVICE_PATH, MSG_IPv4_DP,                      DevPathToTextIPv4           },
+  {MESSAGING_DEVICE_PATH, MSG_IPv6_DP,                      DevPathToTextIPv6           },
+  {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP,                DevPathToTextInfiniBand     },
+  {MESSAGING_DEVICE_PATH, MSG_UART_DP,                      DevPathToTextUart           },
+  {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,                    DevPathToTextVendor         },
+  {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP,                     DevPathToTextiSCSI          },
+  {MESSAGING_DEVICE_PATH, MSG_VLAN_DP,                      DevPathToTextVlan           },
+  {MESSAGING_DEVICE_PATH, MSG_URI_DP,                       DevPathToTextUri            },
+  {MESSAGING_DEVICE_PATH, MSG_BLUETOOTH_DP,                 DevPathToTextBluetooth      },
+  {MESSAGING_DEVICE_PATH, MSG_WIFI_DP,                      DevPathToTextWiFi           },
+  {MEDIA_DEVICE_PATH,     MEDIA_HARDDRIVE_DP,               DevPathToTextHardDrive      },
+  {MEDIA_DEVICE_PATH,     MEDIA_CDROM_DP,                   DevPathToTextCDROM          },
+  {MEDIA_DEVICE_PATH,     MEDIA_VENDOR_DP,                  DevPathToTextVendor         },
+  {MEDIA_DEVICE_PATH,     MEDIA_PROTOCOL_DP,                DevPathToTextMediaProtocol  },
+  {MEDIA_DEVICE_PATH,     MEDIA_FILEPATH_DP,                DevPathToTextFilePath       },
+  {MEDIA_DEVICE_PATH,     MEDIA_PIWG_FW_VOL_DP,             DevPathToTextFv             },
+  {MEDIA_DEVICE_PATH,     MEDIA_PIWG_FW_FILE_DP,            DevPathToTextFvFile         },
+  {MEDIA_DEVICE_PATH,     MEDIA_RELATIVE_OFFSET_RANGE_DP,   DevPathRelativeOffsetRange  },
+  {MEDIA_DEVICE_PATH,     MEDIA_RAM_DISK_DP,                DevPathToTextRamDisk        },
+  {BBS_DEVICE_PATH,       BBS_BBS_DP,                       DevPathToTextBBS            },
+  {END_DEVICE_PATH_TYPE,  END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance    },
+  {0, 0, NULL}
+};
+
+#ifndef __DragonFly__
+/**
+  Converts a device node to its string representation.
+
+  @param DeviceNode        A Pointer to the device node to be converted.
+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
+                           of the display node is used, where applicable. If DisplayOnly
+                           is FALSE, then the longer text representation of the display node
+                           is used.
+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
+                           representation for a device node can be used, where applicable.
+
+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+          is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+UefiDevicePathLibConvertDeviceNodeToText (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
+  IN BOOLEAN                         DisplayOnly,
+  IN BOOLEAN                         AllowShortcuts
+  )
+{
+  POOL_PRINT          Str;
+  UINTN               Index;
+  DEVICE_PATH_TO_TEXT ToText;
+
+  if (DeviceNode == NULL) {
+    return NULL;
+  }
+
+  ZeroMem (&Str, sizeof (Str));
+
+  //
+  // Process the device path node
+  // If not found, use a generic function
+  //
+  ToText = DevPathToTextNodeGeneric;
+  for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index++) {
+    if (DevicePathType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].Type &&
+        DevicePathSubType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].SubType
+        ) {
+      ToText = mUefiDevicePathLibToTextTable[Index].Function;
+      break;
+    }
+  }
+
+  //
+  // Print this node
+  //
+  ToText (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+
+  ASSERT (Str.Str != NULL);
+  return Str.Str;
+}
+#endif
+
+/**
+  Converts a device path to its text representation.
+
+  @param DevicePath      A Pointer to the device to be converted.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+  @return A pointer to the allocated text representation of the device path or
+          NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+static char *
+EFIAPI
+UefiDevicePathLibConvertDevicePathToText (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
+  IN BOOLEAN                          DisplayOnly,
+  IN BOOLEAN                          AllowShortcuts
+  )
+{
+  POOL_PRINT               Str;
+  EFI_DEVICE_PATH_PROTOCOL *Node;
+  EFI_DEVICE_PATH_PROTOCOL *AlignedNode;
+  UINTN                    Index;
+  DEVICE_PATH_TO_TEXT      ToText;
+
+  if (DevicePath == NULL) {
+    return NULL;
+  }
+
+  ZeroMem (&Str, sizeof (Str));
+
+  //
+  // Process each device path node
+  //
+  Node = __DECONST(EFI_DEVICE_PATH_PROTOCOL *, DevicePath);
+  while (!IsDevicePathEnd (Node)) {
+    //
+    // Find the handler to dump this device path node
+    // If not found, use a generic function
+    //
+    ToText = DevPathToTextNodeGeneric;
+    for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index += 1) {
+
+      if (DevicePathType (Node) == mUefiDevicePathLibToTextTable[Index].Type &&
+          DevicePathSubType (Node) == mUefiDevicePathLibToTextTable[Index].SubType
+          ) {
+        ToText = mUefiDevicePathLibToTextTable[Index].Function;
+        break;
+      }
+    }
+    //
+    //  Put a path separator in if needed
+    //
+    if ((Str.Count != 0) && (ToText != DevPathToTextEndInstance)) {
+      if (Str.Str[Str.Count] != ',') {
+        UefiDevicePathLibCatPrint (&Str, "/");
+      }
+    }
+
+    AlignedNode = AllocateCopyPool (DevicePathNodeLength (Node), Node);
+    //
+    // Print this node of the device path
+    //
+    ToText (&Str, AlignedNode, DisplayOnly, AllowShortcuts);
+    FreePool (AlignedNode);
+
+    //
+    // Next device path node
+    //
+    Node = NextDevicePathNode (Node);
+  }
+
+  if (Str.Str == NULL) {
+    return AllocateZeroPool (sizeof (CHAR16));
+  } else {
+    return Str.Str;
+  }
+}
+
+
+ssize_t
+efidp_format_device_path(char *buf, size_t len, const_efidp dp, ssize_t max)
+{
+	char *str;
+	ssize_t retval;
+
+	str = UefiDevicePathLibConvertDevicePathToText (
+		__DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp), FALSE, TRUE);
+	if (str == NULL)
+		return -1;
+	strlcpy(buf, str, len);
+	retval = strlen(str);
+	free(str);
+
+	return retval;
+}
diff --git a/lib/libefivar/efivar-dp-parse.c b/lib/libefivar/efivar-dp-parse.c
new file mode 100644
index 0000000000..b6a165ab20
--- /dev/null
+++ b/lib/libefivar/efivar-dp-parse.c
@@ -0,0 +1,3715 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
+ * this file is taken from EDK2 and rototilled.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/lib/libefivar/efivar-dp-parse.c 315771 2017-03-23 02:30:57Z imp $");
+
+#include <ctype.h>
+#include <efivar.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "efi-osdep.h"
+#include "efivar-dp.h"
+
+#include "uefi-dplib.h"
+
+/* XXX STUBS -- this stuff doesn't work yet */
+#define StrToIpv4Address(str, unk, ipv4ptr, unk2)
+#define StrToIpv6Address(str, unk, ipv6ptr, unk2)
+
+/*
+ * OK. Now this is evil. Can't typedef it again. Sure beats changing them all.
+ * Since we're doing it all as narrow characters since wchar_t can't be used on
+ * FreeBSD and CHAR16 strings generally aren't a good fit. Since this parsing
+ * doesn't need Unicode for anything, this works out well.
+ */
+#define CHAR16 char
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ */
+
+/** @file
+  DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+// #include "UefiDevicePathLib.h"
+
+/**
+
+  Duplicates a string.
+
+  @param  Src  Source string.
+
+  @return The duplicated string.
+
+**/
+static
+CHAR16 *
+UefiDevicePathLibStrDuplicate (
+  IN CONST CHAR16  *Src
+  )
+{
+  return AllocateCopyPool (StrSize (Src), Src);
+}
+
+/**
+
+  Get parameter in a pair of parentheses follow the given node name.
+  For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+  @param  Str      Device Path Text.
+  @param  NodeName Name of the node.
+
+  @return Parameter text for the node.
+
+**/
+static
+CHAR16 *
+GetParamByNodeName (
+  IN CHAR16 *Str,
+  IN const CHAR16 *NodeName
+  )
+{
+  CHAR16  *ParamStr;
+  CHAR16  *StrPointer;
+  UINTN   NodeNameLength;
+  UINTN   ParameterLength;
+
+  //
+  // Check whether the node name matchs
+  //
+  NodeNameLength = StrLen (NodeName);
+  if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
+    return NULL;
+  }
+
+  ParamStr = Str + NodeNameLength;
+  if (!IS_LEFT_PARENTH (*ParamStr)) {
+    return NULL;
+  }
+
+  //
+  // Skip the found '(' and find first occurrence of ')'
+  //
+  ParamStr++;
+  ParameterLength = 0;
+  StrPointer = ParamStr;
+  while (!IS_NULL (*StrPointer)) {
+    if (IS_RIGHT_PARENTH (*StrPointer)) {
+      break;
+    }
+    StrPointer++;
+    ParameterLength++;
+  }
+  if (IS_NULL (*StrPointer)) {
+    //
+    // ')' not found
+    //
+    return NULL;
+  }
+
+  ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+  if (ParamStr == NULL) {
+    return NULL;
+  }
+  //
+  // Terminate the parameter string
+  //
+  ParamStr[ParameterLength] = '\0';
+
+  return ParamStr;
+}
+
+/**
+  Gets current sub-string from a string list, before return
+  the list header is moved to next sub-string. The sub-string is separated
+  by the specified character. For example, the separator is ',', the string
+  list is "2,0,3", it returns "2", the remain list move to "0,3"
+
+  @param  List        A string list separated by the specified separator
+  @param  Separator   The separator character
+
+  @return A pointer to the current sub-string
+
+**/
+static
+CHAR16 *
+SplitStr (
+  IN OUT CHAR16 **List,
+  IN     CHAR16 Separator
+  )
+{
+  CHAR16  *Str;
+  CHAR16  *ReturnStr;
+
+  Str = *List;
+  ReturnStr = Str;
+
+  if (IS_NULL (*Str)) {
+    return ReturnStr;
+  }
+
+  //
+  // Find first occurrence of the separator
+  //
+  while (!IS_NULL (*Str)) {
+    if (*Str == Separator) {
+      break;
+    }
+    Str++;
+  }
+
+  if (*Str == Separator) {
+    //
+    // Find a sub-string, terminate it
+    //
+    *Str = '\0';
+    Str++;
+  }
+
+  //
+  // Move to next sub-string
+  //
+  *List = Str;
+
+  return ReturnStr;
+}
+
+/**
+  Gets the next parameter string from the list.
+
+  @param List            A string list separated by the specified separator
+
+  @return A pointer to the current sub-string
+
+**/
+static
+CHAR16 *
+GetNextParamStr (
+  IN OUT CHAR16 **List
+  )
+{
+  //
+  // The separator is comma
+  //
+  return SplitStr (List, ',');
+}
+
+/**
+  Get one device node from entire device path text.
+
+  @param DevicePath      On input, the current Device Path node; on output, the next device path node
+  @param IsInstanceEnd   This node is the end of a device path instance
+
+  @return A device node text or NULL if no more device node available
+
+**/
+static
+CHAR16 *
+GetNextDeviceNodeStr (
+  IN OUT CHAR16   **DevicePath,
+  OUT    BOOLEAN  *IsInstanceEnd
+  )
+{
+  CHAR16  *Str;
+  CHAR16  *ReturnStr;
+  UINTN   ParenthesesStack;
+
+  Str = *DevicePath;
+  if (IS_NULL (*Str)) {
+    return NULL;
+  }
+
+  //
+  // Skip the leading '/', '(', ')' and ','
+  //
+  while (!IS_NULL (*Str)) {
+    if (!IS_SLASH (*Str) &&
+        !IS_COMMA (*Str) &&
+        !IS_LEFT_PARENTH (*Str) &&
+        !IS_RIGHT_PARENTH (*Str)) {
+      break;
+    }
+    Str++;
+  }
+
+  ReturnStr = Str;
+
+  //
+  // Scan for the separator of this device node, '/' or ','
+  //
+  ParenthesesStack = 0;
+  while (!IS_NULL (*Str)) {
+    if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+      break;
+    }
+
+    if (IS_LEFT_PARENTH (*Str)) {
+      ParenthesesStack++;
+    } else if (IS_RIGHT_PARENTH (*Str)) {
+      ParenthesesStack--;
+    }
+
+    Str++;
+  }
+
+  if (ParenthesesStack != 0) {
+    //
+    // The '(' doesn't pair with ')', invalid device path text
+    //
+    return NULL;
+  }
+
+  if (IS_COMMA (*Str)) {
+    *IsInstanceEnd = TRUE;
+    *Str = '\0';
+    Str++;
+  } else {
+    *IsInstanceEnd = FALSE;
+    if (!IS_NULL (*Str)) {
+      *Str = '\0';
+      Str++;
+    }
+  }
+
+  *DevicePath = Str;
+
+  return ReturnStr;
+}
+
+
+#ifndef __DragonFly__
+/**
+  Return whether the integer string is a hex string.
+
+  @param Str             The integer string
+
+  @retval TRUE   Hex string
+  @retval FALSE  Decimal string
+
+**/
+static
+BOOLEAN
+IsHexStr (
+  IN CHAR16   *Str
+  )
+{
+  //
+  // skip preceeding white space
+  //
+  while ((*Str != 0) && *Str == ' ') {
+    Str ++;
+  }
+  //
+  // skip preceeding zeros
+  //
+  while ((*Str != 0) && *Str == '0') {
+    Str ++;
+  }
+
+  return (BOOLEAN) (*Str == 'x' || *Str == 'X');
+}
+
+/**
+
+  Convert integer string to uint.
+
+  @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
+
+  @return A UINTN value represented by Str
+
+**/
+static
+UINTN
+Strtoi (
+  IN CHAR16  *Str
+  )
+{
+  if (IsHexStr (Str)) {
+    return StrHexToUintn (Str);
+  } else {
+    return StrDecimalToUintn (Str);
+  }
+}
+
+/**
+
+  Convert integer string to 64 bit data.
+
+  @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
+  @param Data            A pointer to the UINT64 value represented by Str
+
+**/
+static
+VOID
+Strtoi64 (
+  IN  CHAR16  *Str,
+  OUT UINT64  *Data
+  )
+{
+  if (IsHexStr (Str)) {
+    *Data = StrHexToUint64 (Str);
+  } else {
+    *Data = StrDecimalToUint64 (Str);
+  }
+}
+#endif
+
+/**
+  Converts a Unicode string to ASCII string.
+
+  @param Str             The equivalent Unicode string
+  @param AsciiStr        On input, it points to destination ASCII string buffer; on output, it points
+                         to the next ASCII string next to it
+
+**/
+static
+VOID
+StrToAscii (
+  IN     CHAR16 *Str,
+  IN OUT CHAR8  **AsciiStr
+  )
+{
+  CHAR8 *Dest;
+
+  Dest = *AsciiStr;
+  while (!IS_NULL (*Str)) {
+    *(Dest++) = (CHAR8) *(Str++);
+  }
+  *Dest = 0;
+
+  //
+  // Return the string next to it
+  //
+  *AsciiStr = Dest + 1;
+}
+
+/**
+  Converts a generic text device path node to device path structure.
+
+  @param Type            The type of the device path node.
+  @param TextDeviceNode  The input text device path node.
+
+  @return A pointer to device path structure.
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextGenericPath (
+  IN UINT8  Type,
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL *Node;
+  CHAR16                   *SubtypeStr;
+  CHAR16                   *DataStr;
+  UINTN                    DataLength;
+
+  SubtypeStr = GetNextParamStr (&TextDeviceNode);
+  DataStr    = GetNextParamStr (&TextDeviceNode);
+
+  if (DataStr == NULL) {
+    DataLength = 0;
+  } else {
+    DataLength = StrLen (DataStr) / 2;
+  }
+  Node = CreateDeviceNode (
+           Type,
+           (UINT8) Strtoi (SubtypeStr),
+           (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength)
+           );
+
+  StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength);
+  return Node;
+}
+
+/**
+  Converts a generic text device path node to device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                   *TypeStr;
+
+  TypeStr    = GetNextParamStr (&TextDeviceNode);
+
+  return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode);
+}
+
+/**
+  Converts a generic hardware text device path node to Hardware device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to Hardware device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHardwarePath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+  Converts a text device path node to Hardware PCI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to Hardware PCI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *FunctionStr;
+  CHAR16          *DeviceStr;
+  PCI_DEVICE_PATH *Pci;
+
+  DeviceStr   = GetNextParamStr (&TextDeviceNode);
+  FunctionStr = GetNextParamStr (&TextDeviceNode);
+  Pci         = (PCI_DEVICE_PATH *) CreateDeviceNode (
+                                      HARDWARE_DEVICE_PATH,
+                                      HW_PCI_DP,
+                                      (UINT16) sizeof (PCI_DEVICE_PATH)
+                                      );
+
+  Pci->Function = (UINT8) Strtoi (FunctionStr);
+  Pci->Device   = (UINT8) Strtoi (DeviceStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+/**
+  Converts a text device path node to Hardware PC card device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to Hardware PC card device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16              *FunctionNumberStr;
+  PCCARD_DEVICE_PATH  *Pccard;
+
+  FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+  Pccard            = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_PCCARD_DP,
+                                               (UINT16) sizeof (PCCARD_DEVICE_PATH)
+                                               );
+
+  Pccard->FunctionNumber  = (UINT8) Strtoi (FunctionNumberStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+/**
+  Converts a text device path node to Hardware memory map device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to Hardware memory map device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16              *MemoryTypeStr;
+  CHAR16              *StartingAddressStr;
+  CHAR16              *EndingAddressStr;
+  MEMMAP_DEVICE_PATH  *MemMap;
+
+  MemoryTypeStr      = GetNextParamStr (&TextDeviceNode);
+  StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddressStr   = GetNextParamStr (&TextDeviceNode);
+  MemMap             = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_MEMMAP_DP,
+                                               (UINT16) sizeof (MEMMAP_DEVICE_PATH)
+                                               );
+
+  MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr);
+  Strtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+  Strtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+/**
+  Converts a text device path node to Vendor device path structure based on the input Type
+  and SubType.
+
+  @param TextDeviceNode  The input Text device path node.
+  @param Type            The type of device path node.
+  @param SubType         The subtype of device path node.
+
+  @return A pointer to the newly-created Vendor device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+  IN CHAR16 *TextDeviceNode,
+  IN UINT8  Type,
+  IN UINT8  SubType
+  )
+{
+  CHAR16              *GuidStr;
+  CHAR16              *DataStr;
+  UINTN               Length;
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+
+  DataStr = GetNextParamStr (&TextDeviceNode);
+  Length  = StrLen (DataStr);
+  //
+  // Two hex characters make up 1 buffer byte
+  //
+  Length  = (Length + 1) / 2;
+
+  Vendor  = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                     Type,
+                                     SubType,
+                                     (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
+                                     );
+
+  StrToGuid (GuidStr, &Vendor->Guid);
+  StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+  Converts a text device path node to Vendor Hardware device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor Hardware device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextVendor (
+           TextDeviceNode,
+           HARDWARE_DEVICE_PATH,
+           HW_VENDOR_DP
+           );
+}
+
+/**
+  Converts a text device path node to Hardware Controller device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Hardware Controller device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                  *ControllerStr;
+  CONTROLLER_DEVICE_PATH  *Controller;
+
+  ControllerStr = GetNextParamStr (&TextDeviceNode);
+  Controller    = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_CONTROLLER_DP,
+                                               (UINT16) sizeof (CONTROLLER_DEVICE_PATH)
+                                               );
+  Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+/**
+  Converts a text device path node to BMC device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created BMC device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBmc (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *InterfaceTypeStr;
+  CHAR16                *BaseAddressStr;
+  BMC_DEVICE_PATH       *BmcDp;
+
+  InterfaceTypeStr = GetNextParamStr (&TextDeviceNode);
+  BaseAddressStr   = GetNextParamStr (&TextDeviceNode);
+  BmcDp            = (BMC_DEVICE_PATH *) CreateDeviceNode (
+                                           HARDWARE_DEVICE_PATH,
+                                           HW_BMC_DP,
+                                           (UINT16) sizeof (BMC_DEVICE_PATH)
+                                           );
+
+  BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr);
+  WriteUnaligned64 (
+    (UINT64 *) (&BmcDp->BaseAddress),
+    StrHexToUint64 (BaseAddressStr)
+    );
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp;
+}
+
+/**
+  Converts a generic ACPI text device path node to ACPI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to ACPI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiPath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+  Converts a string to EisaId.
+
+  @param Text   The input string.
+
+  @return UINT32 EISA ID.
+**/
+static
+UINT32
+EisaIdFromText (
+  IN CHAR16 *Text
+  )
+{
+  return (((Text[0] - 'A' + 1) & 0x1f) << 10)
+       + (((Text[1] - 'A' + 1) & 0x1f) <<  5)
+       + (((Text[2] - 'A' + 1) & 0x1f) <<  0)
+       + (UINT32) (StrHexToUintn (&Text[3]) << 16)
+       ;
+}
+
+/**
+  Converts a text device path node to ACPI HID device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *HIDStr;
+  CHAR16                *UIDStr;
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  HIDStr = GetNextParamStr (&TextDeviceNode);
+  UIDStr = GetNextParamStr (&TextDeviceNode);
+  Acpi   = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+                                      ACPI_DEVICE_PATH,
+                                      ACPI_DP,
+                                      (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+                                      );
+
+  Acpi->HID = EisaIdFromText (HIDStr);
+  Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+  Converts a text device path node to ACPI HID device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+  @param PnPId           The input plug and play identification.
+
+  @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+  IN CHAR16 *TextDeviceNode,
+  IN UINT32  PnPId
+  )
+{
+  CHAR16                *UIDStr;
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  UIDStr = GetNextParamStr (&TextDeviceNode);
+  Acpi   = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+                                      ACPI_DEVICE_PATH,
+                                      ACPI_DP,
+                                      (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+                                      );
+
+  Acpi->HID = EFI_PNP_ID (PnPId);
+  Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+  Converts a text device path node to PCI root device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created PCI root device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0a03);
+}
+
+/**
+  Converts a text device path node to PCIE root device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created PCIE root device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcieRoot (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0a08);
+}
+
+/**
+  Converts a text device path node to Floppy device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Floppy device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0604);
+}
+
+/**
+  Converts a text device path node to Keyboard device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created  Keyboard device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0301);
+}
+
+/**
+  Converts a text device path node to Serial device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Serial device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0501);
+}
+
+/**
+  Converts a text device path node to Parallel Port device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0401);
+}
+
+/**
+  Converts a text device path node to ACPI extension device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                         *HIDStr;
+  CHAR16                         *CIDStr;
+  CHAR16                         *UIDStr;
+  CHAR16                         *HIDSTRStr;
+  CHAR16                         *CIDSTRStr;
+  CHAR16                         *UIDSTRStr;
+  CHAR8                          *AsciiStr;
+  UINT16                         Length;
+  ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
+
+  HIDStr    = GetNextParamStr (&TextDeviceNode);
+  CIDStr    = GetNextParamStr (&TextDeviceNode);
+  UIDStr    = GetNextParamStr (&TextDeviceNode);
+  HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+
+  Length    = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1);
+  Length    = (UINT16) (Length + StrLen (UIDSTRStr) + 1);
+  Length    = (UINT16) (Length + StrLen (CIDSTRStr) + 1);
+  AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+                                               ACPI_DEVICE_PATH,
+                                               ACPI_EXTENDED_DP,
+                                               Length
+                                               );
+
+  AcpiEx->HID = EisaIdFromText (HIDStr);
+  AcpiEx->CID = EisaIdFromText (CIDStr);
+  AcpiEx->UID = (UINT32) Strtoi (UIDStr);
+
+  AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+  StrToAscii (HIDSTRStr, &AsciiStr);
+  StrToAscii (UIDSTRStr, &AsciiStr);
+  StrToAscii (CIDSTRStr, &AsciiStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+  Converts a text device path node to ACPI extension device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                         *HIDStr;
+  CHAR16                         *CIDStr;
+  CHAR16                         *UIDSTRStr;
+  CHAR8                          *AsciiStr;
+  UINT16                         Length;
+  ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
+
+  HIDStr    = GetNextParamStr (&TextDeviceNode);
+  CIDStr    = GetNextParamStr (&TextDeviceNode);
+  UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  Length    = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3);
+  AcpiEx    = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+                                                  ACPI_DEVICE_PATH,
+                                                  ACPI_EXTENDED_DP,
+                                                  Length
+                                                  );
+
+  AcpiEx->HID = EisaIdFromText (HIDStr);
+  AcpiEx->CID = EisaIdFromText (CIDStr);
+  AcpiEx->UID = 0;
+
+  AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+  //
+  // HID string is NULL
+  //
+  *AsciiStr = '\0';
+  //
+  // Convert UID string
+  //
+  AsciiStr++;
+  StrToAscii (UIDSTRStr, &AsciiStr);
+  //
+  // CID string is NULL
+  //
+  *AsciiStr = '\0';
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+  Converts a text device path node to ACPI _ADR device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created ACPI _ADR device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiAdr (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *DisplayDeviceStr;
+  ACPI_ADR_DEVICE_PATH  *AcpiAdr;
+  UINTN                 Index;
+  UINTN                 Length;
+
+  AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode (
+                                       ACPI_DEVICE_PATH,
+                                       ACPI_ADR_DP,
+                                       (UINT16) sizeof (ACPI_ADR_DEVICE_PATH)
+                                       );
+  ASSERT (AcpiAdr != NULL);
+
+  for (Index = 0; ; Index++) {
+    DisplayDeviceStr = GetNextParamStr (&TextDeviceNode);
+    if (IS_NULL (*DisplayDeviceStr)) {
+      break;
+    }
+    if (Index > 0) {
+      Length  = DevicePathNodeLength (AcpiAdr);
+      AcpiAdr = ReallocatePool (
+                  Length,
+                  Length + sizeof (UINT32),
+                  AcpiAdr
+                  );
+      ASSERT (AcpiAdr != NULL);
+      SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32));
+    }
+
+    (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr);
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr;
+}
+
+/**
+  Converts a generic messaging text device path node to messaging device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to messaging device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMsg (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+  Converts a text device path node to Parallel Port device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+IN CHAR16 *TextDeviceNode
+)
+{
+  CHAR16            *PrimarySecondaryStr;
+  CHAR16            *SlaveMasterStr;
+  CHAR16            *LunStr;
+  ATAPI_DEVICE_PATH *Atapi;
+
+  Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+    MESSAGING_DEVICE_PATH,
+    MSG_ATAPI_DP,
+    (UINT16) sizeof (ATAPI_DEVICE_PATH)
+    );
+
+  PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+  SlaveMasterStr      = GetNextParamStr (&TextDeviceNode);
+  LunStr              = GetNextParamStr (&TextDeviceNode);
+
+  if (StrCmp (PrimarySecondaryStr, "Primary") == 0) {
+    Atapi->PrimarySecondary = 0;
+  } else if (StrCmp (PrimarySecondaryStr, "Secondary") == 0) {
+    Atapi->PrimarySecondary = 1;
+  } else {
+    Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);
+  }
+  if (StrCmp (SlaveMasterStr, "Master") == 0) {
+    Atapi->SlaveMaster      = 0;
+  } else if (StrCmp (SlaveMasterStr, "Slave") == 0) {
+    Atapi->SlaveMaster      = 1;
+  } else {
+    Atapi->SlaveMaster      = (UINT8) Strtoi (SlaveMasterStr);
+  }
+
+  Atapi->Lun                = (UINT16) Strtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+/**
+  Converts a text device path node to SCSI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created SCSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *PunStr;
+  CHAR16            *LunStr;
+  SCSI_DEVICE_PATH  *Scsi;
+
+  PunStr = GetNextParamStr (&TextDeviceNode);
+  LunStr = GetNextParamStr (&TextDeviceNode);
+  Scsi   = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+                                   MESSAGING_DEVICE_PATH,
+                                   MSG_SCSI_DP,
+                                   (UINT16) sizeof (SCSI_DEVICE_PATH)
+                                   );
+
+  Scsi->Pun = (UINT16) Strtoi (PunStr);
+  Scsi->Lun = (UINT16) Strtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+/**
+  Converts a text device path node to Fibre device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Fibre device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                    *WWNStr;
+  CHAR16                    *LunStr;
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  WWNStr = GetNextParamStr (&TextDeviceNode);
+  LunStr = GetNextParamStr (&TextDeviceNode);
+  Fibre  = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+                                          MESSAGING_DEVICE_PATH,
+                                          MSG_FIBRECHANNEL_DP,
+                                          (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH)
+                                          );
+
+  Fibre->Reserved = 0;
+  Strtoi64 (WWNStr, &Fibre->WWN);
+  Strtoi64 (LunStr, &Fibre->Lun);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+/**
+  Converts a text device path node to FibreEx device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created FibreEx device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibreEx (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                      *WWNStr;
+  CHAR16                      *LunStr;
+  FIBRECHANNELEX_DEVICE_PATH  *FibreEx;
+
+  WWNStr  = GetNextParamStr (&TextDeviceNode);
+  LunStr  = GetNextParamStr (&TextDeviceNode);
+  FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode (
+                                             MESSAGING_DEVICE_PATH,
+                                             MSG_FIBRECHANNELEX_DP,
+                                             (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH)
+                                             );
+
+  FibreEx->Reserved = 0;
+  Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN));
+  Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun));
+
+  *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN));
+  *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun));
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx;
+}
+
+/**
+  Converts a text device path node to 1394 device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created 1394 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *GuidStr;
+  F1394_DEVICE_PATH *F1394DevPath;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+  F1394DevPath  = (F1394_DEVICE_PATH *) CreateDeviceNode (
+                                          MESSAGING_DEVICE_PATH,
+                                          MSG_1394_DP,
+                                          (UINT16) sizeof (F1394_DEVICE_PATH)
+                                          );
+
+  F1394DevPath->Reserved = 0;
+  F1394DevPath->Guid     = StrHexToUint64 (GuidStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
+}
+
+/**
+  Converts a text device path node to USB device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *PortStr;
+  CHAR16          *InterfaceStr;
+  USB_DEVICE_PATH *Usb;
+
+  PortStr               = GetNextParamStr (&TextDeviceNode);
+  InterfaceStr          = GetNextParamStr (&TextDeviceNode);
+  Usb                   = (USB_DEVICE_PATH *) CreateDeviceNode (
+                                                MESSAGING_DEVICE_PATH,
+                                                MSG_USB_DP,
+                                                (UINT16) sizeof (USB_DEVICE_PATH)
+                                                );
+
+  Usb->ParentPortNumber = (UINT8) Strtoi (PortStr);
+  Usb->InterfaceNumber  = (UINT8) Strtoi (InterfaceStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+/**
+  Converts a text device path node to I20 device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created I20 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *TIDStr;
+  I2O_DEVICE_PATH *I2ODevPath;
+
+  TIDStr     = GetNextParamStr (&TextDeviceNode);
+  I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_I2O_DP,
+                                    (UINT16) sizeof (I2O_DEVICE_PATH)
+                                    );
+
+  I2ODevPath->Tid  = (UINT32) Strtoi (TIDStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath;
+}
+
+/**
+  Converts a text device path node to Infini Band device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Infini Band device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                  *FlagsStr;
+  CHAR16                  *GuidStr;
+  CHAR16                  *SidStr;
+  CHAR16                  *TidStr;
+  CHAR16                  *DidStr;
+  INFINIBAND_DEVICE_PATH  *InfiniBand;
+
+  FlagsStr   = GetNextParamStr (&TextDeviceNode);
+  GuidStr    = GetNextParamStr (&TextDeviceNode);
+  SidStr     = GetNextParamStr (&TextDeviceNode);
+  TidStr     = GetNextParamStr (&TextDeviceNode);
+  DidStr     = GetNextParamStr (&TextDeviceNode);
+  InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+                                            MESSAGING_DEVICE_PATH,
+                                            MSG_INFINIBAND_DP,
+                                            (UINT16) sizeof (INFINIBAND_DEVICE_PATH)
+                                            );
+
+  InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
+  StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid);
+  Strtoi64 (SidStr, &InfiniBand->ServiceId);
+  Strtoi64 (TidStr, &InfiniBand->TargetPortId);
+  Strtoi64 (DidStr, &InfiniBand->DeviceId);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+/**
+  Converts a text device path node to Vendor-Defined Messaging device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor-Defined Messaging device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextVendor (
+            TextDeviceNode,
+            MESSAGING_DEVICE_PATH,
+            MSG_VENDOR_DP
+            );
+}
+
+/**
+  Converts a text device path node to Vendor defined PC-ANSI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor defined PC-ANSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    (UINT16) sizeof (VENDOR_DEVICE_PATH));
+  CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+  Converts a text device path node to Vendor defined VT100 device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor defined VT100 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    (UINT16) sizeof (VENDOR_DEVICE_PATH));
+  CopyGuid (&Vendor->Guid, &gEfiVT100Guid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+  Converts a text device path node to Vendor defined VT100 Plus device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor defined VT100 Plus device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    (UINT16) sizeof (VENDOR_DEVICE_PATH));
+  CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+  Converts a text device path node to Vendor defined UTF8 device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor defined UTF8 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    (UINT16) sizeof (VENDOR_DEVICE_PATH));
+  CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+  Converts a text device path node to UART Flow Control device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created UART Flow Control device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                        *ValueStr;
+  UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+  ValueStr        = GetNextParamStr (&TextDeviceNode);
+  UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+                                                        MESSAGING_DEVICE_PATH,
+                                                        MSG_VENDOR_DP,
+                                                        (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+                                                        );
+
+  CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid);
+  if (StrCmp (ValueStr, "XonXoff") == 0) {
+    UartFlowControl->FlowControlMap = 2;
+  } else if (StrCmp (ValueStr, "Hardware") == 0) {
+    UartFlowControl->FlowControlMap = 1;
+  } else {
+    UartFlowControl->FlowControlMap = 0;
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+/**
+  Converts a text device path node to Serial Attached SCSI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Serial Attached SCSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *AddressStr;
+  CHAR16          *LunStr;
+  CHAR16          *RTPStr;
+  CHAR16          *SASSATAStr;
+  CHAR16          *LocationStr;
+  CHAR16          *ConnectStr;
+  CHAR16          *DriveBayStr;
+  CHAR16          *ReservedStr;
+  UINT16          Info;
+  UINT16          Uint16;
+  SAS_DEVICE_PATH *Sas;
+
+  AddressStr  = GetNextParamStr (&TextDeviceNode);
+  LunStr      = GetNextParamStr (&TextDeviceNode);
+  RTPStr      = GetNextParamStr (&TextDeviceNode);
+  SASSATAStr  = GetNextParamStr (&TextDeviceNode);
+  LocationStr = GetNextParamStr (&TextDeviceNode);
+  ConnectStr  = GetNextParamStr (&TextDeviceNode);
+  DriveBayStr = GetNextParamStr (&TextDeviceNode);
+  ReservedStr = GetNextParamStr (&TextDeviceNode);
+  Sas         = (SAS_DEVICE_PATH *) CreateDeviceNode (
+                                       MESSAGING_DEVICE_PATH,
+                                       MSG_VENDOR_DP,
+                                       (UINT16) sizeof (SAS_DEVICE_PATH)
+                                       );
+
+  CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid);
+  Strtoi64 (AddressStr, &Sas->SasAddress);
+  Strtoi64 (LunStr, &Sas->Lun);
+  Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+  if (StrCmp (SASSATAStr, "NoTopology") == 0) {
+    Info = 0x0;
+
+  } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) {
+
+    Uint16 = (UINT16) Strtoi (DriveBayStr);
+    if (Uint16 == 0) {
+      Info = 0x1;
+    } else {
+      Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+    }
+
+    if (StrCmp (SASSATAStr, "SATA") == 0) {
+      Info |= BIT4;
+    }
+
+    //
+    // Location is an integer between 0 and 1 or else
+    // the keyword Internal (0) or External (1).
+    //
+    if (StrCmp (LocationStr, "External") == 0) {
+      Uint16 = 1;
+    } else if (StrCmp (LocationStr, "Internal") == 0) {
+      Uint16 = 0;
+    } else {
+      Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+    }
+    Info |= (Uint16 << 5);
+
+    //
+    // Connect is an integer between 0 and 3 or else
+    // the keyword Direct (0) or Expanded (1).
+    //
+    if (StrCmp (ConnectStr, "Expanded") == 0) {
+      Uint16 = 1;
+    } else if (StrCmp (ConnectStr, "Direct") == 0) {
+      Uint16 = 0;
+    } else {
+      Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+    }
+    Info |= (Uint16 << 6);
+
+  } else {
+    Info = (UINT16) Strtoi (SASSATAStr);
+  }
+
+  Sas->DeviceTopology = Info;
+  Sas->Reserved       = (UINT32) Strtoi (ReservedStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+/**
+  Converts a text device path node to Serial Attached SCSI Ex device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Serial Attached SCSI Ex device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSasEx (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *AddressStr;
+  CHAR16            *LunStr;
+  CHAR16            *RTPStr;
+  CHAR16            *SASSATAStr;
+  CHAR16            *LocationStr;
+  CHAR16            *ConnectStr;
+  CHAR16            *DriveBayStr;
+  UINT16            Info;
+  UINT16            Uint16;
+  UINT64            SasAddress;
+  UINT64            Lun;
+  SASEX_DEVICE_PATH *SasEx;
+
+  AddressStr  = GetNextParamStr (&TextDeviceNode);
+  LunStr      = GetNextParamStr (&TextDeviceNode);
+  RTPStr      = GetNextParamStr (&TextDeviceNode);
+  SASSATAStr  = GetNextParamStr (&TextDeviceNode);
+  LocationStr = GetNextParamStr (&TextDeviceNode);
+  ConnectStr  = GetNextParamStr (&TextDeviceNode);
+  DriveBayStr = GetNextParamStr (&TextDeviceNode);
+  SasEx       = (SASEX_DEVICE_PATH *) CreateDeviceNode (
+                                        MESSAGING_DEVICE_PATH,
+                                        MSG_SASEX_DP,
+                                        (UINT16) sizeof (SASEX_DEVICE_PATH)
+                                        );
+
+  Strtoi64 (AddressStr, &SasAddress);
+  Strtoi64 (LunStr,     &Lun);
+  WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress));
+  WriteUnaligned64 ((UINT64 *) &SasEx->Lun,        SwapBytes64 (Lun));
+  SasEx->RelativeTargetPort      = (UINT16) Strtoi (RTPStr);
+
+  if (StrCmp (SASSATAStr, "NoTopology") == 0) {
+    Info = 0x0;
+
+  } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) {
+
+    Uint16 = (UINT16) Strtoi (DriveBayStr);
+    if (Uint16 == 0) {
+      Info = 0x1;
+    } else {
+      Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+    }
+
+    if (StrCmp (SASSATAStr, "SATA") == 0) {
+      Info |= BIT4;
+    }
+
+    //
+    // Location is an integer between 0 and 1 or else
+    // the keyword Internal (0) or External (1).
+    //
+    if (StrCmp (LocationStr, "External") == 0) {
+      Uint16 = 1;
+    } else if (StrCmp (LocationStr, "Internal") == 0) {
+      Uint16 = 0;
+    } else {
+      Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+    }
+    Info |= (Uint16 << 5);
+
+    //
+    // Connect is an integer between 0 and 3 or else
+    // the keyword Direct (0) or Expanded (1).
+    //
+    if (StrCmp (ConnectStr, "Expanded") == 0) {
+      Uint16 = 1;
+    } else if (StrCmp (ConnectStr, "Direct") == 0) {
+      Uint16 = 0;
+    } else {
+      Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+    }
+    Info |= (Uint16 << 6);
+
+  } else {
+    Info = (UINT16) Strtoi (SASSATAStr);
+  }
+
+  SasEx->DeviceTopology = Info;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) SasEx;
+}
+
+/**
+  Converts a text device path node to NVM Express Namespace device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created NVM Express Namespace device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextNVMe (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                     *NamespaceIdStr;
+  CHAR16                     *NamespaceUuidStr;
+  NVME_NAMESPACE_DEVICE_PATH *Nvme;
+  UINT8                      *Uuid;
+  UINTN                      Index;
+
+  NamespaceIdStr   = GetNextParamStr (&TextDeviceNode);
+  NamespaceUuidStr = GetNextParamStr (&TextDeviceNode);
+  Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode (
+    MESSAGING_DEVICE_PATH,
+    MSG_NVME_NAMESPACE_DP,
+    (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH)
+    );
+
+  Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr);
+  Uuid = (UINT8 *) &Nvme->NamespaceUuid;
+
+  Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8);
+  while (Index-- != 0) {
+    Uuid[Index] = (UINT8) StrHexToUintn (SplitStr (&NamespaceUuidStr, '-'));
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Nvme;
+}
+
+/**
+  Converts a text device path node to UFS device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created UFS device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUfs (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *PunStr;
+  CHAR16            *LunStr;
+  UFS_DEVICE_PATH   *Ufs;
+
+  PunStr = GetNextParamStr (&TextDeviceNode);
+  LunStr = GetNextParamStr (&TextDeviceNode);
+  Ufs    = (UFS_DEVICE_PATH *) CreateDeviceNode (
+                                 MESSAGING_DEVICE_PATH,
+                                 MSG_UFS_DP,
+                                 (UINT16) sizeof (UFS_DEVICE_PATH)
+                                 );
+
+  Ufs->Pun = (UINT8) Strtoi (PunStr);
+  Ufs->Lun = (UINT8) Strtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Ufs;
+}
+
+/**
+  Converts a text device path node to SD (Secure Digital) device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created SD device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSd (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *SlotNumberStr;
+  SD_DEVICE_PATH    *Sd;
+
+  SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+  Sd            = (SD_DEVICE_PATH *) CreateDeviceNode (
+                                       MESSAGING_DEVICE_PATH,
+                                       MSG_SD_DP,
+                                       (UINT16) sizeof (SD_DEVICE_PATH)
+                                       );
+
+  Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Sd;
+}
+
+/**
+  Converts a text device path node to EMMC (Embedded MMC) device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created EMMC device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmmc (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *SlotNumberStr;
+  EMMC_DEVICE_PATH  *Emmc;
+
+  SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+  Emmc          = (EMMC_DEVICE_PATH *) CreateDeviceNode (
+                                       MESSAGING_DEVICE_PATH,
+                                       MSG_EMMC_DP,
+                                       (UINT16) sizeof (EMMC_DEVICE_PATH)
+                                       );
+
+  Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Emmc;
+}
+
+/**
+  Converts a text device path node to Debug Port device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Debug Port device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEFINED_MESSAGING_DEVICE_PATH  *Vend;
+
+  Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode (
+                                                    MESSAGING_DEVICE_PATH,
+                                                    MSG_VENDOR_DP,
+                                                    (UINT16) sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+                                                    );
+
+  CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+/**
+  Converts a text device path node to MAC device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created MAC device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *AddressStr;
+  CHAR16                *IfTypeStr;
+  UINTN                 Length;
+  MAC_ADDR_DEVICE_PATH  *MACDevPath;
+
+  AddressStr    = GetNextParamStr (&TextDeviceNode);
+  IfTypeStr     = GetNextParamStr (&TextDeviceNode);
+  MACDevPath    = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+                                              MESSAGING_DEVICE_PATH,
+                                              MSG_MAC_ADDR_DP,
+                                              (UINT16) sizeof (MAC_ADDR_DEVICE_PATH)
+                                              );
+
+  MACDevPath->IfType   = (UINT8) Strtoi (IfTypeStr);
+
+  Length = sizeof (EFI_MAC_ADDRESS);
+  StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
+}
+
+
+/**
+  Converts a text format to the network protocol ID.
+
+  @param Text  String of protocol field.
+
+  @return Network protocol ID .
+
+**/
+static
+UINTN
+NetworkProtocolFromText (
+  IN CHAR16 *Text
+  )
+{
+  if (StrCmp (Text, "UDP") == 0) {
+    return RFC_1700_UDP_PROTOCOL;
+  }
+
+  if (StrCmp (Text, "TCP") == 0) {
+    return RFC_1700_TCP_PROTOCOL;
+  }
+
+  return Strtoi (Text);
+}
+
+
+/**
+  Converts a text device path node to IPV4 device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created IPV4 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *RemoteIPStr;
+  CHAR16            *ProtocolStr;
+  CHAR16            *TypeStr;
+  CHAR16            *LocalIPStr;
+  CHAR16            *GatewayIPStr;
+  CHAR16            *SubnetMaskStr;
+  IPv4_DEVICE_PATH  *IPv4;
+
+  RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
+  ProtocolStr           = GetNextParamStr (&TextDeviceNode);
+  TypeStr               = GetNextParamStr (&TextDeviceNode);
+  LocalIPStr            = GetNextParamStr (&TextDeviceNode);
+  GatewayIPStr          = GetNextParamStr (&TextDeviceNode);
+  SubnetMaskStr         = GetNextParamStr (&TextDeviceNode);
+  IPv4                  = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+                                                 MESSAGING_DEVICE_PATH,
+                                                 MSG_IPv4_DP,
+                                                 (UINT16) sizeof (IPv4_DEVICE_PATH)
+                                                 );
+
+  StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
+  IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+  if (StrCmp (TypeStr, "Static") == 0) {
+    IPv4->StaticIpAddress = TRUE;
+  } else {
+    IPv4->StaticIpAddress = FALSE;
+  }
+
+  StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
+  if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
+    StrToIpv4Address (GatewayIPStr,  NULL, &IPv4->GatewayIpAddress, NULL);
+    StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask,       NULL);
+  } else {
+    ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
+    ZeroMem (&IPv4->SubnetMask,    sizeof (IPv4->SubnetMask));
+  }
+
+  IPv4->LocalPort       = 0;
+  IPv4->RemotePort      = 0;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+/**
+  Converts a text device path node to IPV6 device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created IPV6 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *RemoteIPStr;
+  CHAR16            *ProtocolStr;
+  CHAR16            *TypeStr;
+  CHAR16            *LocalIPStr;
+  CHAR16            *GatewayIPStr;
+  CHAR16            *PrefixLengthStr;
+  IPv6_DEVICE_PATH  *IPv6;
+
+  RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
+  ProtocolStr           = GetNextParamStr (&TextDeviceNode);
+  TypeStr               = GetNextParamStr (&TextDeviceNode);
+  LocalIPStr            = GetNextParamStr (&TextDeviceNode);
+  PrefixLengthStr       = GetNextParamStr (&TextDeviceNode);
+  GatewayIPStr          = GetNextParamStr (&TextDeviceNode);
+  IPv6                  = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+                                                 MESSAGING_DEVICE_PATH,
+                                                 MSG_IPv6_DP,
+                                                 (UINT16) sizeof (IPv6_DEVICE_PATH)
+                                                 );
+
+  StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
+  IPv6->Protocol        = (UINT16) NetworkProtocolFromText (ProtocolStr);
+  if (StrCmp (TypeStr, "Static") == 0) {
+    IPv6->IpAddressOrigin = 0;
+  } else if (StrCmp (TypeStr, "StatelessAutoConfigure") == 0) {
+    IPv6->IpAddressOrigin = 1;
+  } else {
+    IPv6->IpAddressOrigin = 2;
+  }
+
+  StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
+  if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
+    StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
+    IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
+  } else {
+    ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
+    IPv6->PrefixLength = 0;
+  }
+
+  IPv6->LocalPort       = 0;
+  IPv6->RemotePort      = 0;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+/**
+  Converts a text device path node to UART device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created UART device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *BaudStr;
+  CHAR16            *DataBitsStr;
+  CHAR16            *ParityStr;
+  CHAR16            *StopBitsStr;
+  UART_DEVICE_PATH  *Uart;
+
+  BaudStr         = GetNextParamStr (&TextDeviceNode);
+  DataBitsStr     = GetNextParamStr (&TextDeviceNode);
+  ParityStr       = GetNextParamStr (&TextDeviceNode);
+  StopBitsStr     = GetNextParamStr (&TextDeviceNode);
+  Uart            = (UART_DEVICE_PATH *) CreateDeviceNode (
+                                           MESSAGING_DEVICE_PATH,
+                                           MSG_UART_DP,
+                                           (UINT16) sizeof (UART_DEVICE_PATH)
+                                           );
+
+  if (StrCmp (BaudStr, "DEFAULT") == 0) {
+    Uart->BaudRate = 115200;
+  } else {
+    Strtoi64 (BaudStr, &Uart->BaudRate);
+  }
+  Uart->DataBits  = (UINT8) ((StrCmp (DataBitsStr, "DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
+  switch (*ParityStr) {
+  case 'D':
+    Uart->Parity = 0;
+    break;
+
+  case 'N':
+    Uart->Parity = 1;
+    break;
+
+  case 'E':
+    Uart->Parity = 2;
+    break;
+
+  case 'O':
+    Uart->Parity = 3;
+    break;
+
+  case 'M':
+    Uart->Parity = 4;
+    break;
+
+  case 'S':
+    Uart->Parity = 5;
+    break;
+
+  default:
+    Uart->Parity = (UINT8) Strtoi (ParityStr);
+    break;
+  }
+
+  if (StrCmp (StopBitsStr, "D") == 0) {
+    Uart->StopBits = (UINT8) 0;
+  } else if (StrCmp (StopBitsStr, "1") == 0) {
+    Uart->StopBits = (UINT8) 1;
+  } else if (StrCmp (StopBitsStr, "1.5") == 0) {
+    Uart->StopBits = (UINT8) 2;
+  } else if (StrCmp (StopBitsStr, "2") == 0) {
+    Uart->StopBits = (UINT8) 3;
+  } else {
+    Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+/**
+  Converts a text device path node to USB class device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+  @param UsbClassText    A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
+
+  @return A pointer to the newly-created USB class device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+  IN CHAR16         *TextDeviceNode,
+  IN USB_CLASS_TEXT *UsbClassText
+  )
+{
+  CHAR16                *VIDStr;
+  CHAR16                *PIDStr;
+  CHAR16                *ClassStr;
+  CHAR16                *SubClassStr;
+  CHAR16                *ProtocolStr;
+  USB_CLASS_DEVICE_PATH *UsbClass;
+
+  UsbClass    = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+                                            MESSAGING_DEVICE_PATH,
+                                            MSG_USB_CLASS_DP,
+                                            (UINT16) sizeof (USB_CLASS_DEVICE_PATH)
+                                            );
+
+  VIDStr      = GetNextParamStr (&TextDeviceNode);
+  PIDStr      = GetNextParamStr (&TextDeviceNode);
+  if (UsbClassText->ClassExist) {
+    ClassStr = GetNextParamStr (&TextDeviceNode);
+    UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
+  } else {
+    UsbClass->DeviceClass = UsbClassText->Class;
+  }
+  if (UsbClassText->SubClassExist) {
+    SubClassStr = GetNextParamStr (&TextDeviceNode);
+    UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
+  } else {
+    UsbClass->DeviceSubClass = UsbClassText->SubClass;
+  }
+
+  ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+  UsbClass->VendorId        = (UINT16) Strtoi (VIDStr);
+  UsbClass->ProductId       = (UINT16) Strtoi (PIDStr);
+  UsbClass->DeviceProtocol  = (UINT8) Strtoi (ProtocolStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+/**
+  Converts a text device path node to USB class device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB class device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = TRUE;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB audio device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB audio device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_AUDIO;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB CDC Control device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB CDC Control device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_CDCCONTROL;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB HID device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB HID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_HID;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB Image device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB Image device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_IMAGE;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB Print device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB Print device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_PRINTER;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB mass storage device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB mass storage device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_MASS_STORAGE;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB HUB device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB HUB device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_HUB;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB CDC data device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB CDC data device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_CDCDATA;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB smart card device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB smart card device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_SMART_CARD;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB video device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB video device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_VIDEO;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB diagnostic device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB diagnostic device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_DIAGNOSTIC;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB wireless device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB wireless device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_WIRELESS;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB device firmware update device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB device firmware update device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_RESERVE;
+  UsbClassText.SubClassExist = FALSE;
+  UsbClassText.SubClass      = USB_SUBCLASS_FW_UPDATE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB IRDA bridge device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB IRDA bridge device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_RESERVE;
+  UsbClassText.SubClassExist = FALSE;
+  UsbClassText.SubClass      = USB_SUBCLASS_IRDA_BRIDGE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB text and measurement device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB text and measurement device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_RESERVE;
+  UsbClassText.SubClassExist = FALSE;
+  UsbClassText.SubClass      = USB_SUBCLASS_TEST;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+  Converts a text device path node to USB WWID device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created USB WWID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *VIDStr;
+  CHAR16                *PIDStr;
+  CHAR16                *InterfaceNumStr;
+  CHAR16                *SerialNumberStr;
+  USB_WWID_DEVICE_PATH  *UsbWwid;
+  UINTN                 SerialNumberStrLen;
+
+  VIDStr                   = GetNextParamStr (&TextDeviceNode);
+  PIDStr                   = GetNextParamStr (&TextDeviceNode);
+  InterfaceNumStr          = GetNextParamStr (&TextDeviceNode);
+  SerialNumberStr          = GetNextParamStr (&TextDeviceNode);
+  SerialNumberStrLen       = StrLen (SerialNumberStr);
+  if (SerialNumberStrLen >= 2 &&
+      SerialNumberStr[0] == '\"' &&
+      SerialNumberStr[SerialNumberStrLen - 1] == '\"'
+    ) {
+    SerialNumberStr[SerialNumberStrLen - 1] = '\0';
+    SerialNumberStr++;
+    SerialNumberStrLen -= 2;
+  }
+  UsbWwid                  = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+                                                         MESSAGING_DEVICE_PATH,
+                                                         MSG_USB_WWID_DP,
+                                                         (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
+                                                         );
+  UsbWwid->VendorId        = (UINT16) Strtoi (VIDStr);
+  UsbWwid->ProductId       = (UINT16) Strtoi (PIDStr);
+  UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
+
+  //
+  // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr.
+  // Therefore, the '\0' will not be copied.
+  //
+  CopyMem (
+    (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH),
+    SerialNumberStr,
+    SerialNumberStrLen * sizeof (CHAR16)
+    );
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+/**
+  Converts a text device path node to Logic Unit device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Logic Unit device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                          *LunStr;
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+  LunStr      = GetNextParamStr (&TextDeviceNode);
+  LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+                                                      MESSAGING_DEVICE_PATH,
+                                                      MSG_DEVICE_LOGICAL_UNIT_DP,
+                                                      (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+                                                      );
+
+  LogicalUnit->Lun  = (UINT8) Strtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+/**
+  Converts a text device path node to iSCSI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created iSCSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  UINT16                      Options;
+  CHAR16                      *NameStr;
+  CHAR16                      *PortalGroupStr;
+  CHAR16                      *LunStr;
+  CHAR16                      *HeaderDigestStr;
+  CHAR16                      *DataDigestStr;
+  CHAR16                      *AuthenticationStr;
+  CHAR16                      *ProtocolStr;
+  CHAR8                       *AsciiStr;
+  ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+
+  NameStr           = GetNextParamStr (&TextDeviceNode);
+  PortalGroupStr    = GetNextParamStr (&TextDeviceNode);
+  LunStr            = GetNextParamStr (&TextDeviceNode);
+  HeaderDigestStr   = GetNextParamStr (&TextDeviceNode);
+  DataDigestStr     = GetNextParamStr (&TextDeviceNode);
+  AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+  ProtocolStr       = GetNextParamStr (&TextDeviceNode);
+  ISCSIDevPath      = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+                                                        MESSAGING_DEVICE_PATH,
+                                                        MSG_ISCSI_DP,
+                                                        (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
+                                                        );
+
+  AsciiStr = ISCSIDevPath->TargetName;
+  StrToAscii (NameStr, &AsciiStr);
+
+  ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
+  Strtoi64 (LunStr, &ISCSIDevPath->Lun);
+
+  Options = 0x0000;
+  if (StrCmp (HeaderDigestStr, "CRC32C") == 0) {
+    Options |= 0x0002;
+  }
+
+  if (StrCmp (DataDigestStr, "CRC32C") == 0) {
+    Options |= 0x0008;
+  }
+
+  if (StrCmp (AuthenticationStr, "None") == 0) {
+    Options |= 0x0800;
+  }
+
+  if (StrCmp (AuthenticationStr, "CHAP_UNI") == 0) {
+    Options |= 0x1000;
+  }
+
+  ISCSIDevPath->LoginOption      = (UINT16) Options;
+
+  ISCSIDevPath->NetworkProtocol  = (UINT16) StrCmp (ProtocolStr, "TCP");
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
+}
+
+/**
+  Converts a text device path node to VLAN device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created VLAN device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVlan (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *VlanStr;
+  VLAN_DEVICE_PATH  *Vlan;
+
+  VlanStr = GetNextParamStr (&TextDeviceNode);
+  Vlan    = (VLAN_DEVICE_PATH *) CreateDeviceNode (
+                                   MESSAGING_DEVICE_PATH,
+                                   MSG_VLAN_DP,
+                                   (UINT16) sizeof (VLAN_DEVICE_PATH)
+                                   );
+
+  Vlan->VlanId = (UINT16) Strtoi (VlanStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
+}
+
+/**
+  Converts a text device path node to Bluetooth device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Bluetooth device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBluetooth (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                  *BluetoothStr;
+  CHAR16                  *Walker;
+  CHAR16                  *TempNumBuffer;
+  UINTN                   TempBufferSize;
+  INT32                   Index;
+  BLUETOOTH_DEVICE_PATH   *BluetoothDp;
+
+  BluetoothStr = GetNextParamStr (&TextDeviceNode);
+  BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode (
+                                   MESSAGING_DEVICE_PATH,
+                                   MSG_BLUETOOTH_DP,
+                                   (UINT16) sizeof (BLUETOOTH_DEVICE_PATH)
+                                   );
+
+  Index = sizeof (BLUETOOTH_ADDRESS) - 1;
+  Walker = BluetoothStr;
+  while (!IS_NULL(*Walker) && Index >= 0) {
+    TempBufferSize = 2 * sizeof(CHAR16) + StrSize("0x");
+    TempNumBuffer = AllocateZeroPool (TempBufferSize);
+    if (TempNumBuffer == NULL) {
+      break;
+    }
+    StrCpyS (TempNumBuffer, TempBufferSize / sizeof (CHAR16), "0x");
+    StrnCatS (TempNumBuffer, TempBufferSize / sizeof (CHAR16), Walker, 2);
+    BluetoothDp->BD_ADDR.Address[Index] = (UINT8)Strtoi (TempNumBuffer);
+    FreePool (TempNumBuffer);
+    Walker += 2;
+    Index--;
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp;
+}
+
+/**
+  Converts a text device path node to Wi-Fi device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Wi-Fi device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextWiFi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *SSIdStr;
+  CHAR8                 AsciiStr[33];
+  UINTN                 DataLen;
+  WIFI_DEVICE_PATH      *WiFiDp;
+
+  SSIdStr = GetNextParamStr (&TextDeviceNode);
+  WiFiDp  = (WIFI_DEVICE_PATH *) CreateDeviceNode (
+                                   MESSAGING_DEVICE_PATH,
+                                   MSG_WIFI_DP,
+                                   (UINT16) sizeof (WIFI_DEVICE_PATH)
+                                   );
+
+  if (NULL != SSIdStr) {
+    DataLen = StrLen (SSIdStr);
+    if (StrLen (SSIdStr) > 32) {
+      SSIdStr[32] = '\0';
+      DataLen     = 32;
+    }
+
+    UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr));
+    CopyMem (WiFiDp->SSId, AsciiStr, DataLen);
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp;
+}
+
+/**
+  Converts a text device path node to URI device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created URI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUri (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16           *UriStr;
+  UINTN            UriLength;
+  URI_DEVICE_PATH  *Uri;
+
+  UriStr = GetNextParamStr (&TextDeviceNode);
+  UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH));
+  Uri    = (URI_DEVICE_PATH *) CreateDeviceNode (
+                                 MESSAGING_DEVICE_PATH,
+                                 MSG_URI_DP,
+                                 (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength)
+                                 );
+
+  while (UriLength-- != 0) {
+    Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength];
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Uri;
+}
+
+/**
+  Converts a media text device path node to media device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to media device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMediaPath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+  Converts a text device path node to HD device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created HD device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *PartitionStr;
+  CHAR16                *TypeStr;
+  CHAR16                *SignatureStr;
+  CHAR16                *StartStr;
+  CHAR16                *SizeStr;
+  UINT32                Signature32;
+  HARDDRIVE_DEVICE_PATH *Hd;
+
+  PartitionStr        = GetNextParamStr (&TextDeviceNode);
+  TypeStr             = GetNextParamStr (&TextDeviceNode);
+  SignatureStr        = GetNextParamStr (&TextDeviceNode);
+  StartStr            = GetNextParamStr (&TextDeviceNode);
+  SizeStr             = GetNextParamStr (&TextDeviceNode);
+  Hd                  = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+                                                    MEDIA_DEVICE_PATH,
+                                                    MEDIA_HARDDRIVE_DP,
+                                                    (UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
+                                                    );
+
+  Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
+
+  ZeroMem (Hd->Signature, 16);
+  Hd->MBRType = (UINT8) 0;
+
+  if (StrCmp (TypeStr, "MBR") == 0) {
+    Hd->SignatureType = SIGNATURE_TYPE_MBR;
+    Hd->MBRType       = 0x01;
+
+    Signature32       = (UINT32) Strtoi (SignatureStr);
+    CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
+  } else if (StrCmp (TypeStr, "GPT") == 0) {
+    Hd->SignatureType = SIGNATURE_TYPE_GUID;
+    Hd->MBRType       = 0x02;
+
+    StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
+  } else {
+    Hd->SignatureType = (UINT8) Strtoi (TypeStr);
+  }
+
+  Strtoi64 (StartStr, &Hd->PartitionStart);
+  Strtoi64 (SizeStr, &Hd->PartitionSize);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+/**
+  Converts a text device path node to CDROM device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created CDROM device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *EntryStr;
+  CHAR16            *StartStr;
+  CHAR16            *SizeStr;
+  CDROM_DEVICE_PATH *CDROMDevPath;
+
+  EntryStr              = GetNextParamStr (&TextDeviceNode);
+  StartStr              = GetNextParamStr (&TextDeviceNode);
+  SizeStr               = GetNextParamStr (&TextDeviceNode);
+  CDROMDevPath          = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+                                                  MEDIA_DEVICE_PATH,
+                                                  MEDIA_CDROM_DP,
+                                                  (UINT16) sizeof (CDROM_DEVICE_PATH)
+                                                  );
+
+  CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
+  Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
+  Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
+}
+
+/**
+  Converts a text device path node to Vendor-defined media device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Vendor-defined media device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMedia (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextVendor (
+           TextDeviceNode,
+           MEDIA_DEVICE_PATH,
+           MEDIA_VENDOR_DP
+           );
+}
+
+/**
+  Converts a text device path node to File device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created File device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  FILEPATH_DEVICE_PATH  *File;
+
+#ifndef __DragonFly__
+  File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+                                    MEDIA_DEVICE_PATH,
+                                    MEDIA_FILEPATH_DP,
+                                    (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
+                                    );
+
+  StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
+#else
+  File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+                                    MEDIA_DEVICE_PATH,
+                                    MEDIA_FILEPATH_DP,
+                                    (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) + 1)
+                                    );
+
+  /* 
+   * Note: We'd have to change the Tianocore header files to fix this
+   * to not need a cast.  Instead we just cast it here. The Interface
+   * to the user may have issues since this won't be a UCS-2
+   * string. Also note that in the original code, a NUL wasn't
+   * allocated for the end of the string, but we copy that below. This
+   * has been corrected.
+   */
+  StrCpyS ((char *)File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
+#endif
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+/**
+  Converts a text device path node to Media protocol device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Media protocol device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                      *GuidStr;
+  MEDIA_PROTOCOL_DEVICE_PATH  *Media;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+  Media   = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+                                             MEDIA_DEVICE_PATH,
+                                             MEDIA_PROTOCOL_DP,
+                                             (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+                                             );
+
+  StrToGuid (GuidStr, &Media->Protocol);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+/**
+  Converts a text device path node to firmware volume device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created firmware volume device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFv (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                    *GuidStr;
+  MEDIA_FW_VOL_DEVICE_PATH  *Fv;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+  Fv      = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode (
+                                           MEDIA_DEVICE_PATH,
+                                           MEDIA_PIWG_FW_VOL_DP,
+                                           (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
+                                           );
+
+  StrToGuid (GuidStr, &Fv->FvName);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
+}
+
+/**
+  Converts a text device path node to firmware file device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created firmware file device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFvFile (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                             *GuidStr;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFile;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+  FvFile  = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+                                                    MEDIA_DEVICE_PATH,
+                                                    MEDIA_PIWG_FW_FILE_DP,
+                                                    (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+                                                    );
+
+  StrToGuid (GuidStr, &FvFile->FvFileName);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
+}
+
+/**
+  Converts a text device path node to text relative offset device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRelativeOffsetRange (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *StartingOffsetStr;
+  CHAR16                                  *EndingOffsetStr;
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+  StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
+  EndingOffsetStr   = GetNextParamStr (&TextDeviceNode);
+  Offset            = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
+                                                                    MEDIA_DEVICE_PATH,
+                                                                    MEDIA_RELATIVE_OFFSET_RANGE_DP,
+                                                                    (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
+                                                                    );
+
+  Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
+  Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
+}
+
+/**
+  Converts a text device path node to text ram disk device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRamDisk (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *StartingAddrStr;
+  CHAR16                                  *EndingAddrStr;
+  CHAR16                                  *TypeGuidStr;
+  CHAR16                                  *InstanceStr;
+  MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
+  UINT64                                  StartingAddr;
+  UINT64                                  EndingAddr;
+
+  StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
+  InstanceStr     = GetNextParamStr (&TextDeviceNode);
+  TypeGuidStr     = GetNextParamStr (&TextDeviceNode);
+  RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+                                                     MEDIA_DEVICE_PATH,
+                                                     MEDIA_RAM_DISK_DP,
+                                                     (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+                                                     );
+
+  Strtoi64 (StartingAddrStr, &StartingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+  Strtoi64 (EndingAddrStr, &EndingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+  RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+  StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+  Converts a text device path node to text virtual disk device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualDisk (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *StartingAddrStr;
+  CHAR16                                  *EndingAddrStr;
+  CHAR16                                  *InstanceStr;
+  MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
+  UINT64                                  StartingAddr;
+  UINT64                                  EndingAddr;
+
+  StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
+  InstanceStr     = GetNextParamStr (&TextDeviceNode);
+
+  RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+                                                     MEDIA_DEVICE_PATH,
+                                                     MEDIA_RAM_DISK_DP,
+                                                     (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+                                                     );
+
+  Strtoi64 (StartingAddrStr, &StartingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+  Strtoi64 (EndingAddrStr, &EndingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+  RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+  CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+  Converts a text device path node to text virtual cd device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualCd (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *StartingAddrStr;
+  CHAR16                                  *EndingAddrStr;
+  CHAR16                                  *InstanceStr;
+  MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
+  UINT64                                  StartingAddr;
+  UINT64                                  EndingAddr;
+
+  StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
+  InstanceStr     = GetNextParamStr (&TextDeviceNode);
+
+  RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+                                                     MEDIA_DEVICE_PATH,
+                                                     MEDIA_RAM_DISK_DP,
+                                                     (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+                                                     );
+
+  Strtoi64 (StartingAddrStr, &StartingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+  Strtoi64 (EndingAddrStr, &EndingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+  RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+  CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+  Converts a text device path node to text persistent virtual disk device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualDisk (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *StartingAddrStr;
+  CHAR16                                  *EndingAddrStr;
+  CHAR16                                  *InstanceStr;
+  MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
+  UINT64                                  StartingAddr;
+  UINT64                                  EndingAddr;
+
+  StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
+  InstanceStr     = GetNextParamStr (&TextDeviceNode);
+
+  RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+                                                     MEDIA_DEVICE_PATH,
+                                                     MEDIA_RAM_DISK_DP,
+                                                     (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+                                                     );
+
+  Strtoi64 (StartingAddrStr, &StartingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+  Strtoi64 (EndingAddrStr, &EndingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+  RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+  CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+  Converts a text device path node to text persistent virtual cd device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualCd (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *StartingAddrStr;
+  CHAR16                                  *EndingAddrStr;
+  CHAR16                                  *InstanceStr;
+  MEDIA_RAM_DISK_DEVICE_PATH              *RamDisk;
+  UINT64                                  StartingAddr;
+  UINT64                                  EndingAddr;
+
+  StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddrStr   = GetNextParamStr (&TextDeviceNode);
+  InstanceStr     = GetNextParamStr (&TextDeviceNode);
+
+  RamDisk         = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+                                                     MEDIA_DEVICE_PATH,
+                                                     MEDIA_RAM_DISK_DP,
+                                                     (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+                                                     );
+
+  Strtoi64 (StartingAddrStr, &StartingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+  Strtoi64 (EndingAddrStr, &EndingAddr);
+  WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+  RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+  CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+  Converts a BBS text device path node to BBS device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to BBS device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBbsPath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+  Converts a text device path node to BIOS Boot Specification device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created BIOS Boot Specification device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16              *TypeStr;
+  CHAR16              *IdStr;
+  CHAR16              *FlagsStr;
+  CHAR8               *AsciiStr;
+  BBS_BBS_DEVICE_PATH *Bbs;
+
+  TypeStr   = GetNextParamStr (&TextDeviceNode);
+  IdStr     = GetNextParamStr (&TextDeviceNode);
+  FlagsStr  = GetNextParamStr (&TextDeviceNode);
+  Bbs       = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+                                        BBS_DEVICE_PATH,
+                                        BBS_BBS_DP,
+                                        (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
+                                        );
+
+  if (StrCmp (TypeStr, "Floppy") == 0) {
+    Bbs->DeviceType = BBS_TYPE_FLOPPY;
+  } else if (StrCmp (TypeStr, "HD") == 0) {
+    Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+  } else if (StrCmp (TypeStr, "CDROM") == 0) {
+    Bbs->DeviceType = BBS_TYPE_CDROM;
+  } else if (StrCmp (TypeStr, "PCMCIA") == 0) {
+    Bbs->DeviceType = BBS_TYPE_PCMCIA;
+  } else if (StrCmp (TypeStr, "USB") == 0) {
+    Bbs->DeviceType = BBS_TYPE_USB;
+  } else if (StrCmp (TypeStr, "Network") == 0) {
+    Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+  } else {
+    Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
+  }
+
+  AsciiStr = Bbs->String;
+  StrToAscii (IdStr, &AsciiStr);
+
+  Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+/**
+  Converts a text device path node to SATA device path structure.
+
+  @param TextDeviceNode  The input Text device path node.
+
+  @return A pointer to the newly-created SATA device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSata (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  SATA_DEVICE_PATH *Sata;
+  CHAR16           *Param1;
+  CHAR16           *Param2;
+  CHAR16           *Param3;
+
+  Param1 = GetNextParamStr (&TextDeviceNode);
+  Param2 = GetNextParamStr (&TextDeviceNode);
+  Param3 = GetNextParamStr (&TextDeviceNode);
+
+  Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
+                                MESSAGING_DEVICE_PATH,
+                                MSG_SATA_DP,
+                                (UINT16) sizeof (SATA_DEVICE_PATH)
+                                );
+  Sata->HBAPortNumber            = (UINT16) Strtoi (Param1);
+  Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
+  Sata->Lun                      = (UINT16) Strtoi (Param3);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
+  {"Path",                    DevPathFromTextPath                    },
+
+  {"HardwarePath",            DevPathFromTextHardwarePath            },
+  {"Pci",                     DevPathFromTextPci                     },
+  {"PcCard",                  DevPathFromTextPcCard                  },
+  {"MemoryMapped",            DevPathFromTextMemoryMapped            },
+  {"VenHw",                   DevPathFromTextVenHw                   },
+  {"Ctrl",                    DevPathFromTextCtrl                    },
+  {"BMC",                     DevPathFromTextBmc                     },
+
+  {"AcpiPath",                DevPathFromTextAcpiPath                },
+  {"Acpi",                    DevPathFromTextAcpi                    },
+  {"PciRoot",                 DevPathFromTextPciRoot                 },
+  {"PcieRoot",                DevPathFromTextPcieRoot                },
+  {"Floppy",                  DevPathFromTextFloppy                  },
+  {"Keyboard",                DevPathFromTextKeyboard                },
+  {"Serial",                  DevPathFromTextSerial                  },
+  {"ParallelPort",            DevPathFromTextParallelPort            },
+  {"AcpiEx",                  DevPathFromTextAcpiEx                  },
+  {"AcpiExp",                 DevPathFromTextAcpiExp                 },
+  {"AcpiAdr",                 DevPathFromTextAcpiAdr                 },
+
+  {"Msg",                     DevPathFromTextMsg                     },
+  {"Ata",                     DevPathFromTextAta                     },
+  {"Scsi",                    DevPathFromTextScsi                    },
+  {"Fibre",                   DevPathFromTextFibre                   },
+  {"FibreEx",                 DevPathFromTextFibreEx                 },
+  {"I1394",                   DevPathFromText1394                    },
+  {"USB",                     DevPathFromTextUsb                     },
+  {"I2O",                     DevPathFromTextI2O                     },
+  {"Infiniband",              DevPathFromTextInfiniband              },
+  {"VenMsg",                  DevPathFromTextVenMsg                  },
+  {"VenPcAnsi",               DevPathFromTextVenPcAnsi               },
+  {"VenVt100",                DevPathFromTextVenVt100                },
+  {"VenVt100Plus",            DevPathFromTextVenVt100Plus            },
+  {"VenUtf8",                 DevPathFromTextVenUtf8                 },
+  {"UartFlowCtrl",            DevPathFromTextUartFlowCtrl            },
+  {"SAS",                     DevPathFromTextSAS                     },
+  {"SasEx",                   DevPathFromTextSasEx                   },
+  {"NVMe",                    DevPathFromTextNVMe                    },
+  {"UFS",                     DevPathFromTextUfs                     },
+  {"SD",                      DevPathFromTextSd                      },
+  {"eMMC",                    DevPathFromTextEmmc                    },
+  {"DebugPort",               DevPathFromTextDebugPort               },
+  {"MAC",                     DevPathFromTextMAC                     },
+  {"IPv4",                    DevPathFromTextIPv4                    },
+  {"IPv6",                    DevPathFromTextIPv6                    },
+  {"Uart",                    DevPathFromTextUart                    },
+  {"UsbClass",                DevPathFromTextUsbClass                },
+  {"UsbAudio",                DevPathFromTextUsbAudio                },
+  {"UsbCDCControl",           DevPathFromTextUsbCDCControl           },
+  {"UsbHID",                  DevPathFromTextUsbHID                  },
+  {"UsbImage",                DevPathFromTextUsbImage                },
+  {"UsbPrinter",              DevPathFromTextUsbPrinter              },
+  {"UsbMassStorage",          DevPathFromTextUsbMassStorage          },
+  {"UsbHub",                  DevPathFromTextUsbHub                  },
+  {"UsbCDCData",              DevPathFromTextUsbCDCData              },
+  {"UsbSmartCard",            DevPathFromTextUsbSmartCard            },
+  {"UsbVideo",                DevPathFromTextUsbVideo                },
+  {"UsbDiagnostic",           DevPathFromTextUsbDiagnostic           },
+  {"UsbWireless",             DevPathFromTextUsbWireless             },
+  {"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
+  {"UsbIrdaBridge",           DevPathFromTextUsbIrdaBridge           },
+  {"UsbTestAndMeasurement",   DevPathFromTextUsbTestAndMeasurement   },
+  {"UsbWwid",                 DevPathFromTextUsbWwid                 },
+  {"Unit",                    DevPathFromTextUnit                    },
+  {"iSCSI",                   DevPathFromTextiSCSI                   },
+  {"Vlan",                    DevPathFromTextVlan                    },
+  {"Uri",                     DevPathFromTextUri                     },
+  {"Bluetooth",               DevPathFromTextBluetooth               },
+  {"Wi-Fi",                   DevPathFromTextWiFi                    },
+  {"MediaPath",               DevPathFromTextMediaPath               },
+  {"HD",                      DevPathFromTextHD                      },
+  {"CDROM",                   DevPathFromTextCDROM                   },
+  {"VenMedia",                DevPathFromTextVenMedia                },
+  {"Media",                   DevPathFromTextMedia                   },
+  {"Fv",                      DevPathFromTextFv                      },
+  {"FvFile",                  DevPathFromTextFvFile                  },
+  {"Offset",                  DevPathFromTextRelativeOffsetRange     },
+  {"RamDisk",                 DevPathFromTextRamDisk                 },
+  {"VirtualDisk",             DevPathFromTextVirtualDisk             },
+  {"VirtualCD",               DevPathFromTextVirtualCd               },
+  {"PersistentVirtualDisk",   DevPathFromTextPersistentVirtualDisk   },
+  {"PersistentVirtualCD",     DevPathFromTextPersistentVirtualCd     },
+
+  {"BbsPath",                 DevPathFromTextBbsPath                 },
+  {"BBS",                     DevPathFromTextBBS                     },
+  {"Sata",                    DevPathFromTextSata                    },
+  {NULL, NULL}
+};
+
+/**
+  Convert text to the binary representation of a device node.
+
+  @param TextDeviceNode  TextDeviceNode points to the text representation of a device
+                         node. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+          insufficient memory or text unsupported.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDeviceNode (
+  IN CONST CHAR16 *TextDeviceNode
+  )
+{
+  DEVICE_PATH_FROM_TEXT    FromText;
+  CHAR16                   *ParamStr;
+  EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+  CHAR16                   *DeviceNodeStr;
+  UINTN                    Index;
+
+  if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+    return NULL;
+  }
+
+  ParamStr      = NULL;
+  FromText      = NULL;
+  DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
+  ASSERT (DeviceNodeStr != NULL);
+
+  for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
+    ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
+    if (ParamStr != NULL) {
+      FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
+      break;
+    }
+  }
+
+  if (FromText == NULL) {
+    //
+    // A file path
+    //
+    FromText = DevPathFromTextFilePath;
+    DeviceNode = FromText (DeviceNodeStr);
+  } else {
+    DeviceNode = FromText (ParamStr);
+    FreePool (ParamStr);
+  }
+
+  FreePool (DeviceNodeStr);
+
+  return DeviceNode;
+}
+
+/**
+  Convert text to the binary representation of a device path.
+
+
+  @param TextDevicePath  TextDevicePath points to the text representation of a device
+                         path. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+          there was insufficient memory.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDevicePath (
+  IN CONST CHAR16 *TextDevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+  EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+  CHAR16                   *DevicePathStr;
+  CHAR16                   *Str;
+  CHAR16                   *DeviceNodeStr;
+  BOOLEAN                  IsInstanceEnd;
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+  if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+    return NULL;
+  }
+
+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+  ASSERT (DevicePath != NULL);
+  SetDevicePathEndNode (DevicePath);
+
+  DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
+
+  Str           = DevicePathStr;
+  while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+    DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
+
+    NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+    FreePool (DevicePath);
+    FreePool (DeviceNode);
+    DevicePath = NewDevicePath;
+
+    if (IsInstanceEnd) {
+      DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+      ASSERT (DeviceNode != NULL);
+      SetDevicePathEndNode (DeviceNode);
+      // Fix from https://bugzilla.tianocore.org/show_bug.cgi?id=419
+      DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+      NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+      FreePool (DevicePath);
+      FreePool (DeviceNode);
+      DevicePath = NewDevicePath;
+    }
+  }
+
+  FreePool (DevicePathStr);
+  return DevicePath;
+}
+
+ssize_t
+efidp_parse_device_path(char *path, efidp out, size_t max)
+{
+	EFI_DEVICE_PATH_PROTOCOL *dp;
+	UINTN len;
+
+	dp = UefiDevicePathLibConvertTextToDevicePath (path);
+	if (dp == NULL)
+		return -1;
+	len = GetDevicePathSize(dp);
+	if (len > max) {
+		free(dp);
+		return -1;
+	}
+	memcpy(out, dp, len);
+	free(dp);
+
+	return len;
+}
diff --git a/lib/libefivar/efivar-dp.h b/lib/libefivar/efivar-dp.h
new file mode 100644
index 0000000000..5f60e1d07f
--- /dev/null
+++ b/lib/libefivar/efivar-dp.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/libefivar/efivar-dp.h 314926 2017-03-09 00:31:31Z imp $
+ */
+
+#ifndef	_EFIVAR_DP_H_
+#define	_EFIVAR_DP_H_
+
+/*
+ * "Linux compatible" efivar-dp.h header. At the moment, it's really a
+ * very thin, minimal interface.
+ */
+
+/*
+ * Generic EFI_DEVICE_PATH, spelled the Linux way. We use this
+ * interface to the outside world and type-pun to the EFI EDK2 code
+ * we use to implement it.
+ */
+typedef struct {
+	uint8_t type;
+	uint8_t subtype;
+	uint16_t length;
+} __packed efidp_header;
+
+/* NB: Linux has shadow types for all dp type */
+
+typedef union {
+        efidp_header header;
+} efidp_data;
+typedef efidp_data *efidp;
+typedef const efidp_data *const_efidp;
+
+/** format a device path into UEFI standard conforming output.
+ *
+ * NB: FreeBSD's implementation is taken from EDK2, while Linux's
+ * was hand-rolled. There may be differences as a result.
+ */
+ssize_t efidp_format_device_path(char *buf, size_t len, const_efidp dp,
+    ssize_t max);
+ssize_t efidp_parse_device_path(char *path, efidp out, size_t max);
+
+#endif /* _EFIVAR_DP_H_ */
diff --git a/lib/libefivar/efivar.3 b/lib/libefivar/efivar.3
index a017981164..906ad63cd6 100644
--- a/lib/libefivar/efivar.3
+++ b/lib/libefivar/efivar.3
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD: head/lib/libefivar/efivar.3 307071 2016-10-11 22:30:41Z imp $
 .\"
-.Dd September 14, 2016
+.Dd May 31, 2017
 .Dt LIBEFIVAR 3
 .Os
 .Sh NAME
@@ -92,6 +92,7 @@ and
 .Fn efi_guid_to_symbol
 This function is not actually implemented.
 .Sh SEE ALSO
+.Xr efidp 8 ,
 .Xr efivar 8
 .Sh AUTHORS
 .An -nosplit
diff --git a/lib/libefivar/efivar.c b/lib/libefivar/efivar.c
index 6936e738ed..0f182fe1d2 100644
--- a/lib/libefivar/efivar.c
+++ b/lib/libefivar/efivar.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libefivar/efivar.c 307189 2016-10-13 06:56:23Z imp $");
+__FBSDID("$FreeBSD: head/lib/libefivar/efivar.c 314925 2017-03-09 00:24:01Z imp $");
 
 #include <efivar.h>
 #include <sys/efiio.h>
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD: head/lib/libefivar/efivar.c 307189 2016-10-13 06:56:23Z imp
 #include <stdlib.h>
 #include <string.h>
 
-#include "libefivar_int.h"
+#include "efichar.h"
 
 static int efi_fd = -2;
 
@@ -44,12 +44,7 @@ static int efi_fd = -2;
 
 const efi_guid_t efi_guid_empty = Z;
 
-static struct uuid_table
-{
-	const char *uuid_str;
-	const char *name;
-	efi_guid_t guid;
-} guid_tbl [] =
+static struct uuid_table guid_tbl [] =
 {
 	{ "00000000-0000-0000-0000-000000000000", "zero", Z },
 	{ "093e0fae-a6c4-4f50-9f1b-d41e2b89c19a", "sha512", Z },
@@ -92,7 +87,10 @@ efi_guid_tbl_compile(void)
 {
 	size_t i;
 	uint32_t status;
+	static int done = 0;
 
+	if (done)
+		return;
 	for (i = 0; i < nitems(guid_tbl); i++) {
 		uuid_from_string(guid_tbl[i].uuid_str, &guid_tbl[i].guid,
 		    &status);
@@ -101,6 +99,15 @@ efi_guid_tbl_compile(void)
 			fprintf(stderr, "Can't convert %s to a uuid for %s: %d\n",
 			    guid_tbl[i].uuid_str, guid_tbl[i].name, (int)status);
 	}
+	done = 1;
+}
+
+int
+efi_known_guid(struct uuid_table **tbl)
+{
+
+	*tbl = guid_tbl;
+	return (nitems(guid_tbl));
 }
 
 static int
@@ -132,10 +139,7 @@ rv_to_linux_rv(int rv)
 {
 	if (rv == 0)
 		rv = 1;
-	else if (errno == ENOENT) {
-		rv = 0;
-		errno = 0;
-	} else
+	else
 		rv = -errno;
 	return (rv);
 }
@@ -169,7 +173,7 @@ efi_get_variable(efi_guid_t guid, const char *name,
 		return -1;
 
 	efi_var_reset(&var);
-	rv = libefi_utf8_to_ucs2(name, &var.name, &var.namesize);
+	rv = utf8_to_ucs2(name, &var.name, &var.namesize);
 	if (rv != 0)
 		goto errout;
 	var.vendor = guid;
@@ -221,7 +225,6 @@ efi_get_next_variable_name(efi_guid_t **guid, char **name)
 	if (efi_open_dev() == -1)
 		return -1;
 
-
 	if (buf == NULL)
 		buf = malloc(buflen);
 
@@ -233,7 +236,7 @@ again:
 		*buf = 0;
 		/* GUID zeroed in var_reset */
 	} else {
-		rv = libefi_utf8_to_ucs2(*name, &var.name, &size);
+		rv = utf8_to_ucs2(*name, &var.name, &size);
 		if (rv != 0)
 			goto errout;
 		var.vendor = **guid;
@@ -257,7 +260,7 @@ again:
 	if (rv == 0) {
 		*name = NULL; /* XXX */
 		var.name[var.namesize / sizeof(efi_char)] = 0;	/* EFI doesn't NUL terminate */
-		rv = libefi_ucs2_to_utf8(var.name, name);
+		rv = ucs2_to_utf8(var.name, name);
 		if (rv != 0)
 			goto errout;
 		retguid = var.vendor;
@@ -267,6 +270,11 @@ errout:
 
 	/* XXX The linux interface expects name to be a static buffer -- fix or leak memory? */
 done:
+	if (errno == ENOENT) {
+		errno = 0;
+		return 0;
+	}
+
 	return (rv_to_linux_rv(rv));
 }
 
@@ -292,6 +300,7 @@ efi_guid_to_name(efi_guid_t *guid, char **name)
 	size_t i;
 	uint32_t status;
 
+	efi_guid_tbl_compile();
 	for (i = 0; i < nitems(guid_tbl); i++) {
 		if (uuid_equal(guid, &guid_tbl[i].guid, &status)) {
 			*name = strdup(guid_tbl[i].name);
@@ -328,6 +337,7 @@ efi_name_to_guid(const char *name, efi_guid_t *guid)
 {
 	size_t i;
 
+	efi_guid_tbl_compile();
 	for (i = 0; i < nitems(guid_tbl); i++) {
 		if (strcmp(name, guid_tbl[i].name) == 0) {
 			*guid = guid_tbl[i].guid;
@@ -348,7 +358,7 @@ efi_set_variable(efi_guid_t guid, const char *name,
 		return -1;
 
 	efi_var_reset(&var);
-	rv = libefi_utf8_to_ucs2(name, &var.name, &var.namesize);
+	rv = utf8_to_ucs2(name, &var.name, &var.namesize);
 	if (rv != 0)
 		goto errout;
 	var.vendor = guid;
diff --git a/lib/libefivar/efivar.h b/lib/libefivar/efivar.h
index 822cd3c125..c97b9702cd 100644
--- a/lib/libefivar/efivar.h
+++ b/lib/libefivar/efivar.h
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libefivar/efivar.h 307071 2016-10-11 22:30:41Z imp $
+ * $FreeBSD: head/lib/libefivar/efivar.h 314926 2017-03-09 00:31:31Z imp $
  */
 
 #ifndef	_EFIVAR_H_
@@ -49,7 +49,11 @@
 #endif
 
 
+#ifndef _EFIVAR_EFI_GUID_T_DEF
+#define _EFIVAR_EFI_GUID_T_DEF
 typedef uuid_t efi_guid_t;
+#endif
+
 #if BYTE_ORDER == LITTLE_ENDIAN
 #define	EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5)			\
 	((efi_guid_t) {(a), (b), (c), (d) >> 8, (d) & 0xff,		\
@@ -83,6 +87,16 @@ int efi_set_variable(efi_guid_t guid, const char *name,
 int efi_str_to_guid(const char *s, efi_guid_t *guid);
 int efi_variables_supported(void);
 
+/* FreeBSD extensions */
+struct uuid_table
+{
+	const char *uuid_str;
+	const char *name;
+	efi_guid_t guid;
+};
+
+int efi_known_guid(struct uuid_table **);
+
 extern const efi_guid_t efi_guid_empty;
 
 /* Stubs that are expected, but aren't really used */
diff --git a/lib/libefivar/uefi-dplib.h b/lib/libefivar/uefi-dplib.h
new file mode 100644
index 0000000000..4c0aa3adc7
--- /dev/null
+++ b/lib/libefivar/uefi-dplib.h
@@ -0,0 +1,635 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: head/lib/libefivar/uefi-dplib.h 315770 2017-03-23 02:30:52Z imp $
+ */
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ */
+
+/** @file
+  Definition for Device Path library.
+
+Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _UEFI_DEVICE_PATH_LIB_H_
+#define _UEFI_DEVICE_PATH_LIB_H_
+#include <Uefi.h>
+#include <Protocol/DevicePathUtilities.h>
+#include <Protocol/DebugPort.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Guid/PcAnsi.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Bluetooth.h>
+
+#define IS_COMMA(a)                ((a) == ',')
+#define IS_HYPHEN(a)               ((a) == '-')
+#define IS_DOT(a)                  ((a) == '.')
+#define IS_LEFT_PARENTH(a)         ((a) == '(')
+#define IS_RIGHT_PARENTH(a)        ((a) == ')')
+#define IS_SLASH(a)                ((a) == '/')
+#define IS_NULL(a)                 ((a) == '\0')
+
+
+//
+// Private Data structure
+//
+typedef struct {
+  char  *Str;
+  UINTN   Count;
+  UINTN   Capacity;
+} POOL_PRINT;
+
+typedef
+EFI_DEVICE_PATH_PROTOCOL  *
+(*DEVICE_PATH_FROM_TEXT) (
+  IN char *Str
+  );
+
+typedef
+VOID
+(*DEVICE_PATH_TO_TEXT) (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevicePath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  );
+
+typedef struct {
+  UINT8                Type;
+  UINT8                SubType;
+  DEVICE_PATH_TO_TEXT  Function;
+} DEVICE_PATH_TO_TEXT_TABLE;
+
+typedef struct {
+  UINT8                Type;
+  const char          *Text;
+} DEVICE_PATH_TO_TEXT_GENERIC_TABLE;
+
+typedef struct {
+  const char                *DevicePathNodeText;
+  DEVICE_PATH_FROM_TEXT     Function;
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+  BOOLEAN ClassExist;
+  UINT8   Class;
+  BOOLEAN SubClassExist;
+  UINT8   SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO            1
+#define USB_CLASS_CDCCONTROL       2
+#define USB_CLASS_HID              3
+#define USB_CLASS_IMAGE            6
+#define USB_CLASS_PRINTER          7
+#define USB_CLASS_MASS_STORAGE     8
+#define USB_CLASS_HUB              9
+#define USB_CLASS_CDCDATA          10
+#define USB_CLASS_SMART_CARD       11
+#define USB_CLASS_VIDEO            14
+#define USB_CLASS_DIAGNOSTIC       220
+#define USB_CLASS_WIRELESS         224
+
+#define USB_CLASS_RESERVE          254
+#define USB_SUBCLASS_FW_UPDATE     1
+#define USB_SUBCLASS_IRDA_BRIDGE   2
+#define USB_SUBCLASS_TEST          3
+
+#define RFC_1700_UDP_PROTOCOL      17
+#define RFC_1700_TCP_PROTOCOL      6
+
+#pragma pack(1)
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  EFI_GUID                  Guid;
+  UINT8                     VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  EFI_GUID                  Guid;
+  UINT8                     VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  EFI_GUID                  Guid;
+  UINT8                     VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  UINT32                    Hid;
+  UINT32                    Uid;
+  UINT32                    Cid;
+  CHAR8                     HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  UINT16                    NetworkProtocol;
+  UINT16                    LoginOption;
+  UINT64                    Lun;
+  UINT16                    TargetPortalGroupTag;
+  CHAR8                     TargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  EFI_GUID                  Guid;
+  UINT8                     VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+#pragma pack()
+
+#ifdef FreeBSD		/* Remove these on FreeBSD */
+
+/**
+  Returns the size of a device path in bytes.
+
+  This function returns the size, in bytes, of the device path data structure
+  specified by DevicePath including the end of device path node.
+  If DevicePath is NULL or invalid, then 0 is returned.
+
+  @param  DevicePath  A pointer to a device path data structure.
+
+  @retval 0           If DevicePath is NULL or invalid.
+  @retval Others      The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+UefiDevicePathLibGetDevicePathSize (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+/**
+  Creates a new copy of an existing device path.
+
+  This function allocates space for a new copy of the device path specified by DevicePath.
+  If DevicePath is NULL, then NULL is returned.  If the memory is successfully
+  allocated, then the contents of DevicePath are copied to the newly allocated
+  buffer, and a pointer to that buffer is returned.  Otherwise, NULL is returned.
+  The memory for the new device path is allocated from EFI boot services memory.
+  It is the responsibility of the caller to free the memory allocated.
+
+  @param  DevicePath    A pointer to a device path data structure.
+
+  @retval NULL          DevicePath is NULL or invalid.
+  @retval Others        A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibDuplicateDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+/**
+  Creates a new device path by appending a second device path to a first device path.
+
+  This function creates a new device path by appending a copy of SecondDevicePath
+  to a copy of FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path
+  device node from SecondDevicePath is retained. The newly created device path is
+  returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+  SecondDevicePath is returned.  If SecondDevicePath is NULL, then it is ignored,
+  and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+  SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+  If there is not enough memory for the newly allocated buffer, then NULL is returned.
+  The memory for the new device path is allocated from EFI boot services memory.
+  It is the responsibility of the caller to free the memory allocated.
+
+  @param  FirstDevicePath            A pointer to a device path data structure.
+  @param  SecondDevicePath           A pointer to a device path data structure.
+
+  @retval NULL      If there is not enough memory for the newly allocated buffer.
+  @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
+  @retval Others    A pointer to the new device path if success.
+                    Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
+  );
+
+/**
+  Creates a new path by appending the device node to the device path.
+
+  This function creates a new device path by appending a copy of the device node
+  specified by DevicePathNode to a copy of the device path specified by DevicePath
+  in an allocated buffer. The end-of-device-path device node is moved after the
+  end of the appended device node.
+  If DevicePathNode is NULL then a copy of DevicePath is returned.
+  If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+  path device node is returned.
+  If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+  device node is returned.
+  If there is not enough memory to allocate space for the new device path, then
+  NULL is returned.
+  The memory is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+
+  @param  DevicePath                 A pointer to a device path data structure.
+  @param  DevicePathNode             A pointer to a single device path node.
+
+  @retval NULL      If there is not enough memory for the new device path.
+  @retval Others    A pointer to the new device path if success.
+                    A copy of DevicePathNode followed by an end-of-device-path node
+                    if both FirstDevicePath and SecondDevicePath are NULL.
+                    A copy of an end-of-device-path node if both FirstDevicePath
+                    and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePathNode (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
+  );
+
+/**
+  Creates a new device path by appending the specified device path instance to the specified device
+  path.
+
+  This function creates a new device path by appending a copy of the device path
+  instance specified by DevicePathInstance to a copy of the device path specified
+  by DevicePath in a allocated buffer.
+  The end-of-device-path device node is moved after the end of the appended device
+  path instance and a new end-of-device-path-instance node is inserted between.
+  If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+  If DevicePathInstance is NULL, then NULL is returned.
+  If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then
+  NULL is returned.
+  The memory is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+
+  @param  DevicePath                 A pointer to a device path data structure.
+  @param  DevicePathInstance         A pointer to a device path instance.
+
+  @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePathInstance (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL
+  );
+
+/**
+  Creates a copy of the current device path instance and returns a pointer to the next device path
+  instance.
+
+  This function creates a copy of the current device path instance. It also updates
+  DevicePath to point to the next device path instance in the device path (or NULL
+  if no more) and updates Size to hold the size of the device path instance copy.
+  If DevicePath is NULL, then NULL is returned.
+  If DevicePath points to a invalid device path, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then
+  NULL is returned.
+  The memory is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+  If Size is NULL, then ASSERT().
+
+  @param  DevicePath                 On input, this holds the pointer to the current
+                                     device path instance. On output, this holds
+                                     the pointer to the next device path instance
+                                     or NULL if there are no more device path
+                                     instances in the device path pointer to a
+                                     device path data structure.
+  @param  Size                       On output, this holds the size of the device
+                                     path instance, in bytes or zero, if DevicePath
+                                     is NULL.
+
+  @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibGetNextDevicePathInstance (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
+  OUT UINTN                          *Size
+  );
+
+/**
+  Creates a device node.
+
+  This function creates a new device node in a newly allocated buffer of size
+  NodeLength and initializes the device path node header with NodeType and NodeSubType.
+  The new device path node is returned.
+  If NodeLength is smaller than a device path header, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then
+  NULL is returned.
+  The memory is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+
+  @param  NodeType                   The device node type for the new device node.
+  @param  NodeSubType                The device node sub-type for the new device node.
+  @param  NodeLength                 The length of the new device node.
+
+  @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibCreateDeviceNode (
+  IN UINT8                           NodeType,
+  IN UINT8                           NodeSubType,
+  IN UINT16                          NodeLength
+  );
+
+/**
+  Determines if a device path is single or multi-instance.
+
+  This function returns TRUE if the device path specified by DevicePath is
+  multi-instance.
+  Otherwise, FALSE is returned.
+  If DevicePath is NULL or invalid, then FALSE is returned.
+
+  @param  DevicePath                 A pointer to a device path data structure.
+
+  @retval  TRUE                      DevicePath is multi-instance.
+  @retval  FALSE                     DevicePath is not multi-instance, or DevicePath
+                                     is NULL or invalid.
+
+**/
+BOOLEAN
+EFIAPI
+UefiDevicePathLibIsDevicePathMultiInstance (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+
+/**
+  Converts a device path to its text representation.
+
+  @param DevicePath      A Pointer to the device to be converted.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+  @return A pointer to the allocated text representation of the device path or
+          NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+UefiDevicePathLibConvertDevicePathToText (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
+  IN BOOLEAN                          DisplayOnly,
+  IN BOOLEAN                          AllowShortcuts
+  );
+
+/**
+  Converts a device node to its string representation.
+
+  @param DeviceNode        A Pointer to the device node to be converted.
+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
+                           of the display node is used, where applicable. If DisplayOnly
+                           is FALSE, then the longer text representation of the display node
+                           is used.
+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
+                           representation for a device node can be used, where applicable.
+
+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+          is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+UefiDevicePathLibConvertDeviceNodeToText (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
+  IN BOOLEAN                         DisplayOnly,
+  IN BOOLEAN                         AllowShortcuts
+  );
+
+/**
+  Convert text to the binary representation of a device node.
+
+  @param TextDeviceNode  TextDeviceNode points to the text representation of a device
+                         node. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+          insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDeviceNode (
+  IN CONST CHAR16 *TextDeviceNode
+  );
+
+/**
+  Convert text to the binary representation of a device path.
+
+
+  @param TextDevicePath  TextDevicePath points to the text representation of a device
+                         path. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+          there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDevicePath (
+  IN CONST CHAR16 *TextDevicePath
+  );
+#else
+
+/*
+ * Small FreeBSD shim layer. Fast and lose hacks to make this code work with FreeBSD.
+ */
+
+#include <ctype.h>
+
+#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount 1000
+#define MAX_UINTN UINTPTR_MAX
+
+#define AllocatePool(x) malloc(x)
+#define AllocateZeroPool(x) calloc(1,x)
+#define AsciiStrLen(s) strlen(s)
+#define CopyGuid(dst, src) memcpy(dst, src, sizeof(uuid_t))
+#define CopyMem(d, s, l) memcpy(d, s, l)
+#define FreePool(x) free(x)
+#define LShiftU64(x, s) ((x) << s)
+#define ReadUnaligned64(x)    le64dec(x)
+#define ReallocatePool(old, new, ptr) realloc(ptr, new)
+/*
+ * Quirky StrCmp returns 0 if equal, 1 if not. This is what the code
+ * expects, though that expectation is likely a bug (it casts the
+ * return value. EDK2's StrCmp returns values just like C's strcmp,
+ * but the parse code casts this to an UINTN, which is bogus. This
+ * definition papers over that bogusness to do the right thing.  If
+ * iSCSI protocol string processing is ever fixed, we can remove this
+ * bletcherous kludge.
+ */
+#define StrCmp(a, b) (strcmp(a, b) != 0)
+#define StrCpyS(d, l, s) strcpy(d, s)
+#define StrHexToUint64(x) strtoll(x, NULL, 16)
+#define StrHexToUintn(x) strtoll(x, NULL, 16)
+#define StrLen(x) strlen(x)
+#define StrSize(x) (strlen(x) + 1)
+#define StrnCatS(d, l, s, len) strncat(d, s, len)
+#define StrnCmp(a, b, n) strncmp(a, b, n)
+#define StrnLenS(str, max) strlen(str)
+#define Strtoi(x) strtol(x, NULL, 0)
+#define Strtoi64(x, y) *(long long *)y = strtoll(x, NULL, 0)
+#define SwapBytes64(u64) bswap64(u64)
+#define UnicodeStrToAsciiStrS(src, dest, len) strlcpy(dest, src, len)
+#define ZeroMem(p,l) memset(p, 0, l)
+
+#undef ASSERT
+#define ASSERT(x)
+
+/*
+ * Define AllocateCopyPool and others so that we "forget" about the
+ * previous non-static deifnition since we want these to be static
+ * inlines.
+ */
+#define AllocateCopyPool AllocateCopyPoolFreeBSD
+#define CompareGuid CompareGuidFreeBSD
+#define StrHexToBytes StrHexToBytesFreeBSD
+#define StrToGuid StrToGuidFreeBSD
+#define WriteUnaligned64 WriteUnaligned64FreeBSD
+
+static inline void *
+AllocateCopyPool(size_t l, const void *p)
+{
+	void *rv;
+		
+	rv = malloc(l);
+	if (rv == NULL)
+		return NULL;
+	memcpy(rv, p, l);
+	return (rv);
+}
+
+static inline BOOLEAN
+CompareGuid (const GUID *g1, const GUID *g2)
+{
+	uint32_t ignored_status;
+
+	return (uuid_compare((const uuid_t *)g1, (const uuid_t *)g2,
+	    &ignored_status) == 0);
+}
+
+static inline int
+StrHexToBytes(const char *str, size_t len, uint8_t *buf, size_t buflen)
+{
+	size_t i;
+	char hex[3];
+
+	/*
+	 * Sanity check preconditions.
+	 */
+	if (buflen != len / 2 || (len % 1) == 1)
+		return 1;
+	for (i = 0; i < len; i += 2) {
+		if (!isxdigit(str[i]) || !isxdigit(str[i + 1]))
+			return 1;
+		hex[0] = str[i];
+		hex[1] = str[i + 1];
+		hex[2] = '\0';
+		buf[i / 2] = strtol(hex, NULL, 16);
+	}
+	return 0;
+}
+
+static inline void
+StrToGuid(const char *str, GUID *guid)
+{
+	uint32_t status;
+
+	uuid_from_string(str, (uuid_t *)guid, &status);
+}
+
+static inline void
+WriteUnaligned64(void *ptr, uint64_t val)
+{
+	memcpy(ptr, &val, sizeof(val));
+}
+
+/*
+ * Hack to allow converting %g to %s in printfs. Hack because
+ * it's single entry, uses a static buffer, etc. Sufficient for
+ * the day for this file though. IF you ever have to convert
+ * two %g's in one format, punt. Did I mention this was super lame.
+ * Not to mention it's name.... Also, the error GUID is horrific.
+ */
+static inline const char *
+guid_str(const GUID *g)
+{
+	static char buf[36 + 1];
+	char *str = NULL;
+	int32_t ignored_status;
+
+	uuid_to_string((const uuid_t *)g, &str, &ignored_status);
+	if (str != NULL)
+		strlcpy(buf, str, sizeof(buf));
+	else
+		strlcpy(buf, "groot-cannot-decode-guid-groot-smash",
+		    sizeof(buf)); /* ^^^^^^^ 36 characters ^^^^^^^ */
+	free(str);
+	return buf;
+}
+#define G(x) guid_str((const GUID *)(const void *)x)
+#endif
+
+#undef GLOBAL_REMOVE_IF_UNREFERENCED
+#define GLOBAL_REMOVE_IF_UNREFERENCED static
+
+#endif
diff --git a/lib/libefivar/uefi-dputil.c b/lib/libefivar/uefi-dputil.c
new file mode 100644
index 0000000000..76c613569a
--- /dev/null
+++ b/lib/libefivar/uefi-dputil.c
@@ -0,0 +1,636 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
+ * this file is taken from EDK2 and rototilled.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/lib/libefivar/uefi-dputil.c 314926 2017-03-09 00:31:31Z imp $");
+
+#include <efivar.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/endian.h>
+
+#include "efi-osdep.h"
+
+#include "uefi-dplib.h"
+
+/* XXX maybe I sould include the entire DevicePathUtiltiies.c and ifdef out what we don't use */
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ */
+
+/** @file
+  Device Path services. The thing to remember is device paths are built out of
+  nodes. The device path is terminated by an end node that is length
+  sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+  all over this file.
+
+  The only place where multi-instance device paths are supported is in
+  environment varibles. Multi-instance device paths should never be placed
+  on a Handle.
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// Template for an end-of-device path node.
+//
+static CONST EFI_DEVICE_PATH_PROTOCOL  mUefiDevicePathLibEndDevicePath = {
+  END_DEVICE_PATH_TYPE,
+  END_ENTIRE_DEVICE_PATH_SUBTYPE,
+  {
+    END_DEVICE_PATH_LENGTH,
+    0
+  }
+};
+
+
+/**
+  Returns the size of a device path in bytes.
+
+  This function returns the size, in bytes, of the device path data structure
+  specified by DevicePath including the end of device path node.
+  If DevicePath is NULL or invalid, then 0 is returned.
+
+  @param  DevicePath  A pointer to a device path data structure.
+
+  @retval 0           If DevicePath is NULL or invalid.
+  @retval Others      The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+GetDevicePathSize (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;
+
+  if (DevicePath == NULL) {
+    return 0;
+  }
+
+  if (!IsDevicePathValid (DevicePath, 0)) {
+    return 0;
+  }
+
+  //
+  // Search for the end of the device path structure
+  //
+  Start = DevicePath;
+  while (!IsDevicePathEnd (DevicePath)) {
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  //
+  // Compute the size and add back in the size of the end device path structure
+  //
+  return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+}
+
+/**
+  Determine whether a given device path is valid.
+  If DevicePath is NULL, then ASSERT().
+
+  @param  DevicePath  A pointer to a device path data structure.
+  @param  MaxSize     The maximum size of the device path data structure.
+
+  @retval TRUE        DevicePath is valid.
+  @retval FALSE       The length of any node node in the DevicePath is less
+                      than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+  @retval FALSE       If MaxSize is not zero, the size of the DevicePath
+                      exceeds MaxSize.
+  @retval FALSE       If PcdMaximumDevicePathNodeCount is not zero, the node
+                      count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathValid (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN       UINTN                    MaxSize
+  )
+{
+  UINTN Count;
+  UINTN Size;
+  UINTN NodeLength;
+
+  ASSERT (DevicePath != NULL);
+
+  if (MaxSize == 0) {
+    MaxSize = MAX_UINTN;
+  }
+
+  //
+  // Validate the input size big enough to touch the first node.
+  //
+  if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+    return FALSE;
+  }
+
+  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
+    NodeLength = DevicePathNodeLength (DevicePath);
+    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+      return FALSE;
+    }
+
+    if (NodeLength > MAX_UINTN - Size) {
+      return FALSE;
+    }
+    Size += NodeLength;
+
+    //
+    // Validate next node before touch it.
+    //
+    if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {
+      return FALSE;
+    }
+
+    if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
+      Count++;
+      if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
+        return FALSE;
+      }
+    }
+  }
+
+  //
+  // Only return TRUE when the End Device Path node is valid.
+  //
+  return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
+}
+
+/**
+  Returns the Type field of a device path node.
+
+  Returns the Type field of the device path node specified by Node.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return The Type field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathType (
+  IN CONST VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  return ((const EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
+}
+
+
+/**
+  Returns the SubType field of a device path node.
+
+  Returns the SubType field of the device path node specified by Node.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return The SubType field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathSubType (
+  IN CONST VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  return ((const EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
+}
+
+/**
+  Returns the 16-bit Length field of a device path node.
+
+  Returns the 16-bit Length field of the device path node specified by Node.
+  Node is not required to be aligned on a 16-bit boundary, so it is recommended
+  that a function such as ReadUnaligned16() be used to extract the contents of
+  the Length field.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return The 16-bit Length field of the device path node specified by Node.
+
+**/
+UINTN
+EFIAPI
+DevicePathNodeLength (
+  IN CONST VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  return ((const EFI_DEVICE_PATH_PROTOCOL *)Node)->Length[0] |
+      (((const EFI_DEVICE_PATH_PROTOCOL *)Node)->Length[1] << 8);
+}
+
+/**
+  Returns a pointer to the next node in a device path.
+
+  Returns a pointer to the device path node that follows the device path node
+  specified by Node.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return a pointer to the device path node that follows the device path node
+  specified by Node.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+NextDevicePathNode (
+  IN CONST VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  return ((EFI_DEVICE_PATH_PROTOCOL *)(__DECONST(UINT8 *, Node) + DevicePathNodeLength(Node)));
+}
+
+/**
+  Determines if a device path node is an end node of a device path.
+  This includes nodes that are the end of a device path instance and nodes that
+  are the end of an entire device path.
+
+  Determines if the device path node specified by Node is an end node of a device path.
+  This includes nodes that are the end of a device path instance and nodes that are the
+  end of an entire device path.  If Node represents an end node of a device path,
+  then TRUE is returned.  Otherwise, FALSE is returned.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @retval TRUE      The device path node specified by Node is an end node of a
+                    device path.
+  @retval FALSE     The device path node specified by Node is not an end node of
+                    a device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEndType (
+  IN CONST VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE);
+}
+
+/**
+  Determines if a device path node is an end node of an entire device path.
+
+  Determines if a device path node specified by Node is an end node of an entire
+  device path. If Node represents the end of an entire device path, then TRUE is
+  returned.  Otherwise, FALSE is returned.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @retval TRUE      The device path node specified by Node is the end of an entire
+                    device path.
+  @retval FALSE     The device path node specified by Node is not the end of an
+                    entire device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEnd (
+  IN CONST VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+  Fills in all the fields of a device path node that is the end of an entire device path.
+
+  Fills in all the fields of a device path node specified by Node so Node represents
+  the end of an entire device path.  The Type field of Node is set to
+  END_DEVICE_PATH_TYPE, the SubType field of Node is set to
+  END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
+  END_DEVICE_PATH_LENGTH.  Node is not required to be aligned on a 16-bit boundary,
+  so it is recommended that a function such as WriteUnaligned16() be used to set
+  the contents of the Length field.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+**/
+VOID
+EFIAPI
+SetDevicePathEndNode (
+  OUT VOID  *Node
+  )
+{
+  ASSERT (Node != NULL);
+  memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
+}
+
+/**
+  Sets the length, in bytes, of a device path node.
+
+  Sets the length of the device path node specified by Node to the value specified
+  by NodeLength.  NodeLength is returned.  Node is not required to be aligned on
+  a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
+  be used to set the contents of the Length field.
+
+  If Node is NULL, then ASSERT().
+  If NodeLength >= SIZE_64KB, then ASSERT().
+  If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+  @param  Length    The length, in bytes, of the device path node.
+
+  @return Length
+
+**/
+UINT16
+EFIAPI
+SetDevicePathNodeLength (
+  IN OUT VOID  *Node,
+  IN UINTN     Length
+  )
+{
+  ASSERT (Node != NULL);
+  ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
+//  return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+  le16enc(&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+  return Length;
+}
+
+/**
+  Creates a device node.
+
+  This function creates a new device node in a newly allocated buffer of size
+  NodeLength and initializes the device path node header with NodeType and NodeSubType.
+  The new device path node is returned.
+  If NodeLength is smaller than a device path header, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then
+  NULL is returned.
+  The memory is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+
+  @param  NodeType                   The device node type for the new device node.
+  @param  NodeSubType                The device node sub-type for the new device node.
+  @param  NodeLength                 The length of the new device node.
+
+  @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+CreateDeviceNode (
+  IN UINT8                           NodeType,
+  IN UINT8                           NodeSubType,
+  IN UINT16                          NodeLength
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
+
+  if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+    //
+    // NodeLength is less than the size of the header.
+    //
+    return NULL;
+  }
+
+  DevicePath = AllocateZeroPool (NodeLength);
+  if (DevicePath != NULL) {
+     DevicePath->Type    = NodeType;
+     DevicePath->SubType = NodeSubType;
+     SetDevicePathNodeLength (DevicePath, NodeLength);
+  }
+
+  return DevicePath;
+}
+
+/**
+  Creates a new copy of an existing device path.
+
+  This function allocates space for a new copy of the device path specified by DevicePath.
+  If DevicePath is NULL, then NULL is returned.  If the memory is successfully
+  allocated, then the contents of DevicePath are copied to the newly allocated
+  buffer, and a pointer to that buffer is returned.  Otherwise, NULL is returned.
+  The memory for the new device path is allocated from EFI boot services memory.
+  It is the responsibility of the caller to free the memory allocated.
+
+  @param  DevicePath    A pointer to a device path data structure.
+
+  @retval NULL          DevicePath is NULL or invalid.
+  @retval Others        A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DuplicateDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  UINTN                     Size;
+
+  //
+  // Compute the size
+  //
+  Size = GetDevicePathSize (DevicePath);
+  if (Size == 0) {
+    return NULL;
+  }
+
+  //
+  // Allocate space for duplicate device path
+  //
+
+  return AllocateCopyPool (Size, DevicePath);
+}
+
+/**
+  Creates a new device path by appending a second device path to a first device path.
+
+  This function creates a new device path by appending a copy of SecondDevicePath
+  to a copy of FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path
+  device node from SecondDevicePath is retained. The newly created device path is
+  returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+  SecondDevicePath is returned.  If SecondDevicePath is NULL, then it is ignored,
+  and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+  SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+  If there is not enough memory for the newly allocated buffer, then NULL is returned.
+  The memory for the new device path is allocated from EFI boot services memory.
+  It is the responsibility of the caller to free the memory allocated.
+
+  @param  FirstDevicePath            A pointer to a device path data structure.
+  @param  SecondDevicePath           A pointer to a device path data structure.
+
+  @retval NULL      If there is not enough memory for the newly allocated buffer.
+  @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
+  @retval Others    A pointer to the new device path if success.
+                    Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
+  )
+{
+  UINTN                     Size;
+  UINTN                     Size1;
+  UINTN                     Size2;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath2;
+
+  //
+  // If there's only 1 path, just duplicate it.
+  //
+  if (FirstDevicePath == NULL) {
+    return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath);
+  }
+
+  if (SecondDevicePath == NULL) {
+    return DuplicateDevicePath (FirstDevicePath);
+  }
+
+  if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) {
+    return NULL;
+  }
+
+  //
+  // Allocate space for the combined device path. It only has one end node of
+  // length EFI_DEVICE_PATH_PROTOCOL.
+  //
+  Size1         = GetDevicePathSize (FirstDevicePath);
+  Size2         = GetDevicePathSize (SecondDevicePath);
+  Size          = Size1 + Size2 - END_DEVICE_PATH_LENGTH;
+
+  NewDevicePath = AllocatePool (Size);
+
+  if (NewDevicePath != NULL) {
+    NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1);
+    //
+    // Over write FirstDevicePath EndNode and do the copy
+    //
+    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +
+                  (Size1 - END_DEVICE_PATH_LENGTH));
+    CopyMem (DevicePath2, SecondDevicePath, Size2);
+  }
+
+  return NewDevicePath;
+}
+
+/**
+  Creates a new path by appending the device node to the device path.
+
+  This function creates a new device path by appending a copy of the device node
+  specified by DevicePathNode to a copy of the device path specified by DevicePath
+  in an allocated buffer. The end-of-device-path device node is moved after the
+  end of the appended device node.
+  If DevicePathNode is NULL then a copy of DevicePath is returned.
+  If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+  path device node is returned.
+  If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+  device node is returned.
+  If there is not enough memory to allocate space for the new device path, then
+  NULL is returned.
+  The memory is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+
+  @param  DevicePath                 A pointer to a device path data structure.
+  @param  DevicePathNode             A pointer to a single device path node.
+
+  @retval NULL      If there is not enough memory for the new device path.
+  @retval Others    A pointer to the new device path if success.
+                    A copy of DevicePathNode followed by an end-of-device-path node
+                    if both FirstDevicePath and SecondDevicePath are NULL.
+                    A copy of an end-of-device-path node if both FirstDevicePath
+                    and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathNode (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  UINTN                     NodeLength;
+
+  if (DevicePathNode == NULL) {
+    return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath);
+  }
+  //
+  // Build a Node that has a terminator on it
+  //
+  NodeLength = DevicePathNodeLength (DevicePathNode);
+
+  TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH);
+  if (TempDevicePath == NULL) {
+    return NULL;
+  }
+  TempDevicePath = CopyMem (TempDevicePath, DevicePathNode, NodeLength);
+  //
+  // Add and end device path node to convert Node to device path
+  //
+  NextNode = NextDevicePathNode (TempDevicePath);
+  SetDevicePathEndNode (NextNode);
+  //
+  // Append device paths
+  //
+  NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);
+
+  FreePool (TempDevicePath);
+
+  return NewDevicePath;
+}
diff --git a/lib/libefivar/uefi-guid.c b/lib/libefivar/uefi-guid.c
new file mode 100644
index 0000000000..532aa4240f
--- /dev/null
+++ b/lib/libefivar/uefi-guid.c
@@ -0,0 +1,36 @@
+/* This generated file is in the public domain */
+/* $FreeBSD: head/lib/libefivar/uefi-guid.c 314926 2017-03-09 00:31:31Z imp $ */
+
+#include <uuid.h>
+#include <stdint.h>
+
+typedef struct {          
+    uint32_t  Data1;
+    uint16_t  Data2;
+    uint16_t  Data3;
+    uint8_t   Data4[8]; 
+} EFI_GUID;
+
+extern EFI_GUID    gEfiDebugPortProtocolGuid;
+extern EFI_GUID    gEfiPcAnsiGuid;
+extern EFI_GUID    gEfiPersistentVirtualCdGuid;
+extern EFI_GUID    gEfiPersistentVirtualDiskGuid;
+extern EFI_GUID    gEfiSasDevicePathGuid;
+extern EFI_GUID    gEfiUartDevicePathGuid;
+extern EFI_GUID    gEfiVT100Guid;
+extern EFI_GUID    gEfiVT100PlusGuid;
+extern EFI_GUID    gEfiVTUTF8Guid;
+extern EFI_GUID    gEfiVirtualCdGuid;
+extern EFI_GUID    gEfiVirtualDiskGuid;
+
+EFI_GUID    gEfiDebugPortProtocolGuid      = { 0xEBA4E8D2, 0x3858, 0x41EC, { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 }} ;
+EFI_GUID    gEfiPcAnsiGuid                 = { 0xE0C14753, 0xF9BE, 0x11D2, { 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} ;
+EFI_GUID    gEfiPersistentVirtualCdGuid    = { 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} ;
+EFI_GUID    gEfiPersistentVirtualDiskGuid  = { 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} ;
+EFI_GUID    gEfiSasDevicePathGuid          = { 0xd487ddb4, 0x008b, 0x11d9, { 0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d }} ;
+EFI_GUID    gEfiUartDevicePathGuid         = { 0x37499a9d, 0x542f, 0x4c89, { 0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 }} ;
+EFI_GUID    gEfiVT100Guid                  = { 0xDFA66065, 0xB419, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} ;
+EFI_GUID    gEfiVT100PlusGuid              = { 0x7BAEC70B, 0x57E0, 0x4C76, { 0x8E, 0x87, 0x2F, 0x9E, 0x28, 0x08, 0x83, 0x43 }} ;
+EFI_GUID    gEfiVTUTF8Guid                 = { 0xAD15A0D6, 0x8BEC, 0x4ACF, { 0xA0, 0x73, 0xD0, 0x1D, 0xE7, 0x7E, 0x2D, 0x88 }} ;
+EFI_GUID    gEfiVirtualCdGuid              = { 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} ;
+EFI_GUID    gEfiVirtualDiskGuid            = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} ;
diff --git a/lib/libefivar/uefi-guid.dat b/lib/libefivar/uefi-guid.dat
new file mode 100644
index 0000000000..921b179ae3
--- /dev/null
+++ b/lib/libefivar/uefi-guid.dat
@@ -0,0 +1,11 @@
+gEfiDebugPortProtocolGuid
+gEfiPcAnsiGuid
+gEfiPersistentVirtualCdGuid
+gEfiPersistentVirtualDiskGuid
+gEfiSasDevicePathGuid
+gEfiUartDevicePathGuid
+gEfiVT100Guid
+gEfiVT100PlusGuid
+gEfiVTUTF8Guid
+gEfiVirtualCdGuid
+gEfiVirtualDiskGuid
diff --git a/lib/libefivar/libefivar_int.h b/sys/boot/efi/include/efichar.h
similarity index 83%
rename from lib/libefivar/libefivar_int.h
rename to sys/boot/efi/include/efichar.h
index 2bebd41841..35393e0aef 100644
--- a/lib/libefivar/libefivar_int.h
+++ b/sys/boot/efi/include/efichar.h
@@ -23,13 +23,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libefivar/libefivar_int.h 307071 2016-10-11 22:30:41Z imp $
+ * $FreeBSD: head/sys/boot/efi/include/efichar.h 314925 2017-03-09 00:24:01Z imp $
  */
 
-#ifndef _LIBEFI_INT_H_
-#define	_LIBEFI_INT_H_
+#ifndef _BOOT_EFI_EFICHAR_H_
+#define	_BOOT_EFI_EFICHAR_H_
 
-int libefi_ucs2_to_utf8(const efi_char *, char **);
-int libefi_utf8_to_ucs2(const char *, efi_char **, size_t *);
+int ucs2_to_utf8(const efi_char *, char **);
+int utf8_to_ucs2(const char *, efi_char **, size_t *);
 
-#endif /* _LIBEFI_INT_H_ */
+#endif /* _BOOT_EFI_EFICHAR_H_ */
diff --git a/lib/libefivar/libefivar.c b/sys/boot/efi/libefi/efichar.c
similarity index 93%
rename from lib/libefivar/libefivar.c
rename to sys/boot/efi/libefi/efichar.c
index e8d167b5f7..79b9e0508e 100644
--- a/lib/libefivar/libefivar.c
+++ b/sys/boot/efi/libefi/efichar.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libefivar/libefivar.c 307071 2016-10-11 22:30:41Z imp $");
+__FBSDID("$FreeBSD: head/sys/boot/efi/libefi/efichar.c 314925 2017-03-09 00:24:01Z imp $");
 
 #include <sys/types.h>
 #include <errno.h>
@@ -36,9 +36,7 @@ __FBSDID("$FreeBSD: head/lib/libefivar/libefivar.c 307071 2016-10-11 22:30:41Z i
 #include <sys/efi.h>
 #include <machine/efi.h>
 
-#include "libefivar_int.h"
-
-#include <stdio.h>
+#include "efichar.h"
 
 /*
  * If nm were converted to utf8, what what would strlen
@@ -65,7 +63,7 @@ utf8_len_of_ucs2(const efi_char *nm)
 }
 
 int
-libefi_ucs2_to_utf8(const efi_char *nm, char **name)
+ucs2_to_utf8(const efi_char *nm, char **name)
 {
 	size_t len, sz;
 	efi_char c;
@@ -113,7 +111,7 @@ libefi_ucs2_to_utf8(const efi_char *nm, char **name)
 }
 
 int
-libefi_utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len)
+utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len)
 {
 	efi_char *nm;
 	size_t sz;
diff --git a/sys/contrib/edk2/Include/Base.h b/sys/contrib/edk2/Include/Base.h
new file mode 100644
index 0000000000..70cb9992a6
--- /dev/null
+++ b/sys/contrib/edk2/Include/Base.h
@@ -0,0 +1,1270 @@
+/** @file
+  Root include file for Mde Package Base type modules
+
+  This is the include file for any module of type base. Base modules only use
+  types defined via this include file and can be ported easily to any
+  environment. There are a set of base libraries in the Mde Package that can
+  be used to implement base modules.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __BASE_H__
+#define __BASE_H__
+
+//
+// Include processor specific binding
+//
+#include <ProcessorBind.h>
+
+#if defined(_MSC_EXTENSIONS)
+//
+// Disable warning when last field of data structure is a zero sized array.
+//
+#pragma warning ( disable : 4200 )
+#endif
+
+/**
+  Verifies the storage size of a given data type.
+
+  This macro generates a divide by zero error or a zero size array declaration in
+  the preprocessor if the size is incorrect.  These are declared as "extern" so
+  the space for these arrays will not be in the modules.
+
+  @param  TYPE  The date type to determine the size of.
+  @param  Size  The expected size for the TYPE.
+
+**/
+#define VERIFY_SIZE_OF(TYPE, Size) extern UINT8 _VerifySizeof##TYPE[(sizeof(TYPE) == (Size)) / (sizeof(TYPE) == (Size))]
+
+//
+// Verify that ProcessorBind.h produced UEFI Data Types that are compliant with
+// Section 2.3.1 of the UEFI 2.3 Specification.
+//
+VERIFY_SIZE_OF (BOOLEAN, 1);
+VERIFY_SIZE_OF (INT8, 1);
+VERIFY_SIZE_OF (UINT8, 1);
+VERIFY_SIZE_OF (INT16, 2);
+VERIFY_SIZE_OF (UINT16, 2);
+VERIFY_SIZE_OF (INT32, 4);
+VERIFY_SIZE_OF (UINT32, 4);
+VERIFY_SIZE_OF (INT64, 8);
+VERIFY_SIZE_OF (UINT64, 8);
+VERIFY_SIZE_OF (CHAR8, 1);
+VERIFY_SIZE_OF (CHAR16, 2);
+
+//
+// The following three enum types are used to verify that the compiler
+// configuration for enum types is compliant with Section 2.3.1 of the 
+// UEFI 2.3 Specification. These enum types and enum values are not 
+// intended to be used. A prefix of '__' is used avoid conflicts with
+// other types.
+//
+typedef enum {
+  __VerifyUint8EnumValue = 0xff
+} __VERIFY_UINT8_ENUM_SIZE;
+
+typedef enum {
+  __VerifyUint16EnumValue = 0xffff
+} __VERIFY_UINT16_ENUM_SIZE;
+
+typedef enum {
+  __VerifyUint32EnumValue = 0xffffffff
+} __VERIFY_UINT32_ENUM_SIZE;
+
+VERIFY_SIZE_OF (__VERIFY_UINT8_ENUM_SIZE, 4);
+VERIFY_SIZE_OF (__VERIFY_UINT16_ENUM_SIZE, 4);
+VERIFY_SIZE_OF (__VERIFY_UINT32_ENUM_SIZE, 4);
+
+//
+// The Microsoft* C compiler can removed references to unreferenced data items
+//  if the /OPT:REF linker option is used. We defined a macro as this is a
+//  a non standard extension
+//
+#if defined(_MSC_EXTENSIONS) && !defined (MDE_CPU_EBC)
+  ///
+  /// Remove global variable from the linked image if there are no references to
+  /// it after all compiler and linker optimizations have been performed.
+  ///
+  ///
+  #define GLOBAL_REMOVE_IF_UNREFERENCED __declspec(selectany)
+#else
+  ///
+  /// Remove the global variable from the linked image if there are no references
+  ///  to it after all compiler and linker optimizations have been performed.
+  ///
+  ///
+  #define GLOBAL_REMOVE_IF_UNREFERENCED
+#endif
+
+//
+// Should be used in combination with NORETURN to avoid 'noreturn' returns
+// warnings.
+//
+#ifndef UNREACHABLE
+  #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)
+    ///
+    /// Signal compilers and analyzers that this call is not reachable.  It is
+    /// up to the compiler to remove any code past that point.
+    /// Not implemented by GCC 4.4 or earlier.
+    ///
+    #define UNREACHABLE()  __builtin_unreachable ()
+  #elif defined (__has_feature)
+    #if __has_builtin (__builtin_unreachable)
+      ///
+      /// Signal compilers and analyzers that this call is not reachable.  It is
+      /// up to the compiler to remove any code past that point.
+      ///
+      #define UNREACHABLE()  __builtin_unreachable ()
+    #endif
+  #endif
+
+  #ifndef UNREACHABLE
+    ///
+    /// Signal compilers and analyzers that this call is not reachable.  It is
+    /// up to the compiler to remove any code past that point.
+    ///
+    #define UNREACHABLE()
+  #endif
+#endif
+
+//
+// Signaling compilers and analyzers that a certain function cannot return may
+// remove all following code and thus lead to better optimization and less
+// false positives.
+//
+#ifndef NORETURN
+  #if defined (__GNUC__) || defined (__clang__)
+    ///
+    /// Signal compilers and analyzers that the function cannot return.
+    /// It is up to the compiler to remove any code past a call to functions
+    /// flagged with this attribute.
+    ///
+    #define NORETURN  __attribute__((noreturn))
+  #elif defined(_MSC_EXTENSIONS) && !defined(MDE_CPU_EBC)
+    ///
+    /// Signal compilers and analyzers that the function cannot return.
+    /// It is up to the compiler to remove any code past a call to functions
+    /// flagged with this attribute.
+    ///
+    #define NORETURN  __declspec(noreturn)
+  #else
+    ///
+    /// Signal compilers and analyzers that the function cannot return.
+    /// It is up to the compiler to remove any code past a call to functions
+    /// flagged with this attribute.
+    ///
+    #define NORETURN
+  #endif
+#endif
+
+//
+// Should be used in combination with ANALYZER_NORETURN to avoid 'noreturn'
+// returns warnings.
+//
+#ifndef ANALYZER_UNREACHABLE
+  #ifdef __clang_analyzer__
+    #if __has_builtin (__builtin_unreachable)
+      ///
+      /// Signal the analyzer that this call is not reachable.
+      /// This excludes compilers.
+      ///
+      #define ANALYZER_UNREACHABLE()  __builtin_unreachable ()
+    #endif
+  #endif
+
+  #ifndef ANALYZER_UNREACHABLE
+    ///
+    /// Signal the analyzer that this call is not reachable.
+    /// This excludes compilers.
+    ///
+    #define ANALYZER_UNREACHABLE()
+  #endif
+#endif
+
+//
+// Static Analyzers may issue errors about potential NULL-dereferences when
+// dereferencing a pointer, that has been checked before, outside of a
+// NULL-check.  This may lead to false positives, such as when using ASSERT()
+// for verification.
+//
+#ifndef ANALYZER_NORETURN
+  #ifdef __has_feature
+    #if __has_feature (attribute_analyzer_noreturn)
+      ///
+      /// Signal analyzers that the function cannot return.
+      /// This excludes compilers.
+      ///
+      #define ANALYZER_NORETURN  __attribute__((analyzer_noreturn))
+    #endif
+  #endif
+
+  #ifndef ANALYZER_NORETURN
+    ///
+    /// Signal the analyzer that the function cannot return.
+    /// This excludes compilers.
+    ///
+    #define ANALYZER_NORETURN
+  #endif
+#endif
+
+//
+// For symbol name in assembly code, an extra "_" is sometimes necessary
+//
+
+///
+/// Private worker functions for ASM_PFX()
+///
+#define _CONCATENATE(a, b)  __CONCATENATE(a, b)
+#define __CONCATENATE(a, b) a ## b
+
+///
+/// The __USER_LABEL_PREFIX__ macro predefined by GNUC represents the prefix
+/// on symbols in assembly language.
+///
+#define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)
+
+#if __APPLE__
+  //
+  // Apple extension that is used by the linker to optimize code size
+  // with assembly functions. Put at the end of your .S files
+  //
+  #define ASM_FUNCTION_REMOVE_IF_UNREFERENCED  .subsections_via_symbols
+#else
+  #define ASM_FUNCTION_REMOVE_IF_UNREFERENCED
+#endif
+
+#ifdef __CC_ARM
+  //
+  // Older RVCT ARM compilers don't fully support #pragma pack and require __packed
+  // as a prefix for the structure.
+  //
+  #define PACKED  __packed
+#else
+  #define PACKED
+#endif
+
+///
+/// 128 bit buffer containing a unique identifier value.
+/// Unless otherwise specified, aligned on a 64 bit boundary.
+///
+typedef struct {
+  UINT32  Data1;
+  UINT16  Data2;
+  UINT16  Data3;
+  UINT8   Data4[8];
+} GUID;
+
+///
+/// 4-byte buffer. An IPv4 internet protocol address.
+///
+typedef struct {
+  UINT8 Addr[4];
+} IPv4_ADDRESS;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef struct {
+  UINT8 Addr[16];
+} IPv6_ADDRESS;
+
+//
+// 8-bytes unsigned value that represents a physical system address.
+//
+typedef UINT64 PHYSICAL_ADDRESS;
+
+///
+/// LIST_ENTRY structure definition.
+///
+typedef struct _LIST_ENTRY LIST_ENTRY;
+
+///
+/// _LIST_ENTRY structure definition.
+///
+struct _LIST_ENTRY {
+  LIST_ENTRY  *ForwardLink;
+  LIST_ENTRY  *BackLink;
+};
+
+//
+// Modifiers to abstract standard types to aid in debug of problems
+//
+
+///
+/// Datum is read-only.
+///
+#define CONST     const
+
+///
+/// Datum is scoped to the current file or function.
+///
+#define STATIC    static
+
+///
+/// Undeclared type.
+///
+#define VOID      void
+
+//
+// Modifiers for Data Types used to self document code.
+// This concept is borrowed for UEFI specification.
+//
+
+///
+/// Datum is passed to the function.
+///
+#define IN
+
+///
+/// Datum is returned from the function.
+///
+#define OUT
+
+///
+/// Passing the datum to the function is optional, and a NULL
+/// is passed if the value is not supplied.
+///
+#define OPTIONAL
+
+//
+//  UEFI specification claims 1 and 0. We are concerned about the
+//  compiler portability so we did it this way.
+//
+
+///
+/// Boolean true value.  UEFI Specification defines this value to be 1,
+/// but this form is more portable.
+///
+#define TRUE  ((BOOLEAN)(1==1))
+
+///
+/// Boolean false value.  UEFI Specification defines this value to be 0,
+/// but this form is more portable.
+///
+#define FALSE ((BOOLEAN)(0==1))
+
+///
+/// NULL pointer (VOID *)
+///
+#define NULL  ((VOID *) 0)
+
+//
+// Null character
+//
+#define CHAR_NULL             0x0000
+
+///
+/// Maximum values for common UEFI Data Types
+///
+#define MAX_INT8    ((INT8)0x7F)
+#define MAX_UINT8   ((UINT8)0xFF)
+#define MAX_INT16   ((INT16)0x7FFF)
+#define MAX_UINT16  ((UINT16)0xFFFF)
+#define MAX_INT32   ((INT32)0x7FFFFFFF)
+#define MAX_UINT32  ((UINT32)0xFFFFFFFF)
+#define MAX_INT64   ((INT64)0x7FFFFFFFFFFFFFFFULL)
+#define MAX_UINT64  ((UINT64)0xFFFFFFFFFFFFFFFFULL)
+
+#define  BIT0     0x00000001
+#define  BIT1     0x00000002
+#define  BIT2     0x00000004
+#define  BIT3     0x00000008
+#define  BIT4     0x00000010
+#define  BIT5     0x00000020
+#define  BIT6     0x00000040
+#define  BIT7     0x00000080
+#define  BIT8     0x00000100
+#define  BIT9     0x00000200
+#define  BIT10    0x00000400
+#define  BIT11    0x00000800
+#define  BIT12    0x00001000
+#define  BIT13    0x00002000
+#define  BIT14    0x00004000
+#define  BIT15    0x00008000
+#define  BIT16    0x00010000
+#define  BIT17    0x00020000
+#define  BIT18    0x00040000
+#define  BIT19    0x00080000
+#define  BIT20    0x00100000
+#define  BIT21    0x00200000
+#define  BIT22    0x00400000
+#define  BIT23    0x00800000
+#define  BIT24    0x01000000
+#define  BIT25    0x02000000
+#define  BIT26    0x04000000
+#define  BIT27    0x08000000
+#define  BIT28    0x10000000
+#define  BIT29    0x20000000
+#define  BIT30    0x40000000
+#define  BIT31    0x80000000
+#define  BIT32    0x0000000100000000ULL
+#define  BIT33    0x0000000200000000ULL
+#define  BIT34    0x0000000400000000ULL
+#define  BIT35    0x0000000800000000ULL
+#define  BIT36    0x0000001000000000ULL
+#define  BIT37    0x0000002000000000ULL
+#define  BIT38    0x0000004000000000ULL
+#define  BIT39    0x0000008000000000ULL
+#define  BIT40    0x0000010000000000ULL
+#define  BIT41    0x0000020000000000ULL
+#define  BIT42    0x0000040000000000ULL
+#define  BIT43    0x0000080000000000ULL
+#define  BIT44    0x0000100000000000ULL
+#define  BIT45    0x0000200000000000ULL
+#define  BIT46    0x0000400000000000ULL
+#define  BIT47    0x0000800000000000ULL
+#define  BIT48    0x0001000000000000ULL
+#define  BIT49    0x0002000000000000ULL
+#define  BIT50    0x0004000000000000ULL
+#define  BIT51    0x0008000000000000ULL
+#define  BIT52    0x0010000000000000ULL
+#define  BIT53    0x0020000000000000ULL
+#define  BIT54    0x0040000000000000ULL
+#define  BIT55    0x0080000000000000ULL
+#define  BIT56    0x0100000000000000ULL
+#define  BIT57    0x0200000000000000ULL
+#define  BIT58    0x0400000000000000ULL
+#define  BIT59    0x0800000000000000ULL
+#define  BIT60    0x1000000000000000ULL
+#define  BIT61    0x2000000000000000ULL
+#define  BIT62    0x4000000000000000ULL
+#define  BIT63    0x8000000000000000ULL
+
+#define  SIZE_1KB    0x00000400
+#define  SIZE_2KB    0x00000800
+#define  SIZE_4KB    0x00001000
+#define  SIZE_8KB    0x00002000
+#define  SIZE_16KB   0x00004000
+#define  SIZE_32KB   0x00008000
+#define  SIZE_64KB   0x00010000
+#define  SIZE_128KB  0x00020000
+#define  SIZE_256KB  0x00040000
+#define  SIZE_512KB  0x00080000
+#define  SIZE_1MB    0x00100000
+#define  SIZE_2MB    0x00200000
+#define  SIZE_4MB    0x00400000
+#define  SIZE_8MB    0x00800000
+#define  SIZE_16MB   0x01000000
+#define  SIZE_32MB   0x02000000
+#define  SIZE_64MB   0x04000000
+#define  SIZE_128MB  0x08000000
+#define  SIZE_256MB  0x10000000
+#define  SIZE_512MB  0x20000000
+#define  SIZE_1GB    0x40000000
+#define  SIZE_2GB    0x80000000
+#define  SIZE_4GB    0x0000000100000000ULL
+#define  SIZE_8GB    0x0000000200000000ULL
+#define  SIZE_16GB   0x0000000400000000ULL
+#define  SIZE_32GB   0x0000000800000000ULL
+#define  SIZE_64GB   0x0000001000000000ULL
+#define  SIZE_128GB  0x0000002000000000ULL
+#define  SIZE_256GB  0x0000004000000000ULL
+#define  SIZE_512GB  0x0000008000000000ULL
+#define  SIZE_1TB    0x0000010000000000ULL
+#define  SIZE_2TB    0x0000020000000000ULL
+#define  SIZE_4TB    0x0000040000000000ULL
+#define  SIZE_8TB    0x0000080000000000ULL
+#define  SIZE_16TB   0x0000100000000000ULL
+#define  SIZE_32TB   0x0000200000000000ULL
+#define  SIZE_64TB   0x0000400000000000ULL
+#define  SIZE_128TB  0x0000800000000000ULL
+#define  SIZE_256TB  0x0001000000000000ULL
+#define  SIZE_512TB  0x0002000000000000ULL
+#define  SIZE_1PB    0x0004000000000000ULL
+#define  SIZE_2PB    0x0008000000000000ULL
+#define  SIZE_4PB    0x0010000000000000ULL
+#define  SIZE_8PB    0x0020000000000000ULL
+#define  SIZE_16PB   0x0040000000000000ULL
+#define  SIZE_32PB   0x0080000000000000ULL
+#define  SIZE_64PB   0x0100000000000000ULL
+#define  SIZE_128PB  0x0200000000000000ULL
+#define  SIZE_256PB  0x0400000000000000ULL
+#define  SIZE_512PB  0x0800000000000000ULL
+#define  SIZE_1EB    0x1000000000000000ULL
+#define  SIZE_2EB    0x2000000000000000ULL
+#define  SIZE_4EB    0x4000000000000000ULL
+#define  SIZE_8EB    0x8000000000000000ULL
+
+#define  BASE_1KB    0x00000400
+#define  BASE_2KB    0x00000800
+#define  BASE_4KB    0x00001000
+#define  BASE_8KB    0x00002000
+#define  BASE_16KB   0x00004000
+#define  BASE_32KB   0x00008000
+#define  BASE_64KB   0x00010000
+#define  BASE_128KB  0x00020000
+#define  BASE_256KB  0x00040000
+#define  BASE_512KB  0x00080000
+#define  BASE_1MB    0x00100000
+#define  BASE_2MB    0x00200000
+#define  BASE_4MB    0x00400000
+#define  BASE_8MB    0x00800000
+#define  BASE_16MB   0x01000000
+#define  BASE_32MB   0x02000000
+#define  BASE_64MB   0x04000000
+#define  BASE_128MB  0x08000000
+#define  BASE_256MB  0x10000000
+#define  BASE_512MB  0x20000000
+#define  BASE_1GB    0x40000000
+#define  BASE_2GB    0x80000000
+#define  BASE_4GB    0x0000000100000000ULL
+#define  BASE_8GB    0x0000000200000000ULL
+#define  BASE_16GB   0x0000000400000000ULL
+#define  BASE_32GB   0x0000000800000000ULL
+#define  BASE_64GB   0x0000001000000000ULL
+#define  BASE_128GB  0x0000002000000000ULL
+#define  BASE_256GB  0x0000004000000000ULL
+#define  BASE_512GB  0x0000008000000000ULL
+#define  BASE_1TB    0x0000010000000000ULL
+#define  BASE_2TB    0x0000020000000000ULL
+#define  BASE_4TB    0x0000040000000000ULL
+#define  BASE_8TB    0x0000080000000000ULL
+#define  BASE_16TB   0x0000100000000000ULL
+#define  BASE_32TB   0x0000200000000000ULL
+#define  BASE_64TB   0x0000400000000000ULL
+#define  BASE_128TB  0x0000800000000000ULL
+#define  BASE_256TB  0x0001000000000000ULL
+#define  BASE_512TB  0x0002000000000000ULL
+#define  BASE_1PB    0x0004000000000000ULL
+#define  BASE_2PB    0x0008000000000000ULL
+#define  BASE_4PB    0x0010000000000000ULL
+#define  BASE_8PB    0x0020000000000000ULL
+#define  BASE_16PB   0x0040000000000000ULL
+#define  BASE_32PB   0x0080000000000000ULL
+#define  BASE_64PB   0x0100000000000000ULL
+#define  BASE_128PB  0x0200000000000000ULL
+#define  BASE_256PB  0x0400000000000000ULL
+#define  BASE_512PB  0x0800000000000000ULL
+#define  BASE_1EB    0x1000000000000000ULL
+#define  BASE_2EB    0x2000000000000000ULL
+#define  BASE_4EB    0x4000000000000000ULL
+#define  BASE_8EB    0x8000000000000000ULL
+
+//
+//  Support for variable length argument lists using the ANSI standard.
+//
+//  Since we are using the ANSI standard we used the standard naming and
+//  did not follow the coding convention
+//
+//  VA_LIST  - typedef for argument list.
+//  VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use.
+//  VA_END (VA_LIST Marker) - Clear Marker
+//  VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from
+//    the ... list. You must know the size and pass it in this macro.
+//  VA_COPY (VA_LIST Dest, VA_LIST Start) - Initialize Dest as a copy of Start.
+//
+//  example:
+//
+//  UINTN
+//  ExampleVarArg (
+//    IN UINTN  NumberOfArgs,
+//    ...
+//    )
+//  {
+//    VA_LIST Marker;
+//    UINTN   Index;
+//    UINTN   Result;
+//
+//    //
+//    // Initialize the Marker
+//    //
+//    VA_START (Marker, NumberOfArgs);
+//    for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) {
+//      //
+//      // The ... list is a series of UINTN values, so average them up.
+//      //
+//      Result += VA_ARG (Marker, UINTN);
+//    }
+//
+//    VA_END (Marker);
+//    return Result
+//  }
+//
+
+/**
+  Return the size of argument that has been aligned to sizeof (UINTN).
+
+  @param  n    The parameter size to be aligned.
+
+  @return The aligned size.
+**/
+#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
+
+#if defined(__CC_ARM)
+//
+// RVCT ARM variable argument list support.
+//
+
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+#ifdef __APCS_ADSABI
+  typedef int         *va_list[1];
+  #define VA_LIST     va_list
+#else
+  typedef struct __va_list { void *__ap; } va_list;
+  #define VA_LIST                          va_list
+#endif
+
+#define VA_START(Marker, Parameter)   __va_start(Marker, Parameter)
+
+#define VA_ARG(Marker, TYPE)          __va_arg(Marker, TYPE)
+
+#define VA_END(Marker)                ((void)0)
+
+// For some ARM RVCT compilers, __va_copy is not defined
+#ifndef __va_copy
+  #define __va_copy(dest, src) ((void)((dest) = (src)))
+#endif
+
+#define VA_COPY(Dest, Start)          __va_copy (Dest, Start)
+
+#elif defined(__GNUC__)
+
+#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS)
+//
+// X64 only. Use MS ABI version of GCC built-in macros for variable argument lists.
+//
+///
+/// Both GCC and LLVM 3.8 for X64 support new variable argument intrinsics for Microsoft ABI
+///
+
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+typedef __builtin_ms_va_list VA_LIST;
+
+#define VA_START(Marker, Parameter)  __builtin_ms_va_start (Marker, Parameter)
+
+#define VA_ARG(Marker, TYPE)         ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))
+
+#define VA_END(Marker)               __builtin_ms_va_end (Marker)
+
+#define VA_COPY(Dest, Start)         __builtin_ms_va_copy (Dest, Start)
+
+#else
+//
+// Use GCC built-in macros for variable argument lists.
+//
+
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+typedef __builtin_va_list VA_LIST;
+
+#define VA_START(Marker, Parameter)  __builtin_va_start (Marker, Parameter)
+
+#define VA_ARG(Marker, TYPE)         ((sizeof (TYPE) < sizeof (UINTN)) ? (TYPE)(__builtin_va_arg (Marker, UINTN)) : (TYPE)(__builtin_va_arg (Marker, TYPE)))
+
+#define VA_END(Marker)               __builtin_va_end (Marker)
+
+#define VA_COPY(Dest, Start)         __builtin_va_copy (Dest, Start)
+
+#endif
+
+#else
+///
+/// Variable used to traverse the list of arguments. This type can vary by
+/// implementation and could be an array or structure.
+///
+typedef CHAR8 *VA_LIST;
+
+/**
+  Retrieves a pointer to the beginning of a variable argument list, based on
+  the name of the parameter that immediately precedes the variable argument list.
+
+  This function initializes Marker to point to the beginning of the variable
+  argument list that immediately follows Parameter.  The method for computing the
+  pointer to the next argument in the argument list is CPU-specific following the
+  EFIAPI ABI.
+
+  @param   Marker       The VA_LIST used to traverse the list of arguments.
+  @param   Parameter    The name of the parameter that immediately precedes
+                        the variable argument list.
+
+  @return  A pointer to the beginning of a variable argument list.
+
+**/
+#define VA_START(Marker, Parameter) (Marker = (VA_LIST) ((UINTN) & (Parameter) + _INT_SIZE_OF (Parameter)))
+
+/**
+  Returns an argument of a specified type from a variable argument list and updates
+  the pointer to the variable argument list to point to the next argument.
+
+  This function returns an argument of the type specified by TYPE from the beginning
+  of the variable argument list specified by Marker.  Marker is then updated to point
+  to the next argument in the variable argument list.  The method for computing the
+  pointer to the next argument in the argument list is CPU-specific following the EFIAPI ABI.
+
+  @param   Marker   VA_LIST used to traverse the list of arguments.
+  @param   TYPE     The type of argument to retrieve from the beginning
+                    of the variable argument list.
+
+  @return  An argument of the type specified by TYPE.
+
+**/
+#define VA_ARG(Marker, TYPE)   (*(TYPE *) ((Marker += _INT_SIZE_OF (TYPE)) - _INT_SIZE_OF (TYPE)))
+
+/**
+  Terminates the use of a variable argument list.
+
+  This function initializes Marker so it can no longer be used with VA_ARG().
+  After this macro is used, the only way to access the variable argument list is
+  by using VA_START() again.
+
+  @param   Marker   VA_LIST used to traverse the list of arguments.
+
+**/
+#define VA_END(Marker)      (Marker = (VA_LIST) 0)
+
+/**
+  Initializes a VA_LIST as a copy of an existing VA_LIST.
+
+  This macro initializes Dest as a copy of Start, as if the VA_START macro had been applied to Dest
+  followed by the same sequence of uses of the VA_ARG macro as had previously been used to reach
+  the present state of Start. 
+
+  @param   Dest   VA_LIST used to traverse the list of arguments.
+  @param   Start  VA_LIST used to traverse the list of arguments.
+
+**/
+#define VA_COPY(Dest, Start)  ((void)((Dest) = (Start)))
+
+#endif
+
+///
+/// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.
+///
+typedef UINTN  *BASE_LIST;
+
+/**
+  Returns the size of a data type in sizeof(UINTN) units rounded up to the nearest UINTN boundary.
+
+  @param  TYPE  The date type to determine the size of.
+
+  @return The size of TYPE in sizeof (UINTN) units rounded up to the nearest UINTN boundary.
+**/
+#define _BASE_INT_SIZE_OF(TYPE) ((sizeof (TYPE) + sizeof (UINTN) - 1) / sizeof (UINTN))
+
+/**
+  Returns an argument of a specified type from a variable argument list and updates
+  the pointer to the variable argument list to point to the next argument.
+
+  This function returns an argument of the type specified by TYPE from the beginning
+  of the variable argument list specified by Marker.  Marker is then updated to point
+  to the next argument in the variable argument list.  The method for computing the
+  pointer to the next argument in the argument list is CPU specific following the EFIAPI ABI.
+
+  @param   Marker   The pointer to the beginning of a variable argument list.
+  @param   TYPE     The type of argument to retrieve from the beginning
+                    of the variable argument list.
+
+  @return  An argument of the type specified by TYPE.
+
+**/
+#define BASE_ARG(Marker, TYPE)   (*(TYPE *) ((Marker += _BASE_INT_SIZE_OF (TYPE)) - _BASE_INT_SIZE_OF (TYPE)))
+
+/**
+  The macro that returns the byte offset of a field in a data structure.
+
+  This function returns the offset, in bytes, of field specified by Field from the
+  beginning of the  data structure specified by TYPE. If TYPE does not contain Field,
+  the module will not compile.
+
+  @param   TYPE     The name of the data structure that contains the field specified by Field.
+  @param   Field    The name of the field in the data structure.
+
+  @return  Offset, in bytes, of field.
+
+**/
+#ifdef __GNUC__
+#if __GNUC__ >= 4
+#define OFFSET_OF(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field))
+#endif
+#endif
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+/**
+  Macro that returns a pointer to the data structure that contains a specified field of
+  that data structure.  This is a lightweight method to hide information by placing a
+  public data structure inside a larger private data structure and using a pointer to
+  the public data structure to retrieve a pointer to the private data structure.
+
+  This function computes the offset, in bytes, of field specified by Field from the beginning
+  of the  data structure specified by TYPE.  This offset is subtracted from Record, and is
+  used to return a pointer to a data structure of the type specified by TYPE. If the data type
+  specified by TYPE does not contain the field specified by Field, then the module will not compile.
+
+  @param   Record   Pointer to the field specified by Field within a data structure of type TYPE.
+  @param   TYPE     The name of the data structure type to return.  This data structure must
+                    contain the field specified by Field.
+  @param   Field    The name of the field in the data structure specified by TYPE to which Record points.
+
+  @return  A pointer to the structure from one of it's elements.
+
+**/
+#define BASE_CR(Record, TYPE, Field)  ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+/**
+  Rounds a value up to the next boundary using a specified alignment.
+
+  This function rounds Value up to the next boundary using the specified Alignment.
+  This aligned value is returned.
+
+  @param   Value      The value to round up.
+  @param   Alignment  The alignment boundary used to return the aligned value.
+
+  @return  A value up to the next boundary.
+
+**/
+#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))
+
+/**
+  Adjust a pointer by adding the minimum offset required for it to be aligned on
+  a specified alignment boundary.
+
+  This function rounds the pointer specified by Pointer to the next alignment boundary
+  specified by Alignment. The pointer to the aligned address is returned.
+
+  @param   Pointer    The pointer to round up.
+  @param   Alignment  The alignment boundary to use to return an aligned pointer.
+
+  @return  Pointer to the aligned address.
+
+**/
+#define ALIGN_POINTER(Pointer, Alignment) ((VOID *) (ALIGN_VALUE ((UINTN)(Pointer), (Alignment))))
+
+/**
+  Rounds a value up to the next natural boundary for the current CPU.
+  This is 4-bytes for 32-bit CPUs and 8-bytes for 64-bit CPUs.
+
+  This function rounds the value specified by Value up to the next natural boundary for the
+  current CPU. This rounded value is returned.
+
+  @param   Value      The value to round up.
+
+  @return  Rounded value specified by Value.
+
+**/
+#define ALIGN_VARIABLE(Value)  ALIGN_VALUE ((Value), sizeof (UINTN))
+
+
+/**
+  Return the maximum of two operands.
+
+  This macro returns the maximum of two operand specified by a and b.
+  Both a and b must be the same numerical types, signed or unsigned.
+
+  @param   a        The first operand with any numerical type.
+  @param   b        The second operand. Can be any numerical type as long as is
+                    the same type as a.
+
+  @return  Maximum of two operands.
+
+**/
+#define MAX(a, b)                       \
+  (((a) > (b)) ? (a) : (b))
+
+/**
+  Return the minimum of two operands.
+
+  This macro returns the minimal of two operand specified by a and b.
+  Both a and b must be the same numerical types, signed or unsigned.
+
+  @param   a        The first operand with any numerical type.
+  @param   b        The second operand. It should be the same any numerical type with a.
+
+  @return  Minimum of two operands.
+
+**/
+#define MIN(a, b)                       \
+  (((a) < (b)) ? (a) : (b))
+
+/**
+  Return the absolute value of a signed operand.
+
+  This macro returns the absolute value of the signed operand specified by a.
+
+  @param   a        The signed operand.
+
+  @return  The absolute value of the signed operand.
+
+**/
+#define ABS(a)                          \
+  (((a) < 0) ? (-(a)) : (a))
+
+//
+// Status codes common to all execution phases
+//
+typedef UINTN RETURN_STATUS;
+
+/**
+  Produces a RETURN_STATUS code with the highest bit set.
+
+  @param  StatusCode    The status code value to convert into a warning code.
+                        StatusCode must be in the range 0x00000000..0x7FFFFFFF.
+
+  @return The value specified by StatusCode with the highest bit set.
+
+**/
+#define ENCODE_ERROR(StatusCode)     ((RETURN_STATUS)(MAX_BIT | (StatusCode)))
+
+/**
+  Produces a RETURN_STATUS code with the highest bit clear.
+
+  @param  StatusCode    The status code value to convert into a warning code.
+                        StatusCode must be in the range 0x00000000..0x7FFFFFFF.
+
+  @return The value specified by StatusCode with the highest bit clear.
+
+**/
+#define ENCODE_WARNING(StatusCode)   ((RETURN_STATUS)(StatusCode))
+
+/**
+  Returns TRUE if a specified RETURN_STATUS code is an error code.
+
+  This function returns TRUE if StatusCode has the high bit set.  Otherwise, FALSE is returned.
+
+  @param  StatusCode    The status code value to evaluate.
+
+  @retval TRUE          The high bit of StatusCode is set.
+  @retval FALSE         The high bit of StatusCode is clear.
+
+**/
+#define RETURN_ERROR(StatusCode)     (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
+
+///
+/// The operation completed successfully.
+///
+#define RETURN_SUCCESS               0
+
+///
+/// The image failed to load.
+///
+#define RETURN_LOAD_ERROR            ENCODE_ERROR (1)
+
+///
+/// The parameter was incorrect.
+///
+#define RETURN_INVALID_PARAMETER     ENCODE_ERROR (2)
+
+///
+/// The operation is not supported.
+///
+#define RETURN_UNSUPPORTED           ENCODE_ERROR (3)
+
+///
+/// The buffer was not the proper size for the request.
+///
+#define RETURN_BAD_BUFFER_SIZE       ENCODE_ERROR (4)
+
+///
+/// The buffer was not large enough to hold the requested data.
+/// The required buffer size is returned in the appropriate
+/// parameter when this error occurs.
+///
+#define RETURN_BUFFER_TOO_SMALL      ENCODE_ERROR (5)
+
+///
+/// There is no data pending upon return.
+///
+#define RETURN_NOT_READY             ENCODE_ERROR (6)
+
+///
+/// The physical device reported an error while attempting the
+/// operation.
+///
+#define RETURN_DEVICE_ERROR          ENCODE_ERROR (7)
+
+///
+/// The device can not be written to.
+///
+#define RETURN_WRITE_PROTECTED       ENCODE_ERROR (8)
+
+///
+/// The resource has run out.
+///
+#define RETURN_OUT_OF_RESOURCES      ENCODE_ERROR (9)
+
+///
+/// An inconsistency was detected on the file system causing the
+/// operation to fail.
+///
+#define RETURN_VOLUME_CORRUPTED      ENCODE_ERROR (10)
+
+///
+/// There is no more space on the file system.
+///
+#define RETURN_VOLUME_FULL           ENCODE_ERROR (11)
+
+///
+/// The device does not contain any medium to perform the
+/// operation.
+///
+#define RETURN_NO_MEDIA              ENCODE_ERROR (12)
+
+///
+/// The medium in the device has changed since the last
+/// access.
+///
+#define RETURN_MEDIA_CHANGED         ENCODE_ERROR (13)
+
+///
+/// The item was not found.
+///
+#define RETURN_NOT_FOUND             ENCODE_ERROR (14)
+
+///
+/// Access was denied.
+///
+#define RETURN_ACCESS_DENIED         ENCODE_ERROR (15)
+
+///
+/// The server was not found or did not respond to the request.
+///
+#define RETURN_NO_RESPONSE           ENCODE_ERROR (16)
+
+///
+/// A mapping to the device does not exist.
+///
+#define RETURN_NO_MAPPING            ENCODE_ERROR (17)
+
+///
+/// A timeout time expired.
+///
+#define RETURN_TIMEOUT               ENCODE_ERROR (18)
+
+///
+/// The protocol has not been started.
+///
+#define RETURN_NOT_STARTED           ENCODE_ERROR (19)
+
+///
+/// The protocol has already been started.
+///
+#define RETURN_ALREADY_STARTED       ENCODE_ERROR (20)
+
+///
+/// The operation was aborted.
+///
+#define RETURN_ABORTED               ENCODE_ERROR (21)
+
+///
+/// An ICMP error occurred during the network operation.
+///
+#define RETURN_ICMP_ERROR            ENCODE_ERROR (22)
+
+///
+/// A TFTP error occurred during the network operation.
+///
+#define RETURN_TFTP_ERROR            ENCODE_ERROR (23)
+
+///
+/// A protocol error occurred during the network operation.
+///
+#define RETURN_PROTOCOL_ERROR        ENCODE_ERROR (24)
+
+///
+/// A function encountered an internal version that was
+/// incompatible with a version requested by the caller.
+///
+#define RETURN_INCOMPATIBLE_VERSION  ENCODE_ERROR (25)
+
+///
+/// The function was not performed due to a security violation.
+///
+#define RETURN_SECURITY_VIOLATION    ENCODE_ERROR (26)
+
+///
+/// A CRC error was detected.
+///
+#define RETURN_CRC_ERROR             ENCODE_ERROR (27)
+
+///
+/// The beginning or end of media was reached.
+///
+#define RETURN_END_OF_MEDIA          ENCODE_ERROR (28)
+
+///
+/// The end of the file was reached.
+///
+#define RETURN_END_OF_FILE           ENCODE_ERROR (31)
+
+///
+/// The language specified was invalid.
+///
+#define RETURN_INVALID_LANGUAGE      ENCODE_ERROR (32)
+
+///
+/// The security status of the data is unknown or compromised
+/// and the data must be updated or replaced to restore a valid
+/// security status.
+///
+#define RETURN_COMPROMISED_DATA      ENCODE_ERROR (33)
+
+///
+/// A HTTP error occurred during the network operation.
+///
+#define RETURN_HTTP_ERROR            ENCODE_ERROR (35)
+
+///
+/// The string contained one or more characters that
+/// the device could not render and were skipped.
+///
+#define RETURN_WARN_UNKNOWN_GLYPH    ENCODE_WARNING (1)
+
+///
+/// The handle was closed, but the file was not deleted.
+///
+#define RETURN_WARN_DELETE_FAILURE   ENCODE_WARNING (2)
+
+///
+/// The handle was closed, but the data to the file was not
+/// flushed properly.
+///
+#define RETURN_WARN_WRITE_FAILURE    ENCODE_WARNING (3)
+
+///
+/// The resulting buffer was too small, and the data was
+/// truncated to the buffer size.
+///
+#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4)
+
+///
+/// The data has not been updated within the timeframe set by
+/// local policy for this type of data.
+///
+#define RETURN_WARN_STALE_DATA       ENCODE_WARNING (5)
+
+///
+/// The resulting buffer contains UEFI-compliant file system.
+///
+#define RETURN_WARN_FILE_SYSTEM      ENCODE_WARNING (6)
+
+
+/**
+  Returns a 16-bit signature built from 2 ASCII characters.
+
+  This macro returns a 16-bit value built from the two ASCII characters specified
+  by A and B.
+
+  @param  A    The first ASCII character.
+  @param  B    The second ASCII character.
+
+  @return A 16-bit value built from the two ASCII characters specified by A and B.
+
+**/
+#define SIGNATURE_16(A, B)        ((A) | (B << 8))
+
+/**
+  Returns a 32-bit signature built from 4 ASCII characters.
+
+  This macro returns a 32-bit value built from the four ASCII characters specified
+  by A, B, C, and D.
+
+  @param  A    The first ASCII character.
+  @param  B    The second ASCII character.
+  @param  C    The third ASCII character.
+  @param  D    The fourth ASCII character.
+
+  @return A 32-bit value built from the two ASCII characters specified by A, B,
+          C and D.
+
+**/
+#define SIGNATURE_32(A, B, C, D)  (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+
+/**
+  Returns a 64-bit signature built from 8 ASCII characters.
+
+  This macro returns a 64-bit value built from the eight ASCII characters specified
+  by A, B, C, D, E, F, G,and H.
+
+  @param  A    The first ASCII character.
+  @param  B    The second ASCII character.
+  @param  C    The third ASCII character.
+  @param  D    The fourth ASCII character.
+  @param  E    The fifth ASCII character.
+  @param  F    The sixth ASCII character.
+  @param  G    The seventh ASCII character.
+  @param  H    The eighth ASCII character.
+
+  @return A 64-bit value built from the two ASCII characters specified by A, B,
+          C, D, E, F, G and H.
+
+**/
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+    (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+
+#if defined(_MSC_EXTENSIONS) && !defined (__INTEL_COMPILER) && !defined (MDE_CPU_EBC)
+  #pragma intrinsic(_ReturnAddress)
+  /**
+    Get the return address of the calling function.
+
+    Based on intrinsic function _ReturnAddress that provides the address of
+    the instruction in the calling function that will be executed after
+    control returns to the caller.
+
+    @param L    Return Level.
+
+    @return The return address of the calling function or 0 if L != 0.
+
+  **/
+  #define RETURN_ADDRESS(L)     ((L == 0) ? _ReturnAddress() : (VOID *) 0)
+#elif defined(__GNUC__)
+  void * __builtin_return_address (unsigned int level);
+  /**
+    Get the return address of the calling function.
+
+    Based on built-in Function __builtin_return_address that returns
+    the return address of the current function, or of one of its callers.
+
+    @param L    Return Level.
+
+    @return The return address of the calling function.
+
+  **/
+  #define RETURN_ADDRESS(L)     __builtin_return_address (L)
+#else
+  /**
+    Get the return address of the calling function.
+
+    @param L    Return Level.
+
+    @return 0 as compilers don't support this feature.
+
+  **/
+  #define RETURN_ADDRESS(L)     ((VOID *) 0)
+#endif
+
+/**
+  Return the number of elements in an array.
+
+  @param  Array  An object of array type. Array is only used as an argument to
+                 the sizeof operator, therefore Array is never evaluated. The
+                 caller is responsible for ensuring that Array's type is not
+                 incomplete; that is, Array must have known constant size.
+
+  @return The number of elements in Array. The result has type UINTN.
+
+**/
+#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0]))
+
+#endif
+
diff --git a/sys/contrib/edk2/Include/Guid/HiiFormMapMethodGuid.h b/sys/contrib/edk2/Include/Guid/HiiFormMapMethodGuid.h
new file mode 100644
index 0000000000..8b37807f3d
--- /dev/null
+++ b/sys/contrib/edk2/Include/Guid/HiiFormMapMethodGuid.h
@@ -0,0 +1,25 @@
+/** @file
+  Guid used to identify HII FormMap configuration method.
+
+  Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+  @par Revision Reference:
+  GUID defined in UEFI 2.2 spec.
+**/
+
+#ifndef __EFI_HII_FORMMAP_GUID_H__
+#define __EFI_HII_FORMMAP_GUID_H__
+
+#define EFI_HII_STANDARD_FORM_GUID \
+  { 0x3bd2f4ec, 0xe524, 0x46e4, { 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } }
+
+extern EFI_GUID gEfiHiiStandardFormGuid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Guid/WinCertificate.h b/sys/contrib/edk2/Include/Guid/WinCertificate.h
new file mode 100644
index 0000000000..6dea446ba0
--- /dev/null
+++ b/sys/contrib/edk2/Include/Guid/WinCertificate.h
@@ -0,0 +1,128 @@
+/** @file
+  GUID for UEFI WIN_CERTIFICATE structure.
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+  @par Revision Reference:
+  GUID defined in UEFI 2.0 spec.
+**/
+
+#ifndef __EFI_WIN_CERTIFICATE_H__
+#define __EFI_WIN_CERTIFICATE_H__
+
+//
+// _WIN_CERTIFICATE.wCertificateType
+//
+#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
+#define WIN_CERT_TYPE_EFI_PKCS115      0x0EF0
+#define WIN_CERT_TYPE_EFI_GUID         0x0EF1
+
+///
+/// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
+///
+typedef struct {
+  ///
+  /// The length of the entire certificate,
+  /// including the length of the header, in bytes.
+  ///
+  UINT32  dwLength;
+  ///
+  /// The revision level of the WIN_CERTIFICATE
+  /// structure. The current revision level is 0x0200.
+  ///
+  UINT16  wRevision;
+  ///
+  /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
+  /// certificate types. The UEFI specification reserves the range of
+  /// certificate type values from 0x0EF0 to 0x0EFF.
+  ///
+  UINT16  wCertificateType;
+  ///
+  /// The following is the actual certificate. The format of
+  /// the certificate depends on wCertificateType.
+  ///
+  /// UINT8 bCertificate[ANYSIZE_ARRAY];
+  ///
+} WIN_CERTIFICATE;
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertType
+///
+#define EFI_CERT_TYPE_RSA2048_SHA256_GUID \
+  {0xa7717414, 0xc616, 0x4977, {0x94, 0x20, 0x84, 0x47, 0x12, 0xa7, 0x35, 0xbf } }
+
+///
+/// WIN_CERTIFICATE_UEFI_GUID.CertData
+///
+typedef struct {
+  EFI_GUID  HashType;
+  UINT8     PublicKey[256];
+  UINT8     Signature[256];
+} EFI_CERT_BLOCK_RSA_2048_SHA256;
+
+
+///
+/// Certificate which encapsulates a GUID-specific digital signature
+///
+typedef struct {
+  ///
+  /// This is the standard WIN_CERTIFICATE header, where
+  /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
+  ///
+  WIN_CERTIFICATE   Hdr;
+  ///
+  /// This is the unique id which determines the
+  /// format of the CertData. .
+  ///
+  EFI_GUID          CertType;
+  ///
+  /// The following is the certificate data. The format of
+  /// the data is determined by the CertType.
+  /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
+  /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
+  ///
+  UINT8            CertData[1];
+} WIN_CERTIFICATE_UEFI_GUID;
+
+
+///
+/// Certificate which encapsulates the RSASSA_PKCS1-v1_5 digital signature.
+///
+/// The WIN_CERTIFICATE_UEFI_PKCS1_15 structure is derived from
+/// WIN_CERTIFICATE and encapsulate the information needed to
+/// implement the RSASSA-PKCS1-v1_5 digital signature algorithm as
+/// specified in RFC2437.
+///
+typedef struct {
+  ///
+  /// This is the standard WIN_CERTIFICATE header, where
+  /// wCertificateType is set to WIN_CERT_TYPE_UEFI_PKCS1_15.
+  ///
+  WIN_CERTIFICATE Hdr;
+  ///
+  /// This is the hashing algorithm which was performed on the
+  /// UEFI executable when creating the digital signature.
+  ///
+  EFI_GUID        HashAlgorithm;
+  ///
+  /// The following is the actual digital signature. The
+  /// size of the signature is the same size as the key
+  /// (1024-bit key is 128 bytes) and can be determined by
+  /// subtracting the length of the other parts of this header
+  /// from the total length of the certificate as found in
+  /// Hdr.dwLength.
+  ///
+  /// UINT8 Signature[];
+  ///
+} WIN_CERTIFICATE_EFI_PKCS1_15;
+
+extern EFI_GUID gEfiCertTypeRsa2048Sha256Guid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Library/BaseLib.h b/sys/contrib/edk2/Include/Library/BaseLib.h
new file mode 100644
index 0000000000..b41c10b1b6
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/BaseLib.h
@@ -0,0 +1,8910 @@
+/** @file
+  Provides string functions, linked list functions, math functions, synchronization
+  functions, file path functions, and CPU architecture-specific functions.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __BASE_LIB__
+#define __BASE_LIB__
+
+//
+// Definitions for architecture-specific types
+//
+#if   defined (MDE_CPU_IA32)
+///
+/// The IA-32 architecture context buffer used by SetJump() and LongJump().
+///
+typedef struct {
+  UINT32                            Ebx;
+  UINT32                            Esi;
+  UINT32                            Edi;
+  UINT32                            Ebp;
+  UINT32                            Esp;
+  UINT32                            Eip;
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4
+
+#endif // defined (MDE_CPU_IA32)
+
+#if defined (MDE_CPU_IPF)
+
+///
+/// The Itanium architecture context buffer used by SetJump() and LongJump().
+///
+typedef struct {
+  UINT64                            F2[2];
+  UINT64                            F3[2];
+  UINT64                            F4[2];
+  UINT64                            F5[2];
+  UINT64                            F16[2];
+  UINT64                            F17[2];
+  UINT64                            F18[2];
+  UINT64                            F19[2];
+  UINT64                            F20[2];
+  UINT64                            F21[2];
+  UINT64                            F22[2];
+  UINT64                            F23[2];
+  UINT64                            F24[2];
+  UINT64                            F25[2];
+  UINT64                            F26[2];
+  UINT64                            F27[2];
+  UINT64                            F28[2];
+  UINT64                            F29[2];
+  UINT64                            F30[2];
+  UINT64                            F31[2];
+  UINT64                            R4;
+  UINT64                            R5;
+  UINT64                            R6;
+  UINT64                            R7;
+  UINT64                            SP;
+  UINT64                            BR0;
+  UINT64                            BR1;
+  UINT64                            BR2;
+  UINT64                            BR3;
+  UINT64                            BR4;
+  UINT64                            BR5;
+  UINT64                            InitialUNAT;
+  UINT64                            AfterSpillUNAT;
+  UINT64                            PFS;
+  UINT64                            BSP;
+  UINT64                            Predicates;
+  UINT64                            LoopCount;
+  UINT64                            FPSR;
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 0x10
+
+#endif // defined (MDE_CPU_IPF)
+
+#if defined (MDE_CPU_X64)
+///
+/// The x64 architecture context buffer used by SetJump() and LongJump().
+///
+typedef struct {
+  UINT64                            Rbx;
+  UINT64                            Rsp;
+  UINT64                            Rbp;
+  UINT64                            Rdi;
+  UINT64                            Rsi;
+  UINT64                            R12;
+  UINT64                            R13;
+  UINT64                            R14;
+  UINT64                            R15;
+  UINT64                            Rip;
+  UINT64                            MxCsr;
+  UINT8                             XmmBuffer[160]; ///< XMM6-XMM15.
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
+
+#endif // defined (MDE_CPU_X64)
+
+#if defined (MDE_CPU_EBC)
+///
+/// The EBC context buffer used by SetJump() and LongJump().
+///
+typedef struct {
+  UINT64                            R0;
+  UINT64                            R1;
+  UINT64                            R2;
+  UINT64                            R3;
+  UINT64                            IP;
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
+
+#endif // defined (MDE_CPU_EBC)
+
+#if defined (MDE_CPU_ARM)
+
+typedef struct {
+  UINT32    R3;  ///< A copy of R13.
+  UINT32    R4;
+  UINT32    R5;
+  UINT32    R6;
+  UINT32    R7;
+  UINT32    R8;
+  UINT32    R9;
+  UINT32    R10;
+  UINT32    R11;
+  UINT32    R12;
+  UINT32    R14;
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 4
+
+#endif  // defined (MDE_CPU_ARM)
+
+#if defined (MDE_CPU_AARCH64)
+typedef struct {
+  // GP regs
+  UINT64    X19;
+  UINT64    X20;
+  UINT64    X21;
+  UINT64    X22;
+  UINT64    X23;
+  UINT64    X24;
+  UINT64    X25;
+  UINT64    X26;
+  UINT64    X27;
+  UINT64    X28;
+  UINT64    FP;
+  UINT64    LR;
+  UINT64    IP0;
+
+  // FP regs
+  UINT64    D8;
+  UINT64    D9;
+  UINT64    D10;
+  UINT64    D11;
+  UINT64    D12;
+  UINT64    D13;
+  UINT64    D14;
+  UINT64    D15;
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
+
+#endif  // defined (MDE_CPU_AARCH64)
+
+
+//
+// String Services
+//
+
+
+/**
+  Returns the length of a Null-terminated Unicode string.
+
+  This function is similar as strlen_s defined in C11.
+
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  String   A pointer to a Null-terminated Unicode string.
+  @param  MaxSize  The maximum number of Destination Unicode
+                   char, including terminating null char.
+
+  @retval 0        If String is NULL.
+  @retval MaxSize  If there is no null character in the first MaxSize characters of String.
+  @return The number of characters that percede the terminating null character.
+
+**/
+UINTN
+EFIAPI
+StrnLenS (
+  IN CONST CHAR16              *String,
+  IN UINTN                     MaxSize
+  );
+
+/**
+  Returns the size of a Null-terminated Unicode string in bytes, including the
+  Null terminator.
+
+  This function returns the size of the Null-terminated Unicode string
+  specified by String in bytes, including the Null terminator.
+
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  String   A pointer to a Null-terminated Unicode string.
+  @param  MaxSize  The maximum number of Destination Unicode
+                   char, including the Null terminator.
+
+  @retval 0  If String is NULL.
+  @retval (sizeof (CHAR16) * (MaxSize + 1))
+             If there is no Null terminator in the first MaxSize characters of
+             String.
+  @return The size of the Null-terminated Unicode string in bytes, including
+          the Null terminator.
+
+**/
+UINTN
+EFIAPI
+StrnSizeS (
+  IN CONST CHAR16              *String,
+  IN UINTN                     MaxSize
+  );
+
+/**
+  Copies the string pointed to by Source (including the terminating null char)
+  to the array pointed to by Destination.
+
+  This function is similar as strcpy_s defined in C11.
+
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Unicode string.
+  @param  DestMax                  The maximum number of Destination Unicode
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Unicode string.
+
+  @retval RETURN_SUCCESS           String is copied.
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumUnicodeStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+StrCpyS (
+  OUT CHAR16       *Destination,
+  IN  UINTN        DestMax,
+  IN  CONST CHAR16 *Source
+  );
+
+/**
+  Copies not more than Length successive char from the string pointed to by
+  Source to the array pointed to by Destination. If no null char is copied from
+  Source, then Destination[Length] is always set to null.
+
+  This function is similar as strncpy_s defined in C11.
+
+  If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Unicode string.
+  @param  DestMax                  The maximum number of Destination Unicode
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Unicode string.
+  @param  Length                   The maximum number of Unicode characters to copy.
+
+  @retval RETURN_SUCCESS           String is copied.
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than 
+                                   MIN(StrLen(Source), Length).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumUnicodeStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+StrnCpyS (
+  OUT CHAR16       *Destination,
+  IN  UINTN        DestMax,
+  IN  CONST CHAR16 *Source,
+  IN  UINTN        Length
+  );
+
+/**
+  Appends a copy of the string pointed to by Source (including the terminating
+  null char) to the end of the string pointed to by Destination.
+
+  This function is similar as strcat_s defined in C11.
+
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Unicode string.
+  @param  DestMax                  The maximum number of Destination Unicode
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Unicode string.
+
+  @retval RETURN_SUCCESS           String is appended.
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than 
+                                   StrLen(Destination).
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
+                                   greater than StrLen(Source).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumUnicodeStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+StrCatS (
+  IN OUT CHAR16       *Destination,
+  IN     UINTN        DestMax,
+  IN     CONST CHAR16 *Source
+  );
+
+/**
+  Appends not more than Length successive char from the string pointed to by
+  Source to the end of the string pointed to by Destination. If no null char is
+  copied from Source, then Destination[StrLen(Destination) + Length] is always
+  set to null.
+
+  This function is similar as strncat_s defined in C11.
+
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Unicode string.
+  @param  DestMax                  The maximum number of Destination Unicode
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Unicode string.
+  @param  Length                   The maximum number of Unicode characters to copy.
+
+  @retval RETURN_SUCCESS           String is appended.
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
+                                   StrLen(Destination).
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
+                                   greater than MIN(StrLen(Source), Length).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumUnicodeStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+StrnCatS (
+  IN OUT CHAR16       *Destination,
+  IN     UINTN        DestMax,
+  IN     CONST CHAR16 *Source,
+  IN     UINTN        Length
+  );
+
+/**
+  Convert a Null-terminated Unicode decimal string to a value of type UINTN.
+
+  This function outputs a value of type UINTN by interpreting the contents of
+  the Unicode string specified by String as a decimal number. The format of the
+  input Unicode string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before
+  [decimal digits]. The running zero in the beginning of [decimal digits] will
+  be ignored. Then, the function stops at the first character that is a not a
+  valid decimal character or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid decimal digits in the above format, then 0 is stored
+  at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINTN, then
+  MAX_UINTN is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  decimal digits right after the optional pad spaces, the value of String is
+  stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and String contains more than
+                                   PcdMaximumUnicodeStringLength Unicode
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINTN.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrDecimalToUintnS (
+  IN  CONST CHAR16             *String,
+  OUT       CHAR16             **EndPointer,  OPTIONAL
+  OUT       UINTN              *Data
+  );
+
+/**
+  Convert a Null-terminated Unicode decimal string to a value of type UINT64.
+
+  This function outputs a value of type UINT64 by interpreting the contents of
+  the Unicode string specified by String as a decimal number. The format of the
+  input Unicode string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before
+  [decimal digits]. The running zero in the beginning of [decimal digits] will
+  be ignored. Then, the function stops at the first character that is a not a
+  valid decimal character or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid decimal digits in the above format, then 0 is stored
+  at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINT64, then
+  MAX_UINT64 is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  decimal digits right after the optional pad spaces, the value of String is
+  stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and String contains more than
+                                   PcdMaximumUnicodeStringLength Unicode
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINT64.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrDecimalToUint64S (
+  IN  CONST CHAR16             *String,
+  OUT       CHAR16             **EndPointer,  OPTIONAL
+  OUT       UINT64             *Data
+  );
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a value of type
+  UINTN.
+
+  This function outputs a value of type UINTN by interpreting the contents of
+  the Unicode string specified by String as a hexadecimal number. The format of
+  the input Unicode string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+  If "x" appears in the input string, it must be prefixed with at least one 0.
+  The function will ignore the pad space, which includes spaces or tab
+  characters, before [zeros], [x] or [hexadecimal digit]. The running zero
+  before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
+  after [x] or the first valid hexadecimal digit. Then, the function stops at
+  the first character that is a not a valid hexadecimal character or NULL,
+  whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid hexadecimal digits in the above format, then 0 is
+  stored at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINTN, then
+  MAX_UINTN is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  hexadecimal digits right after the optional pad spaces, the value of String
+  is stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and String contains more than
+                                   PcdMaximumUnicodeStringLength Unicode
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINTN.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrHexToUintnS (
+  IN  CONST CHAR16             *String,
+  OUT       CHAR16             **EndPointer,  OPTIONAL
+  OUT       UINTN              *Data
+  );
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a value of type
+  UINT64.
+
+  This function outputs a value of type UINT64 by interpreting the contents of
+  the Unicode string specified by String as a hexadecimal number. The format of
+  the input Unicode string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+  If "x" appears in the input string, it must be prefixed with at least one 0.
+  The function will ignore the pad space, which includes spaces or tab
+  characters, before [zeros], [x] or [hexadecimal digit]. The running zero
+  before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
+  after [x] or the first valid hexadecimal digit. Then, the function stops at
+  the first character that is a not a valid hexadecimal character or NULL,
+  whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid hexadecimal digits in the above format, then 0 is
+  stored at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINT64, then
+  MAX_UINT64 is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  hexadecimal digits right after the optional pad spaces, the value of String
+  is stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and String contains more than
+                                   PcdMaximumUnicodeStringLength Unicode
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINT64.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrHexToUint64S (
+  IN  CONST CHAR16             *String,
+  OUT       CHAR16             **EndPointer,  OPTIONAL
+  OUT       UINT64             *Data
+  );
+
+/**
+  Returns the length of a Null-terminated Ascii string.
+
+  This function is similar as strlen_s defined in C11.
+
+  @param  String   A pointer to a Null-terminated Ascii string.
+  @param  MaxSize  The maximum number of Destination Ascii
+                   char, including terminating null char.
+
+  @retval 0        If String is NULL.
+  @retval MaxSize  If there is no null character in the first MaxSize characters of String.
+  @return The number of characters that percede the terminating null character.
+
+**/
+UINTN
+EFIAPI
+AsciiStrnLenS (
+  IN CONST CHAR8               *String,
+  IN UINTN                     MaxSize
+  );
+
+/**
+  Returns the size of a Null-terminated Ascii string in bytes, including the
+  Null terminator.
+
+  This function returns the size of the Null-terminated Ascii string specified
+  by String in bytes, including the Null terminator.
+
+  @param  String   A pointer to a Null-terminated Ascii string.
+  @param  MaxSize  The maximum number of Destination Ascii
+                   char, including the Null terminator.
+
+  @retval 0  If String is NULL.
+  @retval (sizeof (CHAR8) * (MaxSize + 1))
+             If there is no Null terminator in the first MaxSize characters of
+             String.
+  @return The size of the Null-terminated Ascii string in bytes, including the
+          Null terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiStrnSizeS (
+  IN CONST CHAR8               *String,
+  IN UINTN                     MaxSize
+  );
+
+/**
+  Copies the string pointed to by Source (including the terminating null char)
+  to the array pointed to by Destination.
+
+  This function is similar as strcpy_s defined in C11.
+
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Ascii string.
+  @param  DestMax                  The maximum number of Destination Ascii
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Ascii string.
+
+  @retval RETURN_SUCCESS           String is copied.
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumAsciiStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrCpyS (
+  OUT CHAR8        *Destination,
+  IN  UINTN        DestMax,
+  IN  CONST CHAR8  *Source
+  );
+
+/**
+  Copies not more than Length successive char from the string pointed to by
+  Source to the array pointed to by Destination. If no null char is copied from
+  Source, then Destination[Length] is always set to null.
+
+  This function is similar as strncpy_s defined in C11.
+
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Ascii string.
+  @param  DestMax                  The maximum number of Destination Ascii
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Ascii string.
+  @param  Length                   The maximum number of Ascii characters to copy.
+
+  @retval RETURN_SUCCESS           String is copied.
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than 
+                                   MIN(StrLen(Source), Length).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumAsciiStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrnCpyS (
+  OUT CHAR8        *Destination,
+  IN  UINTN        DestMax,
+  IN  CONST CHAR8  *Source,
+  IN  UINTN        Length
+  );
+
+/**
+  Appends a copy of the string pointed to by Source (including the terminating
+  null char) to the end of the string pointed to by Destination.
+
+  This function is similar as strcat_s defined in C11.
+
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Ascii string.
+  @param  DestMax                  The maximum number of Destination Ascii
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Ascii string.
+
+  @retval RETURN_SUCCESS           String is appended.
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than 
+                                   StrLen(Destination).
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
+                                   greater than StrLen(Source).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumAsciiStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrCatS (
+  IN OUT CHAR8        *Destination,
+  IN     UINTN        DestMax,
+  IN     CONST CHAR8  *Source
+  );
+
+/**
+  Appends not more than Length successive char from the string pointed to by
+  Source to the end of the string pointed to by Destination. If no null char is
+  copied from Source, then Destination[StrLen(Destination) + Length] is always
+  set to null.
+
+  This function is similar as strncat_s defined in C11.
+
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Destination              A pointer to a Null-terminated Ascii string.
+  @param  DestMax                  The maximum number of Destination Ascii
+                                   char, including terminating null char.
+  @param  Source                   A pointer to a Null-terminated Ascii string.
+  @param  Length                   The maximum number of Ascii characters to copy.
+
+  @retval RETURN_SUCCESS           String is appended.
+  @retval RETURN_BAD_BUFFER_SIZE   If DestMax is NOT greater than
+                                   StrLen(Destination).
+  @retval RETURN_BUFFER_TOO_SMALL  If (DestMax - StrLen(Destination)) is NOT
+                                   greater than MIN(StrLen(Source), Length).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and DestMax is greater than 
+                                    PcdMaximumAsciiStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrnCatS (
+  IN OUT CHAR8        *Destination,
+  IN     UINTN        DestMax,
+  IN     CONST CHAR8  *Source,
+  IN     UINTN        Length
+  );
+
+/**
+  Convert a Null-terminated Ascii decimal string to a value of type UINTN.
+
+  This function outputs a value of type UINTN by interpreting the contents of
+  the Ascii string specified by String as a decimal number. The format of the
+  input Ascii string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before
+  [decimal digits]. The running zero in the beginning of [decimal digits] will
+  be ignored. Then, the function stops at the first character that is a not a
+  valid decimal character or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than
+  PcdMaximumAsciiStringLength Ascii characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid decimal digits in the above format, then 0 is stored
+  at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINTN, then
+  MAX_UINTN is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  decimal digits right after the optional pad spaces, the value of String is
+  stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Ascii string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                   and String contains more than
+                                   PcdMaximumAsciiStringLength Ascii
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINTN.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrDecimalToUintnS (
+  IN  CONST CHAR8              *String,
+  OUT       CHAR8              **EndPointer,  OPTIONAL
+  OUT       UINTN              *Data
+  );
+
+/**
+  Convert a Null-terminated Ascii decimal string to a value of type UINT64.
+
+  This function outputs a value of type UINT64 by interpreting the contents of
+  the Ascii string specified by String as a decimal number. The format of the
+  input Ascii string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before
+  [decimal digits]. The running zero in the beginning of [decimal digits] will
+  be ignored. Then, the function stops at the first character that is a not a
+  valid decimal character or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than
+  PcdMaximumAsciiStringLength Ascii characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid decimal digits in the above format, then 0 is stored
+  at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINT64, then
+  MAX_UINT64 is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  decimal digits right after the optional pad spaces, the value of String is
+  stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Ascii string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                   and String contains more than
+                                   PcdMaximumAsciiStringLength Ascii
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINT64.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrDecimalToUint64S (
+  IN  CONST CHAR8              *String,
+  OUT       CHAR8              **EndPointer,  OPTIONAL
+  OUT       UINT64             *Data
+  );
+
+/**
+  Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
+
+  This function outputs a value of type UINTN by interpreting the contents of
+  the Ascii string specified by String as a hexadecimal number. The format of
+  the input Ascii string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
+  "x" appears in the input string, it must be prefixed with at least one 0. The
+  function will ignore the pad space, which includes spaces or tab characters,
+  before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
+  [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
+  the first valid hexadecimal digit. Then, the function stops at the first
+  character that is a not a valid hexadecimal character or Null-terminator,
+  whichever on comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than
+  PcdMaximumAsciiStringLength Ascii characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid hexadecimal digits in the above format, then 0 is
+  stored at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINTN, then
+  MAX_UINTN is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  hexadecimal digits right after the optional pad spaces, the value of String
+  is stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Ascii string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                   and String contains more than
+                                   PcdMaximumAsciiStringLength Ascii
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINTN.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrHexToUintnS (
+  IN  CONST CHAR8              *String,
+  OUT       CHAR8              **EndPointer,  OPTIONAL
+  OUT       UINTN              *Data
+  );
+
+/**
+  Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
+
+  This function outputs a value of type UINT64 by interpreting the contents of
+  the Ascii string specified by String as a hexadecimal number. The format of
+  the input Ascii string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
+  "x" appears in the input string, it must be prefixed with at least one 0. The
+  function will ignore the pad space, which includes spaces or tab characters,
+  before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
+  [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
+  the first valid hexadecimal digit. Then, the function stops at the first
+  character that is a not a valid hexadecimal character or Null-terminator,
+  whichever on comes first.
+
+  If String is NULL, then ASSERT().
+  If Data is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than
+  PcdMaximumAsciiStringLength Ascii characters, not including the
+  Null-terminator, then ASSERT().
+
+  If String has no valid hexadecimal digits in the above format, then 0 is
+  stored at the location pointed to by Data.
+  If the number represented by String exceeds the range defined by UINT64, then
+  MAX_UINT64 is stored at the location pointed to by Data.
+
+  If EndPointer is not NULL, a pointer to the character that stopped the scan
+  is stored at the location pointed to by EndPointer. If String has no valid
+  hexadecimal digits right after the optional pad spaces, the value of String
+  is stored at the location pointed to by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Ascii string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Data                     Pointer to the converted value.
+
+  @retval RETURN_SUCCESS           Value is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                   and String contains more than
+                                   PcdMaximumAsciiStringLength Ascii
+                                   characters, not including the
+                                   Null-terminator.
+  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
+                                   the range defined by UINT64.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrHexToUint64S (
+  IN  CONST CHAR8              *String,
+  OUT       CHAR8              **EndPointer,  OPTIONAL
+  OUT       UINT64             *Data
+  );
+
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Copies one Null-terminated Unicode string to another Null-terminated Unicode
+  string and returns the new Unicode string.
+
+  This function copies the contents of the Unicode string Source to the Unicode
+  string Destination, and returns Destination. If Source and Destination
+  overlap, then the results are undefined.
+
+  If Destination is NULL, then ASSERT().
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated Unicode string.
+  @param  Source      The pointer to a Null-terminated Unicode string.
+
+  @return Destination.
+
+**/
+CHAR16 *
+EFIAPI
+StrCpy (
+  OUT     CHAR16                    *Destination,
+  IN      CONST CHAR16              *Source
+  );
+
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Copies up to a specified length from one Null-terminated Unicode string to 
+  another Null-terminated Unicode string and returns the new Unicode string.
+
+  This function copies the contents of the Unicode string Source to the Unicode
+  string Destination, and returns Destination. At most, Length Unicode
+  characters are copied from Source to Destination. If Length is 0, then
+  Destination is returned unmodified. If Length is greater that the number of
+  Unicode characters in Source, then Destination is padded with Null Unicode
+  characters. If Source and Destination overlap, then the results are
+  undefined.
+
+  If Length > 0 and Destination is NULL, then ASSERT().
+  If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Length > 0 and Source is NULL, then ASSERT().
+  If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than 
+  PcdMaximumUnicodeStringLength, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+  then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated Unicode string.
+  @param  Source      The pointer to a Null-terminated Unicode string.
+  @param  Length      The maximum number of Unicode characters to copy.
+
+  @return Destination.
+
+**/
+CHAR16 *
+EFIAPI
+StrnCpy (
+  OUT     CHAR16                    *Destination,
+  IN      CONST CHAR16              *Source,
+  IN      UINTN                     Length
+  );
+#endif
+
+/**
+  Returns the length of a Null-terminated Unicode string.
+
+  This function returns the number of Unicode characters in the Null-terminated
+  Unicode string specified by String.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  String  Pointer to a Null-terminated Unicode string.
+
+  @return The length of String.
+
+**/
+UINTN
+EFIAPI
+StrLen (
+  IN      CONST CHAR16              *String
+  );
+
+
+/**
+  Returns the size of a Null-terminated Unicode string in bytes, including the
+  Null terminator.
+
+  This function returns the size, in bytes, of the Null-terminated Unicode string 
+  specified by String.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  String  The pointer to a Null-terminated Unicode string.
+
+  @return The size of String.
+
+**/
+UINTN
+EFIAPI
+StrSize (
+  IN      CONST CHAR16              *String
+  );
+
+
+/**
+  Compares two Null-terminated Unicode strings, and returns the difference
+  between the first mismatched Unicode characters.
+
+  This function compares the Null-terminated Unicode string FirstString to the
+  Null-terminated Unicode string SecondString. If FirstString is identical to
+  SecondString, then 0 is returned. Otherwise, the value returned is the first
+  mismatched Unicode character in SecondString subtracted from the first
+  mismatched Unicode character in FirstString.
+
+  If FirstString is NULL, then ASSERT().
+  If FirstString is not aligned on a 16-bit boundary, then ASSERT().
+  If SecondString is NULL, then ASSERT().
+  If SecondString is not aligned on a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
+  than PcdMaximumUnicodeStringLength Unicode characters not including the
+  Null-terminator, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
+  than PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  @param  FirstString   The pointer to a Null-terminated Unicode string.
+  @param  SecondString  The pointer to a Null-terminated Unicode string.
+
+  @retval 0      FirstString is identical to SecondString.
+  @return others FirstString is not identical to SecondString.
+
+**/
+INTN
+EFIAPI
+StrCmp (
+  IN      CONST CHAR16              *FirstString,
+  IN      CONST CHAR16              *SecondString
+  );
+
+
+/**
+  Compares up to a specified length the contents of two Null-terminated Unicode strings,
+  and returns the difference between the first mismatched Unicode characters.
+  
+  This function compares the Null-terminated Unicode string FirstString to the
+  Null-terminated Unicode string SecondString. At most, Length Unicode
+  characters will be compared. If Length is 0, then 0 is returned. If
+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the
+  value returned is the first mismatched Unicode character in SecondString
+  subtracted from the first mismatched Unicode character in FirstString.
+
+  If Length > 0 and FirstString is NULL, then ASSERT().
+  If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
+  If Length > 0 and SecondString is NULL, then ASSERT().
+  If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
+  PcdMaximumUnicodeStringLength, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
+  then ASSERT().
+
+  @param  FirstString   The pointer to a Null-terminated Unicode string.
+  @param  SecondString  The pointer to a Null-terminated Unicode string.
+  @param  Length        The maximum number of Unicode characters to compare.
+
+  @retval 0      FirstString is identical to SecondString.
+  @return others FirstString is not identical to SecondString.
+
+**/
+INTN
+EFIAPI
+StrnCmp (
+  IN      CONST CHAR16              *FirstString,
+  IN      CONST CHAR16              *SecondString,
+  IN      UINTN                     Length
+  );
+
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Concatenates one Null-terminated Unicode string to another Null-terminated
+  Unicode string, and returns the concatenated Unicode string.
+
+  This function concatenates two Null-terminated Unicode strings. The contents
+  of Null-terminated Unicode string Source are concatenated to the end of
+  Null-terminated Unicode string Destination. The Null-terminated concatenated
+  Unicode String is returned. If Source and Destination overlap, then the
+  results are undefined.
+
+  If Destination is NULL, then ASSERT().
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
+  than PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
+  and Source results in a Unicode string with more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated Unicode string.
+  @param  Source      The pointer to a Null-terminated Unicode string.
+
+  @return Destination.
+
+**/
+CHAR16 *
+EFIAPI
+StrCat (
+  IN OUT  CHAR16                    *Destination,
+  IN      CONST CHAR16              *Source
+  );
+
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Concatenates up to a specified length one Null-terminated Unicode to the end 
+  of another Null-terminated Unicode string, and returns the concatenated 
+  Unicode string.
+
+  This function concatenates two Null-terminated Unicode strings. The contents
+  of Null-terminated Unicode string Source are concatenated to the end of
+  Null-terminated Unicode string Destination, and Destination is returned. At
+  most, Length Unicode characters are concatenated from Source to the end of
+  Destination, and Destination is always Null-terminated. If Length is 0, then
+  Destination is returned unmodified. If Source and Destination overlap, then
+  the results are undefined.
+
+  If Destination is NULL, then ASSERT().
+  If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Length > 0 and Source is NULL, then ASSERT().
+  If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than 
+  PcdMaximumUnicodeStringLength, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
+  than PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
+  and Source results in a Unicode string with more than PcdMaximumUnicodeStringLength
+  Unicode characters, not including the Null-terminator, then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated Unicode string.
+  @param  Source      The pointer to a Null-terminated Unicode string.
+  @param  Length      The maximum number of Unicode characters to concatenate from
+                      Source.
+
+  @return Destination.
+
+**/
+CHAR16 *
+EFIAPI
+StrnCat (
+  IN OUT  CHAR16                    *Destination,
+  IN      CONST CHAR16              *Source,
+  IN      UINTN                     Length
+  );
+#endif
+
+/**
+  Returns the first occurrence of a Null-terminated Unicode sub-string
+  in a Null-terminated Unicode string.
+
+  This function scans the contents of the Null-terminated Unicode string
+  specified by String and returns the first occurrence of SearchString.
+  If SearchString is not found in String, then NULL is returned.  If
+  the length of SearchString is zero, then String is returned.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned on a 16-bit boundary, then ASSERT().
+  If SearchString is NULL, then ASSERT().
+  If SearchString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and SearchString
+  or String contains more than PcdMaximumUnicodeStringLength Unicode
+  characters, not including the Null-terminator, then ASSERT().
+
+  @param  String          The pointer to a Null-terminated Unicode string.
+  @param  SearchString    The pointer to a Null-terminated Unicode string to search for.
+
+  @retval NULL            If the SearchString does not appear in String.
+  @return others          If there is a match.
+
+**/
+CHAR16 *
+EFIAPI
+StrStr (
+  IN      CONST CHAR16              *String,
+  IN      CONST CHAR16              *SearchString
+  );
+
+/**
+  Convert a Null-terminated Unicode decimal string to a value of
+  type UINTN.
+
+  This function returns a value of type UINTN by interpreting the contents
+  of the Unicode string specified by String as a decimal number. The format
+  of the input Unicode string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The
+  function will ignore the pad space, which includes spaces or
+  tab characters, before [decimal digits]. The running zero in the
+  beginning of [decimal digits] will be ignored. Then, the function
+  stops at the first character that is a not a valid decimal character
+  or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If String has only pad spaces, then 0 is returned.
+  If String has no pad spaces or valid decimal digits,
+  then 0 is returned.
+  If the number represented by String overflows according
+  to the range defined by UINTN, then MAX_UINTN is returned.
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains
+  more than PcdMaximumUnicodeStringLength Unicode characters not including
+  the Null-terminator, then ASSERT().
+
+  @param  String      The pointer to a Null-terminated Unicode string.
+
+  @retval Value translated from String.
+
+**/
+UINTN
+EFIAPI
+StrDecimalToUintn (
+  IN      CONST CHAR16              *String
+  );
+
+/**
+  Convert a Null-terminated Unicode decimal string to a value of
+  type UINT64.
+
+  This function returns a value of type UINT64 by interpreting the contents
+  of the Unicode string specified by String as a decimal number. The format
+  of the input Unicode string String is:
+
+                  [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The
+  function will ignore the pad space, which includes spaces or
+  tab characters, before [decimal digits]. The running zero in the
+  beginning of [decimal digits] will be ignored. Then, the function
+  stops at the first character that is a not a valid decimal character
+  or a Null-terminator, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If String has only pad spaces, then 0 is returned.
+  If String has no pad spaces or valid decimal digits,
+  then 0 is returned.
+  If the number represented by String overflows according
+  to the range defined by UINT64, then MAX_UINT64 is returned.
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains
+  more than PcdMaximumUnicodeStringLength Unicode characters not including
+  the Null-terminator, then ASSERT().
+
+  @param  String          The pointer to a Null-terminated Unicode string.
+
+  @retval Value translated from String.
+
+**/
+UINT64
+EFIAPI
+StrDecimalToUint64 (
+  IN      CONST CHAR16              *String
+  );
+ 
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
+
+  This function returns a value of type UINTN by interpreting the contents
+  of the Unicode string specified by String as a hexadecimal number.
+  The format of the input Unicode string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+  If "x" appears in the input string, it must be prefixed with at least one 0.
+  The function will ignore the pad space, which includes spaces or tab characters,
+  before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
+  [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
+  first valid hexadecimal digit. Then, the function stops at the first character 
+  that is a not a valid hexadecimal character or NULL, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If String has only pad spaces, then zero is returned.
+  If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
+  then zero is returned.
+  If the number represented by String overflows according to the range defined by
+  UINTN, then MAX_UINTN is returned.
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String          The pointer to a Null-terminated Unicode string.
+
+  @retval Value translated from String.
+
+**/
+UINTN
+EFIAPI
+StrHexToUintn (
+  IN      CONST CHAR16              *String
+  );
+
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
+
+  This function returns a value of type UINT64 by interpreting the contents
+  of the Unicode string specified by String as a hexadecimal number.
+  The format of the input Unicode string String is
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
+  If "x" appears in the input string, it must be prefixed with at least one 0.
+  The function will ignore the pad space, which includes spaces or tab characters,
+  before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
+  [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
+  first valid hexadecimal digit. Then, the function stops at the first character that is
+  a not a valid hexadecimal character or NULL, whichever one comes first.
+
+  If String is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+  If String has only pad spaces, then zero is returned.
+  If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
+  then zero is returned.
+  If the number represented by String overflows according to the range defined by
+  UINT64, then MAX_UINT64 is returned.
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String          The pointer to a Null-terminated Unicode string.
+
+  @retval Value translated from String.
+
+**/
+UINT64
+EFIAPI
+StrHexToUint64 (
+  IN      CONST CHAR16             *String
+  );
+
+/**
+  Convert a Null-terminated Unicode string to IPv6 address and prefix length.
+
+  This function outputs a value of type IPv6_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the Unicode string specified
+  by String. The format of the input Unicode string String is as follows:
+
+                  X:X:X:X:X:X:X:X[/P]
+
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
+  memory address and high byte is stored in high memory address. P contains decimal
+  digit characters in the range [0-9]. The running zero in the beginning of P will
+  be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid hexadecimal digit character after eight X's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  "::" can be used to compress one or more groups of X when X contains only 0.
+  The "::" can only appear once in the String.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv6 address.
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If X contains more than four hexadecimal
+                                    digit characters.
+                                   If String contains "::" and number of X
+                                    is not less than 8.
+                                   If P starts with character that is not a
+                                    valid decimal digit character.
+                                   If the decimal number converted from P
+                                    exceeds 128.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToIpv6Address (
+  IN  CONST CHAR16       *String,
+  OUT CHAR16             **EndPointer, OPTIONAL
+  OUT IPv6_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+/**
+  Convert a Null-terminated Unicode string to IPv4 address and prefix length.
+
+  This function outputs a value of type IPv4_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the Unicode string specified
+  by String. The format of the input Unicode string String is as follows:
+
+                  D.D.D.D[/P]
+
+  D and P are decimal digit characters in the range [0-9]. The running zero in
+  the beginning of D and P will be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid decimal digit character after four D's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
+  PcdMaximumUnicodeStringLength Unicode characters, not including the
+  Null-terminator, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv4 address.
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If String is not in the correct format.
+                                   If any decimal number converted from D
+                                    exceeds 255.
+                                   If the decimal number converted from P
+                                    exceeds 32.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToIpv4Address (
+  IN  CONST CHAR16       *String,
+  OUT CHAR16             **EndPointer, OPTIONAL
+  OUT IPv4_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+#define GUID_STRING_LENGTH  36
+
+/**
+  Convert a Null-terminated Unicode GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the Unicode string specified by String. The format of the input
+  Unicode string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If String is not as the above format.
+
+**/
+RETURN_STATUS
+EFIAPI
+StrToGuid (
+  IN  CONST CHAR16       *String,
+  OUT GUID               *Guid
+  );
+
+/**
+  Convert a Null-terminated Unicode hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the Unicode string specified by String in hexadecimal format. The format of
+  the input Unicode string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is not aligned in a 16-bit boundary, then ASSERT().
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero and Length is greater than
+  PcdMaximumUnicodeStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated Unicode string.
+  @param  Length                   The number of Unicode characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumUnicodeStringLength.
+  @retval RETURN_UNSUPPORTED       If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+EFIAPI
+StrHexToBytes (
+  IN  CONST CHAR16       *String,
+  IN  UINTN              Length,
+  OUT UINT8              *Buffer,
+  IN  UINTN              MaxBufferSize
+  );
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Convert a Null-terminated Unicode string to a Null-terminated
+  ASCII string and returns the ASCII string.
+
+  This function converts the content of the Unicode string Source
+  to the ASCII string Destination by copying the lower 8 bits of
+  each Unicode character. It returns Destination.
+
+  The caller is responsible to make sure Destination points to a buffer with size
+  equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
+
+  If any Unicode characters in Source contain non-zero value in
+  the upper 8 bits, then ASSERT().
+
+  If Destination is NULL, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains
+  more than PcdMaximumUnicodeStringLength Unicode characters not including
+  the Null-terminator, then ASSERT().
+
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more
+  than PcdMaximumAsciiStringLength Unicode characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  Source        The pointer to a Null-terminated Unicode string.
+  @param  Destination   The pointer to a Null-terminated ASCII string.
+
+  @return Destination.
+
+**/
+CHAR8 *
+EFIAPI
+UnicodeStrToAsciiStr (
+  IN      CONST CHAR16              *Source,
+  OUT     CHAR8                     *Destination
+  );
+
+#endif
+
+/**
+  Convert a Null-terminated Unicode string to a Null-terminated
+  ASCII string.
+
+  This function is similar to AsciiStrCpyS.
+
+  This function converts the content of the Unicode string Source
+  to the ASCII string Destination by copying the lower 8 bits of
+  each Unicode character. The function terminates the ASCII string
+  Destination by appending a Null-terminator character at the end.
+
+  The caller is responsible to make sure Destination points to a buffer with size
+  equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
+
+  If any Unicode characters in Source contain non-zero value in
+  the upper 8 bits, then ASSERT().
+
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Source        The pointer to a Null-terminated Unicode string.
+  @param  Destination   The pointer to a Null-terminated ASCII string.
+  @param  DestMax       The maximum number of Destination Ascii
+                        char, including terminating null char.
+
+  @retval RETURN_SUCCESS           String is converted.
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and DestMax is greater than
+                                    PcdMaximumAsciiStringLength.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and DestMax is greater than
+                                    PcdMaximumUnicodeStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+
+**/
+RETURN_STATUS
+EFIAPI
+UnicodeStrToAsciiStrS (
+  IN      CONST CHAR16              *Source,
+  OUT     CHAR8                     *Destination,
+  IN      UINTN                     DestMax
+  );
+
+/**
+  Convert not more than Length successive characters from a Null-terminated
+  Unicode string to a Null-terminated Ascii string. If no null char is copied
+  from Source, then Destination[Length] is always set to null.
+
+  This function converts not more than Length successive characters from the
+  Unicode string Source to the Ascii string Destination by copying the lower 8
+  bits of each Unicode character. The function terminates the Ascii string
+  Destination by appending a Null-terminator character at the end.
+
+  The caller is responsible to make sure Destination points to a buffer with size
+  equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
+
+  If any Unicode characters in Source contain non-zero value in the upper 8
+  bits, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Source             The pointer to a Null-terminated Unicode string.
+  @param  Length             The maximum number of Unicode characters to
+                             convert.
+  @param  Destination        The pointer to a Null-terminated Ascii string.
+  @param  DestMax            The maximum number of Destination Ascii
+                             char, including terminating null char.
+  @param  DestinationLength  The number of Unicode characters converted.
+
+  @retval RETURN_SUCCESS            String is converted.
+  @retval RETURN_INVALID_PARAMETER  If Destination is NULL.
+                                    If Source is NULL.
+                                    If DestinationLength is NULL.
+                                    If PcdMaximumAsciiStringLength is not zero,
+                                    and Length or DestMax is greater than
+                                    PcdMaximumAsciiStringLength.
+                                    If PcdMaximumUnicodeStringLength is not
+                                    zero, and Length or DestMax is greater than
+                                    PcdMaximumUnicodeStringLength.
+                                    If DestMax is 0.
+  @retval RETURN_BUFFER_TOO_SMALL   If DestMax is NOT greater than
+                                    MIN(StrLen(Source), Length).
+  @retval RETURN_ACCESS_DENIED      If Source and Destination overlap.
+
+**/
+RETURN_STATUS
+EFIAPI
+UnicodeStrnToAsciiStrS (
+  IN      CONST CHAR16              *Source,
+  IN      UINTN                     Length,
+  OUT     CHAR8                     *Destination,
+  IN      UINTN                     DestMax,
+  OUT     UINTN                     *DestinationLength
+  );
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Copies one Null-terminated ASCII string to another Null-terminated ASCII
+  string and returns the new ASCII string.
+
+  This function copies the contents of the ASCII string Source to the ASCII
+  string Destination, and returns Destination. If Source and Destination
+  overlap, then the results are undefined.
+
+  If Destination is NULL, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and Source contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated ASCII string.
+  @param  Source      The pointer to a Null-terminated ASCII string.
+
+  @return Destination
+
+**/
+CHAR8 *
+EFIAPI
+AsciiStrCpy (
+  OUT     CHAR8                     *Destination,
+  IN      CONST CHAR8               *Source
+  );
+
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Copies up to a specified length one Null-terminated ASCII string to another 
+  Null-terminated ASCII string and returns the new ASCII string.
+
+  This function copies the contents of the ASCII string Source to the ASCII
+  string Destination, and returns Destination. At most, Length ASCII characters
+  are copied from Source to Destination. If Length is 0, then Destination is
+  returned unmodified. If Length is greater that the number of ASCII characters
+  in Source, then Destination is padded with Null ASCII characters. If Source
+  and Destination overlap, then the results are undefined.
+
+  If Destination is NULL, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Length is greater than 
+  PcdMaximumAsciiStringLength, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
+  then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated ASCII string.
+  @param  Source      The pointer to a Null-terminated ASCII string.
+  @param  Length      The maximum number of ASCII characters to copy.
+
+  @return Destination
+
+**/
+CHAR8 *
+EFIAPI
+AsciiStrnCpy (
+  OUT     CHAR8                     *Destination,
+  IN      CONST CHAR8               *Source,
+  IN      UINTN                     Length
+  );
+#endif
+
+/**
+  Returns the length of a Null-terminated ASCII string.
+
+  This function returns the number of ASCII characters in the Null-terminated
+  ASCII string specified by String.
+
+  If Length > 0 and Destination is NULL, then ASSERT().
+  If Length > 0 and Source is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and String contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String  The pointer to a Null-terminated ASCII string.
+
+  @return The length of String.
+
+**/
+UINTN
+EFIAPI
+AsciiStrLen (
+  IN      CONST CHAR8               *String
+  );
+
+
+/**
+  Returns the size of a Null-terminated ASCII string in bytes, including the
+  Null terminator.
+
+  This function returns the size, in bytes, of the Null-terminated ASCII string
+  specified by String.
+
+  If String is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and String contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String  The pointer to a Null-terminated ASCII string.
+
+  @return The size of String.
+
+**/
+UINTN
+EFIAPI
+AsciiStrSize (
+  IN      CONST CHAR8               *String
+  );
+
+
+/**
+  Compares two Null-terminated ASCII strings, and returns the difference
+  between the first mismatched ASCII characters.
+
+  This function compares the Null-terminated ASCII string FirstString to the
+  Null-terminated ASCII string SecondString. If FirstString is identical to
+  SecondString, then 0 is returned. Otherwise, the value returned is the first
+  mismatched ASCII character in SecondString subtracted from the first
+  mismatched ASCII character in FirstString.
+
+  If FirstString is NULL, then ASSERT().
+  If SecondString is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more
+  than PcdMaximumAsciiStringLength ASCII characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  FirstString   The pointer to a Null-terminated ASCII string.
+  @param  SecondString  The pointer to a Null-terminated ASCII string.
+
+  @retval ==0      FirstString is identical to SecondString.
+  @retval !=0      FirstString is not identical to SecondString.
+
+**/
+INTN
+EFIAPI
+AsciiStrCmp (
+  IN      CONST CHAR8               *FirstString,
+  IN      CONST CHAR8               *SecondString
+  );
+
+
+/**
+  Performs a case insensitive comparison of two Null-terminated ASCII strings,
+  and returns the difference between the first mismatched ASCII characters.
+
+  This function performs a case insensitive comparison of the Null-terminated
+  ASCII string FirstString to the Null-terminated ASCII string SecondString. If
+  FirstString is identical to SecondString, then 0 is returned. Otherwise, the
+  value returned is the first mismatched lower case ASCII character in
+  SecondString subtracted from the first mismatched lower case ASCII character
+  in FirstString.
+
+  If FirstString is NULL, then ASSERT().
+  If SecondString is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and SecondString contains more
+  than PcdMaximumAsciiStringLength ASCII characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  FirstString   The pointer to a Null-terminated ASCII string.
+  @param  SecondString  The pointer to a Null-terminated ASCII string.
+
+  @retval ==0    FirstString is identical to SecondString using case insensitive
+                 comparisons.
+  @retval !=0    FirstString is not identical to SecondString using case
+                 insensitive comparisons.
+
+**/
+INTN
+EFIAPI
+AsciiStriCmp (
+  IN      CONST CHAR8               *FirstString,
+  IN      CONST CHAR8               *SecondString
+  );
+
+
+/**
+  Compares two Null-terminated ASCII strings with maximum lengths, and returns
+  the difference between the first mismatched ASCII characters.
+
+  This function compares the Null-terminated ASCII string FirstString to the
+  Null-terminated ASCII  string SecondString. At most, Length ASCII characters
+  will be compared. If Length is 0, then 0 is returned. If FirstString is
+  identical to SecondString, then 0 is returned. Otherwise, the value returned
+  is the first mismatched ASCII character in SecondString subtracted from the
+  first mismatched ASCII character in FirstString.
+
+  If Length > 0 and FirstString is NULL, then ASSERT().
+  If Length > 0 and SecondString is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Length is greater than 
+  PcdMaximumAsciiStringLength, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
+  then ASSERT().
+
+  @param  FirstString   The pointer to a Null-terminated ASCII string.
+  @param  SecondString  The pointer to a Null-terminated ASCII string.
+  @param  Length        The maximum number of ASCII characters for compare.
+  
+  @retval ==0       FirstString is identical to SecondString.
+  @retval !=0       FirstString is not identical to SecondString.
+
+**/
+INTN
+EFIAPI
+AsciiStrnCmp (
+  IN      CONST CHAR8               *FirstString,
+  IN      CONST CHAR8               *SecondString,
+  IN      UINTN                     Length
+  );
+
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Concatenates one Null-terminated ASCII string to another Null-terminated
+  ASCII string, and returns the concatenated ASCII string.
+
+  This function concatenates two Null-terminated ASCII strings. The contents of
+  Null-terminated ASCII string Source are concatenated to the end of Null-
+  terminated ASCII string Destination. The Null-terminated concatenated ASCII
+  String is returned.
+
+  If Destination is NULL, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and Destination contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and Source contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and concatenating Destination and
+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength
+  ASCII characters, then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated ASCII string.
+  @param  Source      The pointer to a Null-terminated ASCII string.
+
+  @return Destination
+
+**/
+CHAR8 *
+EFIAPI
+AsciiStrCat (
+  IN OUT CHAR8    *Destination,
+  IN CONST CHAR8  *Source
+  );
+
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Concatenates up to a specified length one Null-terminated ASCII string to 
+  the end of another Null-terminated ASCII string, and returns the 
+  concatenated ASCII string.
+
+  This function concatenates two Null-terminated ASCII strings. The contents
+  of Null-terminated ASCII string Source are concatenated to the end of Null-
+  terminated ASCII string Destination, and Destination is returned. At most,
+  Length ASCII characters are concatenated from Source to the end of
+  Destination, and Destination is always Null-terminated. If Length is 0, then
+  Destination is returned unmodified. If Source and Destination overlap, then
+  the results are undefined.
+
+  If Length > 0 and Destination is NULL, then ASSERT().
+  If Length > 0 and Source is NULL, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Length is greater than
+  PcdMaximumAsciiStringLength, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Destination contains more than
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and
+  Source results in a ASCII string with more than PcdMaximumAsciiStringLength
+  ASCII characters, not including the Null-terminator, then ASSERT().
+
+  @param  Destination The pointer to a Null-terminated ASCII string.
+  @param  Source      The pointer to a Null-terminated ASCII string.
+  @param  Length      The maximum number of ASCII characters to concatenate from
+                      Source.
+
+  @return Destination
+
+**/
+CHAR8 *
+EFIAPI
+AsciiStrnCat (
+  IN OUT  CHAR8                     *Destination,
+  IN      CONST CHAR8               *Source,
+  IN      UINTN                     Length
+  );
+#endif
+
+/**
+  Returns the first occurrence of a Null-terminated ASCII sub-string
+  in a Null-terminated ASCII string.
+
+  This function scans the contents of the ASCII string specified by String
+  and returns the first occurrence of SearchString. If SearchString is not
+  found in String, then NULL is returned. If the length of SearchString is zero,
+  then String is returned.
+
+  If String is NULL, then ASSERT().
+  If SearchString is NULL, then ASSERT().
+
+  If PcdMaximumAsciiStringLength is not zero, and SearchString or
+  String contains more than PcdMaximumAsciiStringLength Unicode characters
+  not including the Null-terminator, then ASSERT().
+
+  @param  String          The pointer to a Null-terminated ASCII string.
+  @param  SearchString    The pointer to a Null-terminated ASCII string to search for.
+
+  @retval NULL            If the SearchString does not appear in String.
+  @retval others          If there is a match return the first occurrence of SearchingString.
+                          If the length of SearchString is zero,return String.
+
+**/
+CHAR8 *
+EFIAPI
+AsciiStrStr (
+  IN      CONST CHAR8               *String,
+  IN      CONST CHAR8               *SearchString
+  );
+
+
+/**
+  Convert a Null-terminated ASCII decimal string to a value of type
+  UINTN.
+
+  This function returns a value of type UINTN by interpreting the contents
+  of the ASCII string String as a decimal number. The format of the input
+  ASCII string String is:
+
+                    [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before the digits.
+  The running zero in the beginning of [decimal digits] will be ignored. Then, the
+  function stops at the first character that is a not a valid decimal character or
+  Null-terminator, whichever on comes first.
+
+  If String has only pad spaces, then 0 is returned.
+  If String has no pad spaces or valid decimal digits, then 0 is returned.
+  If the number represented by String overflows according to the range defined by
+  UINTN, then MAX_UINTN is returned.
+  If String is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String          The pointer to a Null-terminated ASCII string.
+
+  @retval The value translated from String.
+
+**/
+UINTN
+EFIAPI
+AsciiStrDecimalToUintn (
+  IN      CONST CHAR8               *String
+  );
+
+
+/**
+  Convert a Null-terminated ASCII decimal string to a value of type
+  UINT64.
+
+  This function returns a value of type UINT64 by interpreting the contents
+  of the ASCII string String as a decimal number. The format of the input
+  ASCII string String is:
+
+                    [spaces] [decimal digits].
+
+  The valid decimal digit character is in the range [0-9]. The function will
+  ignore the pad space, which includes spaces or tab characters, before the digits.
+  The running zero in the beginning of [decimal digits] will be ignored. Then, the
+  function stops at the first character that is a not a valid decimal character or
+  Null-terminator, whichever on comes first.
+
+  If String has only pad spaces, then 0 is returned.
+  If String has no pad spaces or valid decimal digits, then 0 is returned.
+  If the number represented by String overflows according to the range defined by
+  UINT64, then MAX_UINT64 is returned.
+  If String is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and String contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String          The pointer to a Null-terminated ASCII string.
+
+  @retval Value translated from String.
+
+**/
+UINT64
+EFIAPI
+AsciiStrDecimalToUint64 (
+  IN      CONST CHAR8               *String
+  );
+
+
+/**
+  Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
+
+  This function returns a value of type UINTN by interpreting the contents of
+  the ASCII string String as a hexadecimal number. The format of the input ASCII
+  string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
+  appears in the input string, it must be prefixed with at least one 0. The function
+  will ignore the pad space, which includes spaces or tab characters, before [zeros],
+  [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
+  will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
+  digit. Then, the function stops at the first character that is a not a valid
+  hexadecimal character or Null-terminator, whichever on comes first.
+
+  If String has only pad spaces, then 0 is returned.
+  If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
+  0 is returned.
+
+  If the number represented by String overflows according to the range defined by UINTN,
+  then MAX_UINTN is returned.
+  If String is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero,
+  and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
+  the Null-terminator, then ASSERT().
+
+  @param  String          The pointer to a Null-terminated ASCII string.
+
+  @retval Value translated from String.
+
+**/
+UINTN
+EFIAPI
+AsciiStrHexToUintn (
+  IN      CONST CHAR8               *String
+  );
+
+
+/**
+  Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
+
+  This function returns a value of type UINT64 by interpreting the contents of
+  the ASCII string String as a hexadecimal number. The format of the input ASCII
+  string String is:
+
+                  [spaces][zeros][x][hexadecimal digits].
+
+  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
+  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
+  appears in the input string, it must be prefixed with at least one 0. The function
+  will ignore the pad space, which includes spaces or tab characters, before [zeros],
+  [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
+  will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
+  digit. Then, the function stops at the first character that is a not a valid
+  hexadecimal character or Null-terminator, whichever on comes first.
+
+  If String has only pad spaces, then 0 is returned.
+  If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
+  0 is returned.
+
+  If the number represented by String overflows according to the range defined by UINT64,
+  then MAX_UINT64 is returned.
+  If String is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero,
+  and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
+  the Null-terminator, then ASSERT().
+
+  @param  String          The pointer to a Null-terminated ASCII string.
+
+  @retval Value translated from String.
+
+**/
+UINT64
+EFIAPI
+AsciiStrHexToUint64 (
+  IN      CONST CHAR8                *String
+  );
+
+/**
+  Convert a Null-terminated ASCII string to IPv6 address and prefix length.
+
+  This function outputs a value of type IPv6_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the ASCII string specified
+  by String. The format of the input ASCII string String is as follows:
+
+                  X:X:X:X:X:X:X:X[/P]
+
+  X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
+  [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
+  memory address and high byte is stored in high memory address. P contains decimal
+  digit characters in the range [0-9]. The running zero in the beginning of P will
+  be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid hexadecimal digit character after eight X's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  "::" can be used to compress one or more groups of X when X contains only 0.
+  The "::" can only appear once in the String.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv6 address.
+  @param  PrefixLength             Pointer to the converted IPv6 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If X contains more than four hexadecimal
+                                    digit characters.
+                                   If String contains "::" and number of X
+                                    is not less than 8.
+                                   If P starts with character that is not a
+                                    valid decimal digit character.
+                                   If the decimal number converted from P
+                                    exceeds 128.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToIpv6Address (
+  IN  CONST CHAR8        *String,
+  OUT CHAR8              **EndPointer, OPTIONAL
+  OUT IPv6_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+/**
+  Convert a Null-terminated ASCII string to IPv4 address and prefix length.
+
+  This function outputs a value of type IPv4_ADDRESS and may output a value
+  of type UINT8 by interpreting the contents of the ASCII string specified
+  by String. The format of the input ASCII string String is as follows:
+
+                  D.D.D.D[/P]
+
+  D and P are decimal digit characters in the range [0-9]. The running zero in
+  the beginning of D and P will be ignored. /P is optional.
+
+  When /P is not in the String, the function stops at the first character that is
+  not a valid decimal digit character after four D's are converted.
+
+  When /P is in the String, the function stops at the first character that is not
+  a valid decimal digit character after P is converted.
+
+  If String is NULL, then ASSERT().
+
+  If Address is NULL, then ASSERT().
+
+  If EndPointer is not NULL and Address is translated from String, a pointer
+  to the character that stopped the scan is stored at the location pointed to
+  by EndPointer.
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  EndPointer               Pointer to character that stops scan.
+  @param  Address                  Pointer to the converted IPv4 address.
+  @param  PrefixLength             Pointer to the converted IPv4 address prefix
+                                   length. MAX_UINT8 is returned when /P is
+                                   not in the String.
+
+  @retval RETURN_SUCCESS           Address is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If String is not in the correct format.
+                                   If any decimal number converted from D
+                                    exceeds 255.
+                                   If the decimal number converted from P
+                                    exceeds 32.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToIpv4Address (
+  IN  CONST CHAR8        *String,
+  OUT CHAR8              **EndPointer, OPTIONAL
+  OUT IPv4_ADDRESS       *Address,
+  OUT UINT8              *PrefixLength OPTIONAL
+  );
+
+/**
+  Convert a Null-terminated ASCII GUID string to a value of type
+  EFI_GUID.
+
+  This function outputs a GUID value by interpreting the contents of
+  the ASCII string specified by String. The format of the input
+  ASCII string String consists of 36 characters, as follows:
+
+                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+
+  The pairs aa - pp are two characters in the range [0-9], [a-f] and
+  [A-F], with each pair representing a single byte hexadecimal value.
+
+  The mapping between String and the EFI_GUID structure is as follows:
+                  aa          Data1[24:31]
+                  bb          Data1[16:23]
+                  cc          Data1[8:15]
+                  dd          Data1[0:7]
+                  ee          Data2[8:15]
+                  ff          Data2[0:7]
+                  gg          Data3[8:15]
+                  hh          Data3[0:7]
+                  ii          Data4[0:7]
+                  jj          Data4[8:15]
+                  kk          Data4[16:23]
+                  ll          Data4[24:31]
+                  mm          Data4[32:39]
+                  nn          Data4[40:47]
+                  oo          Data4[48:55]
+                  pp          Data4[56:63]
+
+  If String is NULL, then ASSERT().
+  If Guid is NULL, then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  Guid                     Pointer to the converted GUID.
+
+  @retval RETURN_SUCCESS           Guid is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+  @retval RETURN_UNSUPPORTED       If String is not as the above format.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToGuid (
+  IN  CONST CHAR8        *String,
+  OUT GUID               *Guid
+  );
+
+/**
+  Convert a Null-terminated ASCII hexadecimal string to a byte array.
+
+  This function outputs a byte array by interpreting the contents of
+  the ASCII string specified by String in hexadecimal format. The format of
+  the input ASCII string String is:
+
+                  [XX]*
+
+  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
+  The function decodes every two hexadecimal digit characters as one byte. The
+  decoding stops after Length of characters and outputs Buffer containing
+  (Length / 2) bytes.
+
+  If String is NULL, then ASSERT().
+
+  If Buffer is NULL, then ASSERT().
+
+  If Length is not multiple of 2, then ASSERT().
+
+  If PcdMaximumAsciiStringLength is not zero and Length is greater than
+  PcdMaximumAsciiStringLength, then ASSERT().
+
+  If MaxBufferSize is less than (Length / 2), then ASSERT().
+
+  @param  String                   Pointer to a Null-terminated ASCII string.
+  @param  Length                   The number of ASCII characters to decode.
+  @param  Buffer                   Pointer to the converted bytes array.
+  @param  MaxBufferSize            The maximum size of Buffer.
+
+  @retval RETURN_SUCCESS           Buffer is translated from String.
+  @retval RETURN_INVALID_PARAMETER If String is NULL.
+                                   If Data is NULL.
+                                   If Length is not multiple of 2.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and Length is greater than
+                                    PcdMaximumAsciiStringLength.
+  @retval RETURN_UNSUPPORTED       If Length of characters from String contain
+                                    a character that is not valid hexadecimal
+                                    digit characters, or a Null-terminator.
+  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrHexToBytes (
+  IN  CONST CHAR8        *String,
+  IN  UINTN              Length,
+  OUT UINT8              *Buffer,
+  IN  UINTN              MaxBufferSize
+  );
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Convert one Null-terminated ASCII string to a Null-terminated
+  Unicode string and returns the Unicode string.
+
+  This function converts the contents of the ASCII string Source to the Unicode
+  string Destination, and returns Destination.  The function terminates the
+  Unicode string Destination by appending a Null-terminator character at the end.
+  The caller is responsible to make sure Destination points to a buffer with size
+  equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
+
+  If Destination is NULL, then ASSERT().
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
+  PcdMaximumUnicodeStringLength ASCII characters not including the
+  Null-terminator, then ASSERT().
+
+  @param  Source        The pointer to a Null-terminated ASCII string.
+  @param  Destination   The pointer to a Null-terminated Unicode string.
+
+  @return Destination.
+
+**/
+CHAR16 *
+EFIAPI
+AsciiStrToUnicodeStr (
+  IN      CONST CHAR8               *Source,
+  OUT     CHAR16                    *Destination
+  );
+
+#endif
+
+/**
+  Convert one Null-terminated ASCII string to a Null-terminated
+  Unicode string.
+
+  This function is similar to StrCpyS.
+
+  This function converts the contents of the ASCII string Source to the Unicode
+  string Destination. The function terminates the Unicode string Destination by
+  appending a Null-terminator character at the end.
+
+  The caller is responsible to make sure Destination points to a buffer with size
+  equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
+
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then the Destination is unmodified.
+
+  @param  Source        The pointer to a Null-terminated ASCII string.
+  @param  Destination   The pointer to a Null-terminated Unicode string.
+  @param  DestMax       The maximum number of Destination Unicode
+                        char, including terminating null char.
+
+  @retval RETURN_SUCCESS           String is converted.
+  @retval RETURN_BUFFER_TOO_SMALL  If DestMax is NOT greater than StrLen(Source).
+  @retval RETURN_INVALID_PARAMETER If Destination is NULL.
+                                   If Source is NULL.
+                                   If PcdMaximumUnicodeStringLength is not zero,
+                                    and DestMax is greater than
+                                    PcdMaximumUnicodeStringLength.
+                                   If PcdMaximumAsciiStringLength is not zero,
+                                    and DestMax is greater than
+                                    PcdMaximumAsciiStringLength.
+                                   If DestMax is 0.
+  @retval RETURN_ACCESS_DENIED     If Source and Destination overlap.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrToUnicodeStrS (
+  IN      CONST CHAR8               *Source,
+  OUT     CHAR16                    *Destination,
+  IN      UINTN                     DestMax
+  );
+
+/**
+  Convert not more than Length successive characters from a Null-terminated
+  Ascii string to a Null-terminated Unicode string. If no null char is copied
+  from Source, then Destination[Length] is always set to null.
+
+  This function converts not more than Length successive characters from the
+  Ascii string Source to the Unicode string Destination. The function
+  terminates the Unicode string Destination by appending a Null-terminator
+  character at the end.
+
+  The caller is responsible to make sure Destination points to a buffer with
+  size not smaller than
+  ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
+
+  If Destination is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  If an error is returned, then Destination and DestinationLength are
+  unmodified.
+
+  @param  Source             The pointer to a Null-terminated Ascii string.
+  @param  Length             The maximum number of Ascii characters to convert.
+  @param  Destination        The pointer to a Null-terminated Unicode string.
+  @param  DestMax            The maximum number of Destination Unicode char,
+                             including terminating null char.
+  @param  DestinationLength  The number of Ascii characters converted.
+
+  @retval RETURN_SUCCESS            String is converted.
+  @retval RETURN_INVALID_PARAMETER  If Destination is NULL.
+                                    If Source is NULL.
+                                    If DestinationLength is NULL.
+                                    If PcdMaximumUnicodeStringLength is not
+                                    zero, and Length or DestMax is greater than
+                                    PcdMaximumUnicodeStringLength.
+                                    If PcdMaximumAsciiStringLength is not zero,
+                                    and Length or DestMax is greater than
+                                    PcdMaximumAsciiStringLength.
+                                    If DestMax is 0.
+  @retval RETURN_BUFFER_TOO_SMALL   If DestMax is NOT greater than
+                                    MIN(AsciiStrLen(Source), Length).
+  @retval RETURN_ACCESS_DENIED      If Source and Destination overlap.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiStrnToUnicodeStrS (
+  IN      CONST CHAR8               *Source,
+  IN      UINTN                     Length,
+  OUT     CHAR16                    *Destination,
+  IN      UINTN                     DestMax,
+  OUT     UINTN                     *DestinationLength
+  );
+
+/**
+  Converts an 8-bit value to an 8-bit BCD value.
+
+  Converts the 8-bit value specified by Value to BCD. The BCD value is
+  returned.
+
+  If Value >= 100, then ASSERT().
+
+  @param  Value The 8-bit value to convert to BCD. Range 0..99.
+
+  @return The BCD value.
+
+**/
+UINT8
+EFIAPI
+DecimalToBcd8 (
+  IN      UINT8                     Value
+  );
+
+
+/**
+  Converts an 8-bit BCD value to an 8-bit value.
+
+  Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
+  value is returned.
+
+  If Value >= 0xA0, then ASSERT().
+  If (Value & 0x0F) >= 0x0A, then ASSERT().
+
+  @param  Value The 8-bit BCD value to convert to an 8-bit value.
+
+  @return The 8-bit value is returned.
+
+**/
+UINT8
+EFIAPI
+BcdToDecimal8 (
+  IN      UINT8                     Value
+  );
+
+//
+//  File Path Manipulation Functions
+//
+
+/**
+  Removes the last directory or file entry in a path.
+
+  @param[in, out] Path    The pointer to the path to modify.
+
+  @retval FALSE     Nothing was found to remove.
+  @retval TRUE      A directory or file was removed.
+**/
+BOOLEAN
+EFIAPI
+PathRemoveLastItem(
+  IN OUT CHAR16 *Path
+  );
+
+/**
+  Function to clean up paths.
+    - Single periods in the path are removed.
+    - Double periods in the path are removed along with a single parent directory.
+    - Forward slashes L'/' are converted to backward slashes L'\'.
+
+  This will be done inline and the existing buffer may be larger than required
+  upon completion.
+
+  @param[in] Path       The pointer to the string containing the path.
+
+  @return       Returns Path, otherwise returns NULL to indicate that an error has occurred.
+**/
+CHAR16*
+EFIAPI
+PathCleanUpDirectories(
+  IN CHAR16 *Path
+  );
+
+//
+// Linked List Functions and Macros
+//
+
+/**
+  Initializes the head node of a doubly linked list that is declared as a
+  global variable in a module.
+
+  Initializes the forward and backward links of a new linked list. After
+  initializing a linked list with this macro, the other linked list functions
+  may be used to add and remove nodes from the linked list. This macro results
+  in smaller executables by initializing the linked list in the data section,
+  instead if calling the InitializeListHead() function to perform the
+  equivalent operation.
+
+  @param  ListHead  The head note of a list to initialize.
+
+**/
+#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)  {&(ListHead), &(ListHead)}
+
+
+/**
+  Initializes the head node of a doubly linked list, and returns the pointer to
+  the head node of the doubly linked list.
+
+  Initializes the forward and backward links of a new linked list. After
+  initializing a linked list with this function, the other linked list
+  functions may be used to add and remove nodes from the linked list. It is up
+  to the caller of this function to allocate the memory for ListHead.
+
+  If ListHead is NULL, then ASSERT().
+
+  @param  ListHead  A pointer to the head node of a new doubly linked list.
+
+  @return ListHead
+
+**/
+LIST_ENTRY *
+EFIAPI
+InitializeListHead (
+  IN OUT  LIST_ENTRY                *ListHead
+  );
+
+
+/**
+  Adds a node to the beginning of a doubly linked list, and returns the pointer
+  to the head node of the doubly linked list.
+
+  Adds the node Entry at the beginning of the doubly linked list denoted by
+  ListHead, and returns ListHead.
+
+  If ListHead is NULL, then ASSERT().
+  If Entry is NULL, then ASSERT().
+  If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and prior to insertion the number
+  of nodes in ListHead, including the ListHead node, is greater than or
+  equal to PcdMaximumLinkedListLength, then ASSERT().
+
+  @param  ListHead  A pointer to the head node of a doubly linked list.
+  @param  Entry     A pointer to a node that is to be inserted at the beginning
+                    of a doubly linked list.
+
+  @return ListHead
+
+**/
+LIST_ENTRY *
+EFIAPI
+InsertHeadList (
+  IN OUT  LIST_ENTRY                *ListHead,
+  IN OUT  LIST_ENTRY                *Entry
+  );
+
+
+/**
+  Adds a node to the end of a doubly linked list, and returns the pointer to
+  the head node of the doubly linked list.
+
+  Adds the node Entry to the end of the doubly linked list denoted by ListHead,
+  and returns ListHead.
+
+  If ListHead is NULL, then ASSERT().
+  If Entry is NULL, then ASSERT().
+  If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or 
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and prior to insertion the number
+  of nodes in ListHead, including the ListHead node, is greater than or
+  equal to PcdMaximumLinkedListLength, then ASSERT().
+
+  @param  ListHead  A pointer to the head node of a doubly linked list.
+  @param  Entry     A pointer to a node that is to be added at the end of the
+                    doubly linked list.
+
+  @return ListHead
+
+**/
+LIST_ENTRY *
+EFIAPI
+InsertTailList (
+  IN OUT  LIST_ENTRY                *ListHead,
+  IN OUT  LIST_ENTRY                *Entry
+  );
+
+
+/**
+  Retrieves the first node of a doubly linked list.
+
+  Returns the first node of a doubly linked list.  List must have been 
+  initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+  If List is empty, then List is returned.
+
+  If List is NULL, then ASSERT().
+  If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or 
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and the number of nodes
+  in List, including the List node, is greater than or equal to
+  PcdMaximumLinkedListLength, then ASSERT().
+
+  @param  List  A pointer to the head node of a doubly linked list.
+
+  @return The first node of a doubly linked list.
+  @retval List  The list is empty.
+
+**/
+LIST_ENTRY *
+EFIAPI
+GetFirstNode (
+  IN      CONST LIST_ENTRY          *List
+  );
+
+
+/**
+  Retrieves the next node of a doubly linked list.
+
+  Returns the node of a doubly linked list that follows Node.  
+  List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
+  or InitializeListHead().  If List is empty, then List is returned.
+
+  If List is NULL, then ASSERT().
+  If Node is NULL, then ASSERT().
+  If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or 
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and List contains more than
+  PcdMaximumLinkedListLength nodes, then ASSERT().
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
+
+  @param  List  A pointer to the head node of a doubly linked list.
+  @param  Node  A pointer to a node in the doubly linked list.
+
+  @return The pointer to the next node if one exists. Otherwise List is returned.
+
+**/
+LIST_ENTRY *
+EFIAPI
+GetNextNode (
+  IN      CONST LIST_ENTRY          *List,
+  IN      CONST LIST_ENTRY          *Node
+  );
+
+  
+/**
+  Retrieves the previous node of a doubly linked list.
+ 
+  Returns the node of a doubly linked list that precedes Node.  
+  List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
+  or InitializeListHead().  If List is empty, then List is returned.
+ 
+  If List is NULL, then ASSERT().
+  If Node is NULL, then ASSERT().
+  If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or 
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and List contains more than
+  PcdMaximumLinkedListLength nodes, then ASSERT().
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
+ 
+  @param  List  A pointer to the head node of a doubly linked list.
+  @param  Node  A pointer to a node in the doubly linked list.
+ 
+  @return The pointer to the previous node if one exists. Otherwise List is returned.
+ 
+**/
+LIST_ENTRY *
+EFIAPI
+GetPreviousNode (
+  IN      CONST LIST_ENTRY          *List,
+  IN      CONST LIST_ENTRY          *Node
+  );
+
+  
+/**
+  Checks to see if a doubly linked list is empty or not.
+
+  Checks to see if the doubly linked list is empty. If the linked list contains
+  zero nodes, this function returns TRUE. Otherwise, it returns FALSE.
+
+  If ListHead is NULL, then ASSERT().
+  If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or 
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and the number of nodes
+  in List, including the List node, is greater than or equal to
+  PcdMaximumLinkedListLength, then ASSERT().
+
+  @param  ListHead  A pointer to the head node of a doubly linked list.
+
+  @retval TRUE  The linked list is empty.
+  @retval FALSE The linked list is not empty.
+
+**/
+BOOLEAN
+EFIAPI
+IsListEmpty (
+  IN      CONST LIST_ENTRY          *ListHead
+  );
+
+
+/**
+  Determines if a node in a doubly linked list is the head node of a the same
+  doubly linked list.  This function is typically used to terminate a loop that
+  traverses all the nodes in a doubly linked list starting with the head node.
+
+  Returns TRUE if Node is equal to List.  Returns FALSE if Node is one of the
+  nodes in the doubly linked list specified by List.  List must have been
+  initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+
+  If List is NULL, then ASSERT().
+  If Node is NULL, then ASSERT().
+  If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(), 
+  then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and the number of nodes
+  in List, including the List node, is greater than or equal to
+  PcdMaximumLinkedListLength, then ASSERT().
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List the and Node is not equal 
+  to List, then ASSERT().
+
+  @param  List  A pointer to the head node of a doubly linked list.
+  @param  Node  A pointer to a node in the doubly linked list.
+
+  @retval TRUE  Node is the head of the doubly-linked list pointed by List.
+  @retval FALSE Node is not the head of the doubly-linked list pointed by List.
+
+**/
+BOOLEAN
+EFIAPI
+IsNull (
+  IN      CONST LIST_ENTRY          *List,
+  IN      CONST LIST_ENTRY          *Node
+  );
+
+
+/**
+  Determines if a node the last node in a doubly linked list.
+
+  Returns TRUE if Node is the last node in the doubly linked list specified by
+  List. Otherwise, FALSE is returned. List must have been initialized with
+  INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
+
+  If List is NULL, then ASSERT().
+  If Node is NULL, then ASSERT().
+  If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
+  InitializeListHead(), then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and the number of nodes
+  in List, including the List node, is greater than or equal to
+  PcdMaximumLinkedListLength, then ASSERT().
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
+
+  @param  List  A pointer to the head node of a doubly linked list.
+  @param  Node  A pointer to a node in the doubly linked list.
+
+  @retval TRUE  Node is the last node in the linked list.
+  @retval FALSE Node is not the last node in the linked list.
+
+**/
+BOOLEAN
+EFIAPI
+IsNodeAtEnd (
+  IN      CONST LIST_ENTRY          *List,
+  IN      CONST LIST_ENTRY          *Node
+  );
+
+
+/**
+  Swaps the location of two nodes in a doubly linked list, and returns the
+  first node after the swap.
+
+  If FirstEntry is identical to SecondEntry, then SecondEntry is returned.
+  Otherwise, the location of the FirstEntry node is swapped with the location
+  of the SecondEntry node in a doubly linked list. SecondEntry must be in the
+  same double linked list as FirstEntry and that double linked list must have
+  been initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). 
+  SecondEntry is returned after the nodes are swapped.
+
+  If FirstEntry is NULL, then ASSERT().
+  If SecondEntry is NULL, then ASSERT().
+  If PcdVerifyNodeInList is TRUE and SecondEntry and FirstEntry are not in the 
+  same linked list, then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
+  linked list containing the FirstEntry and SecondEntry nodes, including
+  the FirstEntry and SecondEntry nodes, is greater than or equal to
+  PcdMaximumLinkedListLength, then ASSERT().
+
+  @param  FirstEntry  A pointer to a node in a linked list.
+  @param  SecondEntry A pointer to another node in the same linked list.
+  
+  @return SecondEntry.
+
+**/
+LIST_ENTRY *
+EFIAPI
+SwapListEntries (
+  IN OUT  LIST_ENTRY                *FirstEntry,
+  IN OUT  LIST_ENTRY                *SecondEntry
+  );
+
+
+/**
+  Removes a node from a doubly linked list, and returns the node that follows
+  the removed node.
+
+  Removes the node Entry from a doubly linked list. It is up to the caller of
+  this function to release the memory used by this node if that is required. On
+  exit, the node following Entry in the doubly linked list is returned. If
+  Entry is the only node in the linked list, then the head node of the linked
+  list is returned.
+
+  If Entry is NULL, then ASSERT().
+  If Entry is the head node of an empty list, then ASSERT().
+  If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
+  linked list containing Entry, including the Entry node, is greater than
+  or equal to PcdMaximumLinkedListLength, then ASSERT().
+
+  @param  Entry A pointer to a node in a linked list.
+
+  @return Entry.
+
+**/
+LIST_ENTRY *
+EFIAPI
+RemoveEntryList (
+  IN      CONST LIST_ENTRY          *Entry
+  );
+
+//
+// Math Services
+//
+
+/**
+  Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled
+  with zeros. The shifted value is returned.
+
+  This function shifts the 64-bit value Operand to the left by Count bits. The
+  low Count bits are set to zero. The shifted value is returned.
+
+  If Count is greater than 63, then ASSERT().
+
+  @param  Operand The 64-bit operand to shift left.
+  @param  Count   The number of bits to shift left.
+
+  @return Operand << Count.
+
+**/
+UINT64
+EFIAPI
+LShiftU64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Shifts a 64-bit integer right between 0 and 63 bits. This high bits are
+  filled with zeros. The shifted value is returned.
+
+  This function shifts the 64-bit value Operand to the right by Count bits. The
+  high Count bits are set to zero. The shifted value is returned.
+
+  If Count is greater than 63, then ASSERT().
+
+  @param  Operand The 64-bit operand to shift right.
+  @param  Count   The number of bits to shift right.
+
+  @return Operand >> Count
+
+**/
+UINT64
+EFIAPI
+RShiftU64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Shifts a 64-bit integer right between 0 and 63 bits. The high bits are filled
+  with original integer's bit 63. The shifted value is returned.
+
+  This function shifts the 64-bit value Operand to the right by Count bits. The
+  high Count bits are set to bit 63 of Operand.  The shifted value is returned.
+
+  If Count is greater than 63, then ASSERT().
+
+  @param  Operand The 64-bit operand to shift right.
+  @param  Count   The number of bits to shift right.
+
+  @return Operand >> Count
+
+**/
+UINT64
+EFIAPI
+ARShiftU64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Rotates a 32-bit integer left between 0 and 31 bits, filling the low bits
+  with the high bits that were rotated.
+
+  This function rotates the 32-bit value Operand to the left by Count bits. The
+  low Count bits are fill with the high Count bits of Operand. The rotated
+  value is returned.
+
+  If Count is greater than 31, then ASSERT().
+
+  @param  Operand The 32-bit operand to rotate left.
+  @param  Count   The number of bits to rotate left.
+
+  @return Operand << Count
+
+**/
+UINT32
+EFIAPI
+LRotU32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Rotates a 32-bit integer right between 0 and 31 bits, filling the high bits
+  with the low bits that were rotated.
+
+  This function rotates the 32-bit value Operand to the right by Count bits.
+  The high Count bits are fill with the low Count bits of Operand. The rotated
+  value is returned.
+
+  If Count is greater than 31, then ASSERT().
+
+  @param  Operand The 32-bit operand to rotate right.
+  @param  Count   The number of bits to rotate right.
+
+  @return Operand >> Count
+
+**/
+UINT32
+EFIAPI
+RRotU32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Rotates a 64-bit integer left between 0 and 63 bits, filling the low bits
+  with the high bits that were rotated.
+
+  This function rotates the 64-bit value Operand to the left by Count bits. The
+  low Count bits are fill with the high Count bits of Operand. The rotated
+  value is returned.
+
+  If Count is greater than 63, then ASSERT().
+
+  @param  Operand The 64-bit operand to rotate left.
+  @param  Count   The number of bits to rotate left.
+
+  @return Operand << Count
+
+**/
+UINT64
+EFIAPI
+LRotU64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Rotates a 64-bit integer right between 0 and 63 bits, filling the high bits
+  with the high low bits that were rotated.
+
+  This function rotates the 64-bit value Operand to the right by Count bits.
+  The high Count bits are fill with the low Count bits of Operand. The rotated
+  value is returned.
+
+  If Count is greater than 63, then ASSERT().
+
+  @param  Operand The 64-bit operand to rotate right.
+  @param  Count   The number of bits to rotate right.
+
+  @return Operand >> Count
+
+**/
+UINT64
+EFIAPI
+RRotU64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     Count
+  );
+
+
+/**
+  Returns the bit position of the lowest bit set in a 32-bit value.
+
+  This function computes the bit position of the lowest bit set in the 32-bit
+  value specified by Operand. If Operand is zero, then -1 is returned.
+  Otherwise, a value between 0 and 31 is returned.
+
+  @param  Operand The 32-bit operand to evaluate.
+
+  @retval 0..31  The lowest bit set in Operand was found.
+  @retval -1    Operand is zero.
+
+**/
+INTN
+EFIAPI
+LowBitSet32 (
+  IN      UINT32                    Operand
+  );
+
+
+/**
+  Returns the bit position of the lowest bit set in a 64-bit value.
+
+  This function computes the bit position of the lowest bit set in the 64-bit
+  value specified by Operand. If Operand is zero, then -1 is returned.
+  Otherwise, a value between 0 and 63 is returned.
+
+  @param  Operand The 64-bit operand to evaluate.
+
+  @retval 0..63  The lowest bit set in Operand was found.
+  @retval -1    Operand is zero.
+
+
+**/
+INTN
+EFIAPI
+LowBitSet64 (
+  IN      UINT64                    Operand
+  );
+
+
+/**
+  Returns the bit position of the highest bit set in a 32-bit value. Equivalent
+  to log2(x).
+
+  This function computes the bit position of the highest bit set in the 32-bit
+  value specified by Operand. If Operand is zero, then -1 is returned.
+  Otherwise, a value between 0 and 31 is returned.
+
+  @param  Operand The 32-bit operand to evaluate.
+
+  @retval 0..31  Position of the highest bit set in Operand if found.
+  @retval -1    Operand is zero.
+
+**/
+INTN
+EFIAPI
+HighBitSet32 (
+  IN      UINT32                    Operand
+  );
+
+
+/**
+  Returns the bit position of the highest bit set in a 64-bit value. Equivalent
+  to log2(x).
+
+  This function computes the bit position of the highest bit set in the 64-bit
+  value specified by Operand. If Operand is zero, then -1 is returned.
+  Otherwise, a value between 0 and 63 is returned.
+
+  @param  Operand The 64-bit operand to evaluate.
+
+  @retval 0..63   Position of the highest bit set in Operand if found.
+  @retval -1     Operand is zero.
+
+**/
+INTN
+EFIAPI
+HighBitSet64 (
+  IN      UINT64                    Operand
+  );
+
+
+/**
+  Returns the value of the highest bit set in a 32-bit value. Equivalent to
+  1 << log2(x).
+
+  This function computes the value of the highest bit set in the 32-bit value
+  specified by Operand. If Operand is zero, then zero is returned.
+
+  @param  Operand The 32-bit operand to evaluate.
+
+  @return 1 << HighBitSet32(Operand)
+  @retval 0 Operand is zero.
+
+**/
+UINT32
+EFIAPI
+GetPowerOfTwo32 (
+  IN      UINT32                    Operand
+  );
+
+
+/**
+  Returns the value of the highest bit set in a 64-bit value. Equivalent to
+  1 << log2(x).
+
+  This function computes the value of the highest bit set in the 64-bit value
+  specified by Operand. If Operand is zero, then zero is returned.
+
+  @param  Operand The 64-bit operand to evaluate.
+
+  @return 1 << HighBitSet64(Operand)
+  @retval 0 Operand is zero.
+
+**/
+UINT64
+EFIAPI
+GetPowerOfTwo64 (
+  IN      UINT64                    Operand
+  );
+
+
+/**
+  Switches the endianness of a 16-bit integer.
+
+  This function swaps the bytes in a 16-bit unsigned value to switch the value
+  from little endian to big endian or vice versa. The byte swapped value is
+  returned.
+
+  @param  Value A 16-bit unsigned value.
+
+  @return The byte swapped Value.
+
+**/
+UINT16
+EFIAPI
+SwapBytes16 (
+  IN      UINT16                    Value
+  );
+
+
+/**
+  Switches the endianness of a 32-bit integer.
+
+  This function swaps the bytes in a 32-bit unsigned value to switch the value
+  from little endian to big endian or vice versa. The byte swapped value is
+  returned.
+
+  @param  Value A 32-bit unsigned value.
+
+  @return The byte swapped Value.
+
+**/
+UINT32
+EFIAPI
+SwapBytes32 (
+  IN      UINT32                    Value
+  );
+
+
+/**
+  Switches the endianness of a 64-bit integer.
+
+  This function swaps the bytes in a 64-bit unsigned value to switch the value
+  from little endian to big endian or vice versa. The byte swapped value is
+  returned.
+
+  @param  Value A 64-bit unsigned value.
+
+  @return The byte swapped Value.
+
+**/
+UINT64
+EFIAPI
+SwapBytes64 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Multiples a 64-bit unsigned integer by a 32-bit unsigned integer and
+  generates a 64-bit unsigned result.
+
+  This function multiples the 64-bit unsigned value Multiplicand by the 32-bit
+  unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
+  bit unsigned result is returned.
+
+  @param  Multiplicand  A 64-bit unsigned value.
+  @param  Multiplier    A 32-bit unsigned value.
+
+  @return Multiplicand * Multiplier
+
+**/
+UINT64
+EFIAPI
+MultU64x32 (
+  IN      UINT64                    Multiplicand,
+  IN      UINT32                    Multiplier
+  );
+
+
+/**
+  Multiples a 64-bit unsigned integer by a 64-bit unsigned integer and
+  generates a 64-bit unsigned result.
+
+  This function multiples the 64-bit unsigned value Multiplicand by the 64-bit
+  unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
+  bit unsigned result is returned.
+
+  @param  Multiplicand  A 64-bit unsigned value.
+  @param  Multiplier    A 64-bit unsigned value.
+
+  @return Multiplicand * Multiplier.
+
+**/
+UINT64
+EFIAPI
+MultU64x64 (
+  IN      UINT64                    Multiplicand,
+  IN      UINT64                    Multiplier
+  );
+
+
+/**
+  Multiples a 64-bit signed integer by a 64-bit signed integer and generates a
+  64-bit signed result.
+
+  This function multiples the 64-bit signed value Multiplicand by the 64-bit
+  signed value Multiplier and generates a 64-bit signed result. This 64-bit
+  signed result is returned.
+
+  @param  Multiplicand  A 64-bit signed value.
+  @param  Multiplier    A 64-bit signed value.
+
+  @return Multiplicand * Multiplier
+
+**/
+INT64
+EFIAPI
+MultS64x64 (
+  IN      INT64                     Multiplicand,
+  IN      INT64                     Multiplier
+  );
+
+
+/**
+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
+  a 64-bit unsigned result.
+
+  This function divides the 64-bit unsigned value Dividend by the 32-bit
+  unsigned value Divisor and generates a 64-bit unsigned quotient. This
+  function returns the 64-bit unsigned quotient.
+
+  If Divisor is 0, then ASSERT().
+
+  @param  Dividend  A 64-bit unsigned value.
+  @param  Divisor   A 32-bit unsigned value.
+
+  @return Dividend / Divisor.
+
+**/
+UINT64
+EFIAPI
+DivU64x32 (
+  IN      UINT64                    Dividend,
+  IN      UINT32                    Divisor
+  );
+
+
+/**
+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
+  a 32-bit unsigned remainder.
+
+  This function divides the 64-bit unsigned value Dividend by the 32-bit
+  unsigned value Divisor and generates a 32-bit remainder. This function
+  returns the 32-bit unsigned remainder.
+
+  If Divisor is 0, then ASSERT().
+
+  @param  Dividend  A 64-bit unsigned value.
+  @param  Divisor   A 32-bit unsigned value.
+
+  @return Dividend % Divisor.
+
+**/
+UINT32
+EFIAPI
+ModU64x32 (
+  IN      UINT64                    Dividend,
+  IN      UINT32                    Divisor
+  );
+
+
+/**
+  Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
+  a 64-bit unsigned result and an optional 32-bit unsigned remainder.
+
+  This function divides the 64-bit unsigned value Dividend by the 32-bit
+  unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
+  is not NULL, then the 32-bit unsigned remainder is returned in Remainder.
+  This function returns the 64-bit unsigned quotient.
+
+  If Divisor is 0, then ASSERT().
+
+  @param  Dividend  A 64-bit unsigned value.
+  @param  Divisor   A 32-bit unsigned value.
+  @param  Remainder A pointer to a 32-bit unsigned value. This parameter is
+                    optional and may be NULL.
+
+  @return Dividend / Divisor.
+
+**/
+UINT64
+EFIAPI
+DivU64x32Remainder (
+  IN      UINT64                    Dividend,
+  IN      UINT32                    Divisor,
+  OUT     UINT32                    *Remainder  OPTIONAL
+  );
+
+
+/**
+  Divides a 64-bit unsigned integer by a 64-bit unsigned integer and generates
+  a 64-bit unsigned result and an optional 64-bit unsigned remainder.
+
+  This function divides the 64-bit unsigned value Dividend by the 64-bit
+  unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
+  is not NULL, then the 64-bit unsigned remainder is returned in Remainder.
+  This function returns the 64-bit unsigned quotient.
+
+  If Divisor is 0, then ASSERT().
+
+  @param  Dividend  A 64-bit unsigned value.
+  @param  Divisor   A 64-bit unsigned value.
+  @param  Remainder A pointer to a 64-bit unsigned value. This parameter is
+                    optional and may be NULL.
+
+  @return Dividend / Divisor.
+
+**/
+UINT64
+EFIAPI
+DivU64x64Remainder (
+  IN      UINT64                    Dividend,
+  IN      UINT64                    Divisor,
+  OUT     UINT64                    *Remainder  OPTIONAL
+  );
+
+
+/**
+  Divides a 64-bit signed integer by a 64-bit signed integer and generates a
+  64-bit signed result and a optional 64-bit signed remainder.
+
+  This function divides the 64-bit signed value Dividend by the 64-bit signed
+  value Divisor and generates a 64-bit signed quotient. If Remainder is not
+  NULL, then the 64-bit signed remainder is returned in Remainder. This
+  function returns the 64-bit signed quotient.
+
+  It is the caller's responsibility to not call this function with a Divisor of 0.
+  If Divisor is 0, then the quotient and remainder should be assumed to be 
+  the largest negative integer.
+
+  If Divisor is 0, then ASSERT().
+
+  @param  Dividend  A 64-bit signed value.
+  @param  Divisor   A 64-bit signed value.
+  @param  Remainder A pointer to a 64-bit signed value. This parameter is
+                    optional and may be NULL.
+
+  @return Dividend / Divisor.
+
+**/
+INT64
+EFIAPI
+DivS64x64Remainder (
+  IN      INT64                     Dividend,
+  IN      INT64                     Divisor,
+  OUT     INT64                     *Remainder  OPTIONAL
+  );
+
+
+/**
+  Reads a 16-bit value from memory that may be unaligned.
+
+  This function returns the 16-bit value pointed to by Buffer. The function
+  guarantees that the read operation does not produce an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 16-bit value that may be unaligned.
+
+  @return The 16-bit value read from Buffer.
+
+**/
+UINT16
+EFIAPI
+ReadUnaligned16 (
+  IN CONST UINT16              *Buffer
+  );
+
+
+/**
+  Writes a 16-bit value to memory that may be unaligned.
+
+  This function writes the 16-bit value specified by Value to Buffer. Value is
+  returned. The function guarantees that the write operation does not produce
+  an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 16-bit value that may be unaligned.
+  @param  Value   16-bit value to write to Buffer.
+
+  @return The 16-bit value to write to Buffer.
+
+**/
+UINT16
+EFIAPI
+WriteUnaligned16 (
+  OUT UINT16                    *Buffer,
+  IN  UINT16                    Value
+  );
+
+
+/**
+  Reads a 24-bit value from memory that may be unaligned.
+
+  This function returns the 24-bit value pointed to by Buffer. The function
+  guarantees that the read operation does not produce an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 24-bit value that may be unaligned.
+
+  @return The 24-bit value read from Buffer.
+
+**/
+UINT32
+EFIAPI
+ReadUnaligned24 (
+  IN CONST UINT32              *Buffer
+  );
+
+
+/**
+  Writes a 24-bit value to memory that may be unaligned.
+
+  This function writes the 24-bit value specified by Value to Buffer. Value is
+  returned. The function guarantees that the write operation does not produce
+  an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 24-bit value that may be unaligned.
+  @param  Value   24-bit value to write to Buffer.
+
+  @return The 24-bit value to write to Buffer.
+
+**/
+UINT32
+EFIAPI
+WriteUnaligned24 (
+  OUT UINT32                    *Buffer,
+  IN  UINT32                    Value
+  );
+
+
+/**
+  Reads a 32-bit value from memory that may be unaligned.
+
+  This function returns the 32-bit value pointed to by Buffer. The function
+  guarantees that the read operation does not produce an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 32-bit value that may be unaligned.
+
+  @return The 32-bit value read from Buffer.
+
+**/
+UINT32
+EFIAPI
+ReadUnaligned32 (
+  IN CONST UINT32              *Buffer
+  );
+
+
+/**
+  Writes a 32-bit value to memory that may be unaligned.
+
+  This function writes the 32-bit value specified by Value to Buffer. Value is
+  returned. The function guarantees that the write operation does not produce
+  an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 32-bit value that may be unaligned.
+  @param  Value   32-bit value to write to Buffer.
+
+  @return The 32-bit value to write to Buffer.
+
+**/
+UINT32
+EFIAPI
+WriteUnaligned32 (
+  OUT UINT32                    *Buffer,
+  IN  UINT32                    Value
+  );
+
+
+/**
+  Reads a 64-bit value from memory that may be unaligned.
+
+  This function returns the 64-bit value pointed to by Buffer. The function
+  guarantees that the read operation does not produce an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 64-bit value that may be unaligned.
+
+  @return The 64-bit value read from Buffer.
+
+**/
+UINT64
+EFIAPI
+ReadUnaligned64 (
+  IN CONST UINT64              *Buffer
+  );
+
+
+/**
+  Writes a 64-bit value to memory that may be unaligned.
+
+  This function writes the 64-bit value specified by Value to Buffer. Value is
+  returned. The function guarantees that the write operation does not produce
+  an alignment fault.
+
+  If the Buffer is NULL, then ASSERT().
+
+  @param  Buffer  The pointer to a 64-bit value that may be unaligned.
+  @param  Value   64-bit value to write to Buffer.
+
+  @return The 64-bit value to write to Buffer.
+
+**/
+UINT64
+EFIAPI
+WriteUnaligned64 (
+  OUT UINT64                    *Buffer,
+  IN  UINT64                    Value
+  );
+
+
+//
+// Bit Field Functions
+//
+
+/**
+  Returns a bit field from an 8-bit value.
+
+  Returns the bitfield specified by the StartBit and the EndBit from Operand.
+
+  If 8-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+
+  @return The bit field read.
+
+**/
+UINT8
+EFIAPI
+BitFieldRead8 (
+  IN      UINT8                     Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit
+  );
+
+
+/**
+  Writes a bit field to an 8-bit value, and returns the result.
+
+  Writes Value to the bit field specified by the StartBit and the EndBit in
+  Operand. All other bits in Operand are preserved. The new 8-bit value is
+  returned.
+
+  If 8-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  Value     New value of the bit field.
+
+  @return The new 8-bit value.
+
+**/
+UINT8
+EFIAPI
+BitFieldWrite8 (
+  IN      UINT8                     Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT8                     Value
+  );
+
+
+/**
+  Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the
+  result.
+
+  Performs a bitwise OR between the bit field specified by StartBit
+  and EndBit in Operand and the value specified by OrData. All other bits in
+  Operand are preserved. The new 8-bit value is returned.
+
+  If 8-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  OrData    The value to OR with the read value from the value
+
+  @return The new 8-bit value.
+
+**/
+UINT8
+EFIAPI
+BitFieldOr8 (
+  IN      UINT8                     Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT8                     OrData
+  );
+
+
+/**
+  Reads a bit field from an 8-bit value, performs a bitwise AND, and returns
+  the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData. All other bits in Operand are
+  preserved. The new 8-bit value is returned.
+
+  If 8-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  AndData   The value to AND with the read value from the value.
+
+  @return The new 8-bit value.
+
+**/
+UINT8
+EFIAPI
+BitFieldAnd8 (
+  IN      UINT8                     Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT8                     AndData
+  );
+
+
+/**
+  Reads a bit field from an 8-bit value, performs a bitwise AND followed by a
+  bitwise OR, and returns the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData, followed by a bitwise 
+  OR with value specified by OrData. All other bits in Operand are
+  preserved. The new 8-bit value is returned.
+
+  If 8-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  AndData   The value to AND with the read value from the value.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The new 8-bit value.
+
+**/
+UINT8
+EFIAPI
+BitFieldAndThenOr8 (
+  IN      UINT8                     Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT8                     AndData,
+  IN      UINT8                     OrData
+  );
+
+
+/**
+  Returns a bit field from a 16-bit value.
+
+  Returns the bitfield specified by the StartBit and the EndBit from Operand.
+
+  If 16-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+
+  @return The bit field read.
+
+**/
+UINT16
+EFIAPI
+BitFieldRead16 (
+  IN      UINT16                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit
+  );
+
+
+/**
+  Writes a bit field to a 16-bit value, and returns the result.
+
+  Writes Value to the bit field specified by the StartBit and the EndBit in
+  Operand. All other bits in Operand are preserved. The new 16-bit value is
+  returned.
+
+  If 16-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  Value     New value of the bit field.
+
+  @return The new 16-bit value.
+
+**/
+UINT16
+EFIAPI
+BitFieldWrite16 (
+  IN      UINT16                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT16                    Value
+  );
+
+
+/**
+  Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the
+  result.
+
+  Performs a bitwise OR between the bit field specified by StartBit
+  and EndBit in Operand and the value specified by OrData. All other bits in
+  Operand are preserved. The new 16-bit value is returned.
+
+  If 16-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  OrData    The value to OR with the read value from the value
+
+  @return The new 16-bit value.
+
+**/
+UINT16
+EFIAPI
+BitFieldOr16 (
+  IN      UINT16                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT16                    OrData
+  );
+
+
+/**
+  Reads a bit field from a 16-bit value, performs a bitwise AND, and returns
+  the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData. All other bits in Operand are
+  preserved. The new 16-bit value is returned.
+
+  If 16-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  AndData   The value to AND with the read value from the value
+
+  @return The new 16-bit value.
+
+**/
+UINT16
+EFIAPI
+BitFieldAnd16 (
+  IN      UINT16                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT16                    AndData
+  );
+
+
+/**
+  Reads a bit field from a 16-bit value, performs a bitwise AND followed by a
+  bitwise OR, and returns the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData, followed by a bitwise 
+  OR with value specified by OrData. All other bits in Operand are
+  preserved. The new 16-bit value is returned.
+
+  If 16-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  AndData   The value to AND with the read value from the value.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The new 16-bit value.
+
+**/
+UINT16
+EFIAPI
+BitFieldAndThenOr16 (
+  IN      UINT16                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT16                    AndData,
+  IN      UINT16                    OrData
+  );
+
+
+/**
+  Returns a bit field from a 32-bit value.
+
+  Returns the bitfield specified by the StartBit and the EndBit from Operand.
+
+  If 32-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+
+  @return The bit field read.
+
+**/
+UINT32
+EFIAPI
+BitFieldRead32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit
+  );
+
+
+/**
+  Writes a bit field to a 32-bit value, and returns the result.
+
+  Writes Value to the bit field specified by the StartBit and the EndBit in
+  Operand. All other bits in Operand are preserved. The new 32-bit value is
+  returned.
+
+  If 32-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  Value     New value of the bit field.
+
+  @return The new 32-bit value.
+
+**/
+UINT32
+EFIAPI
+BitFieldWrite32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    Value
+  );
+
+
+/**
+  Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the
+  result.
+
+  Performs a bitwise OR between the bit field specified by StartBit
+  and EndBit in Operand and the value specified by OrData. All other bits in
+  Operand are preserved. The new 32-bit value is returned.
+
+  If 32-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  OrData    The value to OR with the read value from the value.
+
+  @return The new 32-bit value.
+
+**/
+UINT32
+EFIAPI
+BitFieldOr32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    OrData
+  );
+
+
+/**
+  Reads a bit field from a 32-bit value, performs a bitwise AND, and returns
+  the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData. All other bits in Operand are
+  preserved. The new 32-bit value is returned.
+
+  If 32-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the read value from the value
+
+  @return The new 32-bit value.
+
+**/
+UINT32
+EFIAPI
+BitFieldAnd32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    AndData
+  );
+
+
+/**
+  Reads a bit field from a 32-bit value, performs a bitwise AND followed by a
+  bitwise OR, and returns the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData, followed by a bitwise 
+  OR with value specified by OrData. All other bits in Operand are
+  preserved. The new 32-bit value is returned.
+
+  If 32-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the read value from the value.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The new 32-bit value.
+
+**/
+UINT32
+EFIAPI
+BitFieldAndThenOr32 (
+  IN      UINT32                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    AndData,
+  IN      UINT32                    OrData
+  );
+
+
+/**
+  Returns a bit field from a 64-bit value.
+
+  Returns the bitfield specified by the StartBit and the EndBit from Operand.
+
+  If 64-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+
+  @return The bit field read.
+
+**/
+UINT64
+EFIAPI
+BitFieldRead64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit
+  );
+
+
+/**
+  Writes a bit field to a 64-bit value, and returns the result.
+
+  Writes Value to the bit field specified by the StartBit and the EndBit in
+  Operand. All other bits in Operand are preserved. The new 64-bit value is
+  returned.
+
+  If 64-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  Value     New value of the bit field.
+
+  @return The new 64-bit value.
+
+**/
+UINT64
+EFIAPI
+BitFieldWrite64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the
+  result.
+
+  Performs a bitwise OR between the bit field specified by StartBit
+  and EndBit in Operand and the value specified by OrData. All other bits in
+  Operand are preserved. The new 64-bit value is returned.
+
+  If 64-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  OrData    The value to OR with the read value from the value
+
+  @return The new 64-bit value.
+
+**/
+UINT64
+EFIAPI
+BitFieldOr64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    OrData
+  );
+
+
+/**
+  Reads a bit field from a 64-bit value, performs a bitwise AND, and returns
+  the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData. All other bits in Operand are
+  preserved. The new 64-bit value is returned.
+
+  If 64-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  AndData   The value to AND with the read value from the value
+
+  @return The new 64-bit value.
+
+**/
+UINT64
+EFIAPI
+BitFieldAnd64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    AndData
+  );
+
+
+/**
+  Reads a bit field from a 64-bit value, performs a bitwise AND followed by a
+  bitwise OR, and returns the result.
+
+  Performs a bitwise AND between the bit field specified by StartBit and EndBit
+  in Operand and the value specified by AndData, followed by a bitwise 
+  OR with value specified by OrData. All other bits in Operand are
+  preserved. The new 64-bit value is returned.
+
+  If 64-bit operations are not supported, then ASSERT().
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Operand   Operand on which to perform the bitfield operation.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  AndData   The value to AND with the read value from the value.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The new 64-bit value.
+
+**/
+UINT64
+EFIAPI
+BitFieldAndThenOr64 (
+  IN      UINT64                    Operand,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    AndData,
+  IN      UINT64                    OrData
+  );
+
+//
+// Base Library Checksum Functions
+//
+
+/**
+  Returns the sum of all elements in a buffer in unit of UINT8.
+  During calculation, the carry bits are dropped.
+
+  This function calculates the sum of all elements in a buffer
+  in unit of UINT8. The carry bits in result of addition are dropped.
+  The result is returned as UINT8. If Length is Zero, then Zero is
+  returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the sum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Sum         The sum of Buffer with carry bits dropped during additions.
+
+**/
+UINT8
+EFIAPI
+CalculateSum8 (
+  IN      CONST UINT8              *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the two's complement checksum of all elements in a buffer
+  of 8-bit values.
+
+  This function first calculates the sum of the 8-bit values in the
+  buffer specified by Buffer and Length.  The carry bits in the result
+  of addition are dropped. Then, the two's complement of the sum is
+  returned.  If Length is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the checksum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Checksum    The two's complement checksum of Buffer.
+
+**/
+UINT8
+EFIAPI
+CalculateCheckSum8 (
+  IN      CONST UINT8              *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the sum of all elements in a buffer of 16-bit values.  During
+  calculation, the carry bits are dropped.
+
+  This function calculates the sum of the 16-bit values in the buffer
+  specified by Buffer and Length. The carry bits in result of addition are dropped.
+  The 16-bit result is returned.  If Length is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the sum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Sum         The sum of Buffer with carry bits dropped during additions.
+
+**/
+UINT16
+EFIAPI
+CalculateSum16 (
+  IN      CONST UINT16             *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the two's complement checksum of all elements in a buffer of
+  16-bit values.
+
+  This function first calculates the sum of the 16-bit values in the buffer
+  specified by Buffer and Length.  The carry bits in the result of addition
+  are dropped. Then, the two's complement of the sum is returned.  If Length
+  is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the checksum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Checksum    The two's complement checksum of Buffer.
+
+**/
+UINT16
+EFIAPI
+CalculateCheckSum16 (
+  IN      CONST UINT16             *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the sum of all elements in a buffer of 32-bit values. During
+  calculation, the carry bits are dropped.
+
+  This function calculates the sum of the 32-bit values in the buffer
+  specified by Buffer and Length. The carry bits in result of addition are dropped.
+  The 32-bit result is returned. If Length is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the sum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Sum         The sum of Buffer with carry bits dropped during additions.
+
+**/
+UINT32
+EFIAPI
+CalculateSum32 (
+  IN      CONST UINT32             *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the two's complement checksum of all elements in a buffer of
+  32-bit values.
+
+  This function first calculates the sum of the 32-bit values in the buffer
+  specified by Buffer and Length.  The carry bits in the result of addition
+  are dropped. Then, the two's complement of the sum is returned.  If Length
+  is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the checksum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Checksum    The two's complement checksum of Buffer.
+
+**/
+UINT32
+EFIAPI
+CalculateCheckSum32 (
+  IN      CONST UINT32             *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the sum of all elements in a buffer of 64-bit values.  During
+  calculation, the carry bits are dropped.
+
+  This function calculates the sum of the 64-bit values in the buffer
+  specified by Buffer and Length. The carry bits in result of addition are dropped.
+  The 64-bit result is returned.  If Length is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the sum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Sum         The sum of Buffer with carry bits dropped during additions.
+
+**/
+UINT64
+EFIAPI
+CalculateSum64 (
+  IN      CONST UINT64             *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Returns the two's complement checksum of all elements in a buffer of
+  64-bit values.
+
+  This function first calculates the sum of the 64-bit values in the buffer
+  specified by Buffer and Length.  The carry bits in the result of addition
+  are dropped. Then, the two's complement of the sum is returned.  If Length
+  is 0, then 0 is returned.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to carry out the checksum operation.
+  @param  Length      The size, in bytes, of Buffer.
+
+  @return Checksum    The two's complement checksum of Buffer.
+
+**/
+UINT64
+EFIAPI
+CalculateCheckSum64 (
+  IN      CONST UINT64             *Buffer,
+  IN      UINTN                     Length
+  );
+
+
+//
+// Base Library CPU Functions
+//
+
+/**
+  Function entry point used when a stack switch is requested with SwitchStack()
+
+  @param  Context1        Context1 parameter passed into SwitchStack().
+  @param  Context2        Context2 parameter passed into SwitchStack().
+
+**/
+typedef
+VOID
+(EFIAPI *SWITCH_STACK_ENTRY_POINT)(
+  IN      VOID                      *Context1,  OPTIONAL
+  IN      VOID                      *Context2   OPTIONAL
+  );
+
+
+/**
+  Used to serialize load and store operations.
+
+  All loads and stores that proceed calls to this function are guaranteed to be
+  globally visible when this function returns.
+
+**/
+VOID
+EFIAPI
+MemoryFence (
+  VOID
+  );
+
+
+/**
+  Saves the current CPU context that can be restored with a call to LongJump()
+  and returns 0.
+
+  Saves the current CPU context in the buffer specified by JumpBuffer and
+  returns 0. The initial call to SetJump() must always return 0. Subsequent
+  calls to LongJump() cause a non-zero value to be returned by SetJump().
+
+  If JumpBuffer is NULL, then ASSERT().
+  For Itanium processors, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().
+  
+  NOTE: The structure BASE_LIBRARY_JUMP_BUFFER is CPU architecture specific.
+  The same structure must never be used for more than one CPU architecture context.
+  For example, a BASE_LIBRARY_JUMP_BUFFER allocated by an IA-32 module must never be used from an x64 module. 
+  SetJump()/LongJump() is not currently supported for the EBC processor type.   
+
+  @param  JumpBuffer  A pointer to CPU context buffer.
+
+  @retval 0 Indicates a return from SetJump().
+
+**/
+UINTN
+EFIAPI
+SetJump (
+  OUT     BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer
+  );
+
+
+/**
+  Restores the CPU context that was saved with SetJump().
+
+  Restores the CPU context from the buffer specified by JumpBuffer. This
+  function never returns to the caller. Instead is resumes execution based on
+  the state of JumpBuffer.
+
+  If JumpBuffer is NULL, then ASSERT().
+  For Itanium processors, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().
+  If Value is 0, then ASSERT().
+
+  @param  JumpBuffer  A pointer to CPU context buffer.
+  @param  Value       The value to return when the SetJump() context is
+                      restored and must be non-zero.
+
+**/
+VOID
+EFIAPI
+LongJump (
+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,
+  IN      UINTN                     Value
+  );
+
+
+/**
+  Enables CPU interrupts.
+
+**/
+VOID
+EFIAPI
+EnableInterrupts (
+  VOID
+  );
+
+
+/**
+  Disables CPU interrupts.
+
+**/
+VOID
+EFIAPI
+DisableInterrupts (
+  VOID
+  );
+
+
+/**
+  Disables CPU interrupts and returns the interrupt state prior to the disable
+  operation.
+
+  @retval TRUE  CPU interrupts were enabled on entry to this call.
+  @retval FALSE CPU interrupts were disabled on entry to this call.
+
+**/
+BOOLEAN
+EFIAPI
+SaveAndDisableInterrupts (
+  VOID
+  );
+
+
+/**
+  Enables CPU interrupts for the smallest window required to capture any
+  pending interrupts.
+
+**/
+VOID
+EFIAPI
+EnableDisableInterrupts (
+  VOID
+  );
+
+
+/**
+  Retrieves the current CPU interrupt state.
+
+  Returns TRUE if interrupts are currently enabled. Otherwise
+  returns FALSE.
+
+  @retval TRUE  CPU interrupts are enabled.
+  @retval FALSE CPU interrupts are disabled.
+
+**/
+BOOLEAN
+EFIAPI
+GetInterruptState (
+  VOID
+  );
+
+
+/**
+  Set the current CPU interrupt state.
+
+  Sets the current CPU interrupt state to the state specified by
+  InterruptState. If InterruptState is TRUE, then interrupts are enabled. If
+  InterruptState is FALSE, then interrupts are disabled. InterruptState is
+  returned.
+
+  @param  InterruptState  TRUE if interrupts should enabled. FALSE if
+                          interrupts should be disabled.
+
+  @return InterruptState
+
+**/
+BOOLEAN
+EFIAPI
+SetInterruptState (
+  IN      BOOLEAN                   InterruptState
+  );
+
+
+/**
+  Requests CPU to pause for a short period of time.
+
+  Requests CPU to pause for a short period of time. Typically used in MP
+  systems to prevent memory starvation while waiting for a spin lock.
+
+**/
+VOID
+EFIAPI
+CpuPause (
+  VOID
+  );
+
+
+/**
+  Transfers control to a function starting with a new stack.
+
+  Transfers control to the function specified by EntryPoint using the
+  new stack specified by NewStack and passing in the parameters specified
+  by Context1 and Context2.  Context1 and Context2 are optional and may
+  be NULL.  The function EntryPoint must never return.  This function
+  supports a variable number of arguments following the NewStack parameter.
+  These additional arguments are ignored on IA-32, x64, and EBC architectures.
+  Itanium processors expect one additional parameter of type VOID * that specifies
+  the new backing store pointer.
+
+  If EntryPoint is NULL, then ASSERT().
+  If NewStack is NULL, then ASSERT().
+
+  @param  EntryPoint  A pointer to function to call with the new stack.
+  @param  Context1    A pointer to the context to pass into the EntryPoint
+                      function.
+  @param  Context2    A pointer to the context to pass into the EntryPoint
+                      function.
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint
+                      function.
+  @param  ...         This variable argument list is ignored for IA-32, x64, and 
+                      EBC architectures.  For Itanium processors, this variable 
+                      argument list is expected to contain a single parameter of 
+                      type VOID * that specifies the new backing store pointer.
+
+
+**/
+VOID
+EFIAPI
+SwitchStack (
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
+  IN      VOID                      *Context1,  OPTIONAL
+  IN      VOID                      *Context2,  OPTIONAL
+  IN      VOID                      *NewStack,
+  ...
+  );
+
+
+/**
+  Generates a breakpoint on the CPU.
+
+  Generates a breakpoint on the CPU. The breakpoint must be implemented such
+  that code can resume normal execution after the breakpoint.
+
+**/
+VOID
+EFIAPI
+CpuBreakpoint (
+  VOID
+  );
+
+
+/**
+  Executes an infinite loop.
+
+  Forces the CPU to execute an infinite loop. A debugger may be used to skip
+  past the loop and the code that follows the loop must execute properly. This
+  implies that the infinite loop must not cause the code that follow it to be
+  optimized away.
+
+**/
+VOID
+EFIAPI
+CpuDeadLoop (
+  VOID
+  );
+ 
+#if defined (MDE_CPU_IPF)
+
+/**
+  Flush a range of  cache lines in the cache coherency domain of the calling
+  CPU.
+
+  Flushes the cache lines specified by Address and Length.  If Address is not aligned 
+  on a cache line boundary, then entire cache line containing Address is flushed.  
+  If Address + Length is not aligned on a cache line boundary, then the entire cache 
+  line containing Address + Length - 1 is flushed.  This function may choose to flush 
+  the entire cache if that is more efficient than flushing the specified range.  If 
+  Length is 0, the no cache lines are flushed.  Address is returned.   
+  This function is only available on Itanium processors.
+
+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
+
+  @param  Address The base address of the instruction lines to invalidate. If
+                  the CPU is in a physical addressing mode, then Address is a
+                  physical address. If the CPU is in a virtual addressing mode,
+                  then Address is a virtual address.
+
+  @param  Length  The number of bytes to invalidate from the instruction cache.
+
+  @return Address.
+
+**/
+VOID *
+EFIAPI
+AsmFlushCacheRange (
+  IN      VOID                      *Address,
+  IN      UINTN                     Length
+  );
+
+
+/**
+  Executes an FC instruction.
+  Executes an FC instruction on the cache line specified by Address.
+  The cache line size affected is at least 32-bytes (aligned on a 32-byte boundary).
+  An implementation may flush a larger region.  This function is only available on Itanium processors.
+
+  @param Address    The Address of cache line to be flushed.
+
+  @return The address of FC instruction executed.
+
+**/
+UINT64
+EFIAPI
+AsmFc (
+  IN  UINT64  Address
+  );
+
+
+/**
+  Executes an FC.I instruction.
+  Executes an FC.I instruction on the cache line specified by Address.
+  The cache line size affected is at least 32-bytes (aligned on a 32-byte boundary).
+  An implementation may flush a larger region.  This function is only available on Itanium processors.
+
+  @param Address    The Address of cache line to be flushed.
+
+  @return The address of the FC.I instruction executed.
+
+**/
+UINT64
+EFIAPI
+AsmFci (
+  IN  UINT64  Address
+  );
+
+
+/**
+  Reads the current value of a Processor Identifier Register (CPUID).
+  
+  Reads and returns the current value of Processor Identifier Register specified by Index. 
+  The Index of largest implemented CPUID (One less than the number of implemented CPUID
+  registers) is determined by CPUID [3] bits {7:0}.
+  No parameter checking is performed on Index.  If the Index value is beyond the
+  implemented CPUID register range, a Reserved Register/Field fault may occur.  The caller
+  must either guarantee that Index is valid, or the caller must set up fault handlers to
+  catch the faults.  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Processor Identifier Register index to read.
+
+  @return The current value of Processor Identifier Register specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadCpuid (
+  IN  UINT8   Index
+  );
+
+
+/**
+  Reads the current value of 64-bit Processor Status Register (PSR).
+  This function is only available on Itanium processors.
+
+  @return The current value of PSR.
+
+**/
+UINT64
+EFIAPI
+AsmReadPsr (
+  VOID
+  );
+
+
+/**
+  Writes the current value of 64-bit Processor Status Register (PSR).
+
+  No parameter checking is performed on Value.  All bits of Value corresponding to
+  reserved fields of PSR must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults. This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to PSR.
+
+  @return The 64-bit value written to the PSR.
+
+**/
+UINT64
+EFIAPI
+AsmWritePsr (
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #0 (KR0).
+  
+  Reads and returns the current value of KR0. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR0.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr0 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #1 (KR1).
+
+  Reads and returns the current value of KR1. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR1.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr1 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #2 (KR2).
+
+  Reads and returns the current value of KR2. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR2.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr2 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #3 (KR3).
+
+  Reads and returns the current value of KR3. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR3.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr3 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #4 (KR4).
+
+  Reads and returns the current value of KR4. 
+  This function is only available on Itanium processors.
+  
+  @return The current value of KR4.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr4 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #5 (KR5).
+
+  Reads and returns the current value of KR5. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR5.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr5 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #6 (KR6).
+
+  Reads and returns the current value of KR6. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR6.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr6 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit Kernel Register #7 (KR7).
+
+  Reads and returns the current value of KR7. 
+  This function is only available on Itanium processors.
+
+  @return The current value of KR7.
+
+**/
+UINT64
+EFIAPI
+AsmReadKr7 (
+  VOID
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #0 (KR0).
+  
+  Writes the current value of KR0.  The 64-bit value written to 
+  the KR0 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR0.
+
+  @return The 64-bit value written to the KR0.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr0 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #1 (KR1).
+
+  Writes the current value of KR1.  The 64-bit value written to 
+  the KR1 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR1.
+
+  @return The 64-bit value written to the KR1.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr1 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #2 (KR2).
+
+  Writes the current value of KR2.  The 64-bit value written to 
+  the KR2 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR2.
+
+  @return The 64-bit value written to the KR2.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr2 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #3 (KR3).
+
+  Writes the current value of KR3.  The 64-bit value written to 
+  the KR3 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR3.
+
+  @return The 64-bit value written to the KR3.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr3 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #4 (KR4).
+
+  Writes the current value of KR4.  The 64-bit value written to 
+  the KR4 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR4.
+
+  @return The 64-bit value written to the KR4.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr4 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #5 (KR5).
+
+  Writes the current value of KR5.  The 64-bit value written to 
+  the KR5 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR5.
+
+  @return The 64-bit value written to the KR5.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr5 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #6 (KR6).
+
+  Writes the current value of KR6.  The 64-bit value written to 
+  the KR6 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR6.
+
+  @return The 64-bit value written to the KR6.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr6 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Write the current value of 64-bit Kernel Register #7 (KR7).
+
+  Writes the current value of KR7.  The 64-bit value written to 
+  the KR7 is returned. This function is only available on Itanium processors.
+
+  @param  Value   The 64-bit value to write to KR7.
+
+  @return The 64-bit value written to the KR7.
+
+**/
+UINT64
+EFIAPI
+AsmWriteKr7 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of Interval Timer Counter Register (ITC).
+  
+  Reads and returns the current value of ITC.
+  This function is only available on Itanium processors.
+
+  @return The current value of ITC.
+
+**/
+UINT64
+EFIAPI
+AsmReadItc (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Interval Timer Vector Register (ITV).
+  
+  Reads and returns the current value of ITV. 
+  This function is only available on Itanium processors.
+
+  @return The current value of ITV.
+
+**/
+UINT64
+EFIAPI
+AsmReadItv (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Interval Timer Match Register (ITM).
+  
+  Reads and returns the current value of ITM.
+  This function is only available on Itanium processors.
+
+  @return The current value of ITM.
+**/
+UINT64
+EFIAPI
+AsmReadItm (
+  VOID
+  );
+
+
+/**
+  Writes the current value of 64-bit Interval Timer Counter Register (ITC).
+  
+  Writes the current value of ITC.  The 64-bit value written to the ITC is returned. 
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to ITC.
+
+  @return The 64-bit value written to the ITC.
+
+**/
+UINT64
+EFIAPI
+AsmWriteItc (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Interval Timer Match Register (ITM).
+  
+  Writes the current value of ITM.  The 64-bit value written to the ITM is returned. 
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to ITM.
+
+  @return The 64-bit value written to the ITM.
+
+**/
+UINT64
+EFIAPI
+AsmWriteItm (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Interval Timer Vector Register (ITV).
+  
+  Writes the current value of ITV.  The 64-bit value written to the ITV is returned.  
+  No parameter checking is performed on Value.  All bits of Value corresponding to
+  reserved fields of ITV must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to ITV.
+
+  @return The 64-bit value written to the ITV.
+
+**/
+UINT64
+EFIAPI
+AsmWriteItv (
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of Default Control Register (DCR).
+  
+  Reads and returns the current value of DCR.  This function is only available on Itanium processors.
+
+  @return The current value of DCR.
+
+**/
+UINT64
+EFIAPI
+AsmReadDcr (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Interruption Vector Address Register (IVA).
+  
+  Reads and returns the current value of IVA.  This function is only available on Itanium processors.
+
+  @return The current value of IVA.
+**/
+UINT64
+EFIAPI
+AsmReadIva (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Page Table Address Register (PTA).
+  
+  Reads and returns the current value of PTA.  This function is only available on Itanium processors.
+
+  @return The current value of PTA.
+
+**/
+UINT64
+EFIAPI
+AsmReadPta (
+  VOID
+  );
+
+
+/**
+  Writes the current value of 64-bit Default Control Register (DCR).
+  
+  Writes the current value of DCR.  The 64-bit value written to the DCR is returned. 
+  No parameter checking is performed on Value.  All bits of Value corresponding to
+  reserved fields of DCR must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to DCR.
+
+  @return The 64-bit value written to the DCR.
+
+**/
+UINT64
+EFIAPI
+AsmWriteDcr (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Interruption Vector Address Register (IVA).
+  
+  Writes the current value of IVA.  The 64-bit value written to the IVA is returned.  
+  The size of vector table is 32 K bytes and is 32 K bytes aligned
+  the low 15 bits of Value is ignored when written.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to IVA.
+
+  @return The 64-bit value written to the IVA.
+
+**/
+UINT64
+EFIAPI
+AsmWriteIva (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Page Table Address Register (PTA).
+  
+  Writes the current value of PTA.  The 64-bit value written to the PTA is returned. 
+  No parameter checking is performed on Value.  All bits of Value corresponding to
+  reserved fields of DCR must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to PTA.
+
+  @return The 64-bit value written to the PTA.
+**/
+UINT64
+EFIAPI
+AsmWritePta (
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of Local Interrupt ID Register (LID).
+  
+  Reads and returns the current value of LID.  This function is only available on Itanium processors.
+
+  @return The current value of LID.
+
+**/
+UINT64
+EFIAPI
+AsmReadLid (
+  VOID
+  );
+
+
+/**
+  Reads the current value of External Interrupt Vector Register (IVR).
+  
+  Reads and returns the current value of IVR.  This function is only available on Itanium processors. 
+
+  @return The current value of IVR.
+
+**/
+UINT64
+EFIAPI
+AsmReadIvr (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Task Priority Register (TPR).
+  
+  Reads and returns the current value of TPR.  This function is only available on Itanium processors. 
+
+  @return The current value of TPR.
+
+**/
+UINT64
+EFIAPI
+AsmReadTpr (
+  VOID
+  );
+
+
+/**
+  Reads the current value of External Interrupt Request Register #0 (IRR0).
+  
+  Reads and returns the current value of IRR0.  This function is only available on Itanium processors.  
+
+  @return The current value of IRR0.
+
+**/
+UINT64
+EFIAPI
+AsmReadIrr0 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of External Interrupt Request Register #1 (IRR1).
+  
+  Reads and returns the current value of IRR1.  This function is only available on Itanium processors. 
+
+  @return The current value of IRR1.
+
+**/
+UINT64
+EFIAPI
+AsmReadIrr1 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of External Interrupt Request Register #2 (IRR2).
+  
+  Reads and returns the current value of IRR2.  This function is only available on Itanium processors.
+
+  @return The current value of IRR2.
+
+**/
+UINT64
+EFIAPI
+AsmReadIrr2 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of External Interrupt Request Register #3 (IRR3).
+  
+  Reads and returns the current value of IRR3.  This function is only available on Itanium processors.  
+
+  @return The current value of IRR3.
+
+**/
+UINT64
+EFIAPI
+AsmReadIrr3 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Performance Monitor Vector Register (PMV).
+  
+  Reads and returns the current value of PMV.  This function is only available on Itanium processors. 
+
+  @return The current value of PMV.
+
+**/
+UINT64
+EFIAPI
+AsmReadPmv (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Corrected Machine Check Vector Register (CMCV).
+  
+  Reads and returns the current value of CMCV.  This function is only available on Itanium processors.
+
+  @return The current value of CMCV.
+
+**/
+UINT64
+EFIAPI
+AsmReadCmcv (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Local Redirection Register #0 (LRR0).
+  
+  Reads and returns the current value of LRR0.  This function is only available on Itanium processors. 
+
+  @return The current value of LRR0.
+
+**/
+UINT64
+EFIAPI
+AsmReadLrr0 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Local Redirection Register #1 (LRR1).
+  
+  Reads and returns the current value of LRR1.  This function is only available on Itanium processors.
+
+  @return The current value of LRR1.
+
+**/
+UINT64
+EFIAPI
+AsmReadLrr1 (
+  VOID
+  );
+
+
+/**
+  Writes the current value of 64-bit Page Local Interrupt ID Register (LID).
+  
+  Writes the current value of LID.  The 64-bit value written to the LID is returned.  
+  No parameter checking is performed on Value.  All bits of Value corresponding to
+  reserved fields of LID must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to LID.
+
+  @return The 64-bit value written to the LID.
+
+**/
+UINT64
+EFIAPI
+AsmWriteLid (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Task Priority Register (TPR).
+  
+  Writes the current value of TPR.  The 64-bit value written to the TPR is returned. 
+  No parameter checking is performed on Value.  All bits of Value corresponding to
+  reserved fields of TPR must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to TPR.
+
+  @return The 64-bit value written to the TPR.
+
+**/
+UINT64
+EFIAPI
+AsmWriteTpr (
+  IN UINT64  Value
+  );
+
+
+/**
+  Performs a write operation on End OF External Interrupt Register (EOI).
+  
+  Writes a value of 0 to the EOI Register.  This function is only available on Itanium processors.
+
+**/
+VOID
+EFIAPI
+AsmWriteEoi (
+  VOID
+  );
+
+
+/**
+  Writes the current value of 64-bit Performance Monitor Vector Register (PMV).
+  
+  Writes the current value of PMV.  The 64-bit value written to the PMV is returned.  
+  No parameter checking is performed on Value.  All bits of Value corresponding
+  to reserved fields of PMV must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to PMV.
+
+  @return The 64-bit value written to the PMV.
+
+**/
+UINT64
+EFIAPI
+AsmWritePmv (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Corrected Machine Check Vector Register (CMCV).
+  
+  Writes the current value of CMCV.  The 64-bit value written to the CMCV is returned. 
+  No parameter checking is performed on Value.  All bits of Value corresponding
+  to reserved fields of CMCV must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to CMCV.
+
+  @return The 64-bit value written to the CMCV.
+
+**/
+UINT64
+EFIAPI
+AsmWriteCmcv (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Local Redirection Register #0 (LRR0).
+  
+  Writes the current value of LRR0.  The 64-bit value written to the LRR0 is returned.  
+  No parameter checking is performed on Value.  All bits of Value corresponding
+  to reserved fields of LRR0 must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to LRR0.
+
+  @return The 64-bit value written to the LRR0.
+
+**/
+UINT64
+EFIAPI
+AsmWriteLrr0 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Local Redirection Register #1 (LRR1).
+  
+  Writes the current value of LRR1.  The 64-bit value written to the LRR1 is returned. 
+  No parameter checking is performed on Value.  All bits of Value corresponding
+  to reserved fields of LRR1 must be 0 or a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Value is valid, or the caller must
+  set up fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Value    The 64-bit value to write to LRR1.
+
+  @return The 64-bit value written to the LRR1.
+
+**/
+UINT64
+EFIAPI
+AsmWriteLrr1 (
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of Instruction Breakpoint Register (IBR).
+  
+  The Instruction Breakpoint Registers are used in pairs.  The even numbered
+  registers contain breakpoint addresses, and the odd numbered registers contain
+  breakpoint mask conditions.  At least four instruction registers pairs are implemented
+  on all processor models.   Implemented registers are contiguous starting with
+  register 0.  No parameter checking is performed on Index, and if the Index value
+  is beyond the implemented IBR register range, a Reserved Register/Field fault may
+  occur.  The caller must either guarantee that Index is valid, or the caller must
+  set up fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Instruction Breakpoint Register index to read.
+
+  @return The current value of Instruction Breakpoint Register specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadIbr (
+  IN  UINT8   Index
+  );
+
+
+/**
+  Reads the current value of Data Breakpoint Register (DBR).
+
+  The Data Breakpoint Registers are used in pairs.  The even numbered registers
+  contain breakpoint addresses, and odd numbered registers contain breakpoint
+  mask conditions.  At least four data registers pairs are implemented on all processor
+  models.  Implemented registers are contiguous starting with register 0.
+  No parameter checking is performed on Index.  If the Index value is beyond
+  the implemented DBR register range, a Reserved Register/Field fault may occur.
+  The caller must either guarantee that Index is valid, or the caller must set up
+  fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Data Breakpoint Register index to read.
+
+  @return The current value of Data Breakpoint Register specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadDbr (
+  IN  UINT8   Index
+  );
+
+
+/**
+  Reads the current value of Performance Monitor Configuration Register (PMC).
+
+  All processor implementations provide at least four performance counters
+  (PMC/PMD [4]...PMC/PMD [7] pairs), and four performance monitor counter overflow
+  status registers (PMC [0]... PMC [3]).  Processor implementations may provide
+  additional implementation-dependent PMC and PMD to increase the number of
+  'generic' performance counters (PMC/PMD pairs).  The remainder of PMC and PMD
+  register set is implementation dependent.  No parameter checking is performed
+  on Index.  If the Index value is beyond the implemented PMC register range,
+  zero value will be returned.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Performance Monitor Configuration Register index to read.
+
+  @return   The current value of Performance Monitor Configuration Register
+            specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadPmc (
+  IN  UINT8   Index
+  );
+
+
+/**
+  Reads the current value of Performance Monitor Data Register (PMD).
+
+  All processor implementations provide at least 4 performance counters
+  (PMC/PMD [4]...PMC/PMD [7] pairs), and 4 performance monitor counter
+  overflow status registers (PMC [0]... PMC [3]).  Processor implementations may
+  provide additional implementation-dependent PMC and PMD to increase the number
+  of 'generic' performance counters (PMC/PMD pairs).  The remainder of PMC and PMD
+  register set is implementation dependent.  No parameter checking is performed
+  on Index.  If the Index value is beyond the implemented PMD register range,
+  zero value will be returned.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Performance Monitor Data Register index to read.
+
+  @return The current value of Performance Monitor Data Register specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadPmd (
+  IN  UINT8   Index
+  );
+
+
+/**
+  Writes the current value of 64-bit Instruction Breakpoint Register (IBR).
+
+  Writes current value of Instruction Breakpoint Register specified by Index.
+  The Instruction Breakpoint Registers are used in pairs.  The even numbered
+  registers contain breakpoint addresses, and odd numbered registers contain
+  breakpoint mask conditions.  At least four instruction registers pairs are implemented
+  on all processor models.  Implemented registers are contiguous starting with
+  register 0.  No parameter checking is performed on Index.  If the Index value
+  is beyond the implemented IBR register range, a Reserved Register/Field fault may
+  occur.  The caller must either guarantee that Index is valid, or the caller must
+  set up fault handlers to catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Instruction Breakpoint Register index to write.
+  @param Value    The 64-bit value to write to IBR.
+
+  @return The 64-bit value written to the IBR.
+
+**/
+UINT64
+EFIAPI
+AsmWriteIbr (
+  IN UINT8   Index,
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Data Breakpoint Register (DBR).
+
+  Writes current value of Data Breakpoint Register specified by Index.
+  The Data Breakpoint Registers are used in pairs.  The even numbered registers
+  contain breakpoint addresses, and odd numbered registers contain breakpoint
+  mask conditions.  At least four data registers pairs are implemented on all processor
+  models.  Implemented registers are contiguous starting with register 0.  No parameter
+  checking is performed on Index.  If the Index value is beyond the implemented
+  DBR register range, a Reserved Register/Field fault may occur.  The caller must
+  either guarantee that Index is valid, or the caller must set up fault handlers to
+  catch the faults.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Data Breakpoint Register index to write.
+  @param Value    The 64-bit value to write to DBR.
+
+  @return The 64-bit value written to the DBR.
+
+**/
+UINT64
+EFIAPI
+AsmWriteDbr (
+  IN UINT8   Index,
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Performance Monitor Configuration Register (PMC).
+
+  Writes current value of Performance Monitor Configuration Register specified by Index.
+  All processor implementations provide at least four performance counters
+  (PMC/PMD [4]...PMC/PMD [7] pairs), and four performance monitor counter overflow status
+  registers (PMC [0]... PMC [3]).  Processor implementations may provide additional
+  implementation-dependent PMC and PMD to increase the number of 'generic' performance
+  counters (PMC/PMD pairs).  The remainder of PMC and PMD register set is implementation
+  dependent.  No parameter checking is performed on Index.  If the Index value is
+  beyond the implemented PMC register range, the write is ignored.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Performance Monitor Configuration Register index to write.
+  @param Value    The 64-bit value to write to PMC.
+
+  @return The 64-bit value written to the PMC.
+
+**/
+UINT64
+EFIAPI
+AsmWritePmc (
+  IN UINT8   Index,
+  IN UINT64  Value
+  );
+
+
+/**
+  Writes the current value of 64-bit Performance Monitor Data Register (PMD).
+
+  Writes current value of Performance Monitor Data Register specified by Index.
+  All processor implementations provide at least four performance counters
+  (PMC/PMD [4]...PMC/PMD [7] pairs), and four performance monitor counter overflow
+  status registers (PMC [0]... PMC [3]).  Processor implementations may provide
+  additional implementation-dependent PMC and PMD to increase the number of 'generic'
+  performance counters (PMC/PMD pairs).  The remainder of PMC and PMD register set
+  is implementation dependent.  No parameter checking is performed on Index.  If the
+  Index value is beyond the implemented PMD register range, the write is ignored.
+  This function is only available on Itanium processors.
+
+  @param Index    The 8-bit Performance Monitor Data Register index to write.
+  @param Value    The 64-bit value to write to PMD.
+
+  @return The 64-bit value written to the PMD.
+
+**/
+UINT64
+EFIAPI
+AsmWritePmd (
+  IN UINT8   Index,
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of 64-bit Global Pointer (GP).
+
+  Reads and returns the current value of GP.
+  This function is only available on Itanium processors.
+
+  @return The current value of GP.
+
+**/
+UINT64
+EFIAPI
+AsmReadGp (
+  VOID
+  );
+
+
+/**
+  Write the current value of 64-bit Global Pointer (GP).
+
+  Writes the current value of GP. The 64-bit value written to the GP is returned.
+  No parameter checking is performed on Value.
+  This function is only available on Itanium processors.
+
+  @param Value  The 64-bit value to write to GP.
+
+  @return The 64-bit value written to the GP.
+
+**/
+UINT64
+EFIAPI
+AsmWriteGp (
+  IN UINT64  Value
+  );
+
+
+/**
+  Reads the current value of 64-bit Stack Pointer (SP).
+
+  Reads and returns the current value of SP.
+  This function is only available on Itanium processors.
+
+  @return The current value of SP.
+
+**/
+UINT64
+EFIAPI
+AsmReadSp (
+  VOID
+  );
+
+
+///
+/// Valid Index value for AsmReadControlRegister().
+///
+#define IPF_CONTROL_REGISTER_DCR   0
+#define IPF_CONTROL_REGISTER_ITM   1
+#define IPF_CONTROL_REGISTER_IVA   2
+#define IPF_CONTROL_REGISTER_PTA   8
+#define IPF_CONTROL_REGISTER_IPSR  16
+#define IPF_CONTROL_REGISTER_ISR   17
+#define IPF_CONTROL_REGISTER_IIP   19
+#define IPF_CONTROL_REGISTER_IFA   20
+#define IPF_CONTROL_REGISTER_ITIR  21
+#define IPF_CONTROL_REGISTER_IIPA  22
+#define IPF_CONTROL_REGISTER_IFS   23
+#define IPF_CONTROL_REGISTER_IIM   24
+#define IPF_CONTROL_REGISTER_IHA   25
+#define IPF_CONTROL_REGISTER_LID   64
+#define IPF_CONTROL_REGISTER_IVR   65
+#define IPF_CONTROL_REGISTER_TPR   66
+#define IPF_CONTROL_REGISTER_EOI   67
+#define IPF_CONTROL_REGISTER_IRR0  68
+#define IPF_CONTROL_REGISTER_IRR1  69
+#define IPF_CONTROL_REGISTER_IRR2  70
+#define IPF_CONTROL_REGISTER_IRR3  71
+#define IPF_CONTROL_REGISTER_ITV   72
+#define IPF_CONTROL_REGISTER_PMV   73
+#define IPF_CONTROL_REGISTER_CMCV  74
+#define IPF_CONTROL_REGISTER_LRR0  80
+#define IPF_CONTROL_REGISTER_LRR1  81
+
+/**
+  Reads a 64-bit control register.
+
+  Reads and returns the control register specified by Index. The valid Index valued 
+  are defined above in "Related Definitions".
+  If Index is invalid then 0xFFFFFFFFFFFFFFFF is returned.  This function is only 
+  available on Itanium processors.
+
+  @param  Index                     The index of the control register to read.
+
+  @return The control register specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadControlRegister (
+  IN UINT64  Index
+  );
+
+
+///
+/// Valid Index value for AsmReadApplicationRegister().
+///
+#define IPF_APPLICATION_REGISTER_K0        0
+#define IPF_APPLICATION_REGISTER_K1        1
+#define IPF_APPLICATION_REGISTER_K2        2
+#define IPF_APPLICATION_REGISTER_K3        3
+#define IPF_APPLICATION_REGISTER_K4        4
+#define IPF_APPLICATION_REGISTER_K5        5
+#define IPF_APPLICATION_REGISTER_K6        6
+#define IPF_APPLICATION_REGISTER_K7        7
+#define IPF_APPLICATION_REGISTER_RSC       16
+#define IPF_APPLICATION_REGISTER_BSP       17
+#define IPF_APPLICATION_REGISTER_BSPSTORE  18
+#define IPF_APPLICATION_REGISTER_RNAT      19
+#define IPF_APPLICATION_REGISTER_FCR       21
+#define IPF_APPLICATION_REGISTER_EFLAG     24
+#define IPF_APPLICATION_REGISTER_CSD       25
+#define IPF_APPLICATION_REGISTER_SSD       26
+#define IPF_APPLICATION_REGISTER_CFLG      27
+#define IPF_APPLICATION_REGISTER_FSR       28
+#define IPF_APPLICATION_REGISTER_FIR       29
+#define IPF_APPLICATION_REGISTER_FDR       30
+#define IPF_APPLICATION_REGISTER_CCV       32
+#define IPF_APPLICATION_REGISTER_UNAT      36
+#define IPF_APPLICATION_REGISTER_FPSR      40
+#define IPF_APPLICATION_REGISTER_ITC       44
+#define IPF_APPLICATION_REGISTER_PFS       64
+#define IPF_APPLICATION_REGISTER_LC        65
+#define IPF_APPLICATION_REGISTER_EC        66
+
+/**
+  Reads a 64-bit application register.
+
+  Reads and returns the application register specified by Index. The valid Index 
+  valued are defined above in "Related Definitions".
+  If Index is invalid then 0xFFFFFFFFFFFFFFFF is returned.  This function is only 
+  available on Itanium processors.
+
+  @param  Index                     The index of the application register to read.
+
+  @return The application register specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadApplicationRegister (
+  IN UINT64  Index
+  );
+
+
+/**
+  Reads the current value of a Machine Specific Register (MSR).
+
+  Reads and returns the current value of the Machine Specific Register specified by Index.  No
+  parameter checking is performed on Index, and if the Index value is beyond the implemented MSR
+  register range, a Reserved Register/Field fault may occur.  The caller must either guarantee that
+  Index is valid, or the caller must set up fault handlers to catch the faults.  This function is
+  only available on Itanium processors.
+
+  @param  Index                     The 8-bit Machine Specific Register index to read.
+
+  @return The current value of the Machine Specific Register specified by Index.  
+
+**/
+UINT64
+EFIAPI
+AsmReadMsr (
+  IN UINT8   Index  
+  );
+
+
+/**
+  Writes the current value of a Machine Specific Register (MSR).
+
+  Writes Value to the Machine Specific Register specified by Index.  Value is returned.  No
+  parameter checking is performed on Index, and if the Index value is beyond the implemented MSR
+  register range, a Reserved Register/Field fault may occur.  The caller must either guarantee that
+  Index is valid, or the caller must set up fault handlers to catch the faults.  This function is
+  only available on Itanium processors.
+
+  @param  Index                     The 8-bit Machine Specific Register index to write.
+  @param  Value                     The 64-bit value to write to the Machine Specific Register.
+
+  @return The 64-bit value to write to the Machine Specific Register.  
+
+**/
+UINT64
+EFIAPI
+AsmWriteMsr (
+  IN UINT8   Index, 
+  IN UINT64  Value  
+  );
+
+
+/**
+  Determines if the CPU is currently executing in virtual, physical, or mixed mode.
+
+  Determines the current execution mode of the CPU.
+  If the CPU is in virtual mode(PSR.RT=1, PSR.DT=1, PSR.IT=1), then 1 is returned.
+  If the CPU is in physical mode(PSR.RT=0, PSR.DT=0, PSR.IT=0), then 0 is returned.
+  If the CPU is not in physical mode or virtual mode, then it is in mixed mode,
+  and -1 is returned.
+  This function is only available on Itanium processors.
+
+  @retval  1  The CPU is in virtual mode.
+  @retval  0  The CPU is in physical mode.
+  @retval -1  The CPU is in mixed mode.
+
+**/
+INT64
+EFIAPI
+AsmCpuVirtual (
+  VOID
+  );
+
+
+/**
+  Makes a PAL procedure call.
+
+  This is a wrapper function to make a PAL procedure call.  Based on the Index
+  value this API will make static or stacked PAL call.  The following table
+  describes the usage of PAL Procedure Index Assignment. Architected procedures
+  may be designated as required or optional.  If a PAL procedure is specified
+  as optional, a unique return code of 0xFFFFFFFFFFFFFFFF is returned in the
+  Status field of the PAL_CALL_RETURN structure.
+  This indicates that the procedure is not present in this PAL implementation.
+  It is the caller's responsibility to check for this return code after calling
+  any optional PAL procedure.
+  No parameter checking is performed on the 5 input parameters, but there are
+  some common rules that the caller should follow when making a PAL call.  Any
+  address passed to PAL as buffers for return parameters must be 8-byte aligned.
+  Unaligned addresses may cause undefined results.  For those parameters defined
+  as reserved or some fields defined as reserved must be zero filled or the invalid
+  argument return value may be returned or undefined result may occur during the
+  execution of the procedure.  If the PalEntryPoint  does not point to a valid
+  PAL entry point then the system behavior is undefined.  This function is only
+  available on Itanium processors.
+
+  @param PalEntryPoint  The PAL procedure calls entry point.
+  @param Index          The PAL procedure Index number.
+  @param Arg2           The 2nd parameter for PAL procedure calls.
+  @param Arg3           The 3rd parameter for PAL procedure calls.
+  @param Arg4           The 4th parameter for PAL procedure calls.
+
+  @return structure returned from the PAL Call procedure, including the status and return value.
+
+**/
+PAL_CALL_RETURN
+EFIAPI
+AsmPalCall (
+  IN UINT64  PalEntryPoint,
+  IN UINT64  Index,
+  IN UINT64  Arg2,
+  IN UINT64  Arg3,
+  IN UINT64  Arg4
+  );
+#endif
+
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+///
+/// IA32 and x64 Specific Functions.
+/// Byte packed structure for 16-bit Real Mode EFLAGS.
+///
+typedef union {
+  struct {
+    UINT32  CF:1;           ///< Carry Flag.
+    UINT32  Reserved_0:1;   ///< Reserved.
+    UINT32  PF:1;           ///< Parity Flag.
+    UINT32  Reserved_1:1;   ///< Reserved.
+    UINT32  AF:1;           ///< Auxiliary Carry Flag.
+    UINT32  Reserved_2:1;   ///< Reserved.
+    UINT32  ZF:1;           ///< Zero Flag.
+    UINT32  SF:1;           ///< Sign Flag.
+    UINT32  TF:1;           ///< Trap Flag.
+    UINT32  IF:1;           ///< Interrupt Enable Flag.
+    UINT32  DF:1;           ///< Direction Flag.
+    UINT32  OF:1;           ///< Overflow Flag.
+    UINT32  IOPL:2;         ///< I/O Privilege Level.
+    UINT32  NT:1;           ///< Nested Task.
+    UINT32  Reserved_3:1;   ///< Reserved.
+  } Bits;
+  UINT16    Uint16;
+} IA32_FLAGS16;
+
+///
+/// Byte packed structure for EFLAGS/RFLAGS.
+/// 32-bits on IA-32.
+/// 64-bits on x64.  The upper 32-bits on x64 are reserved.
+///
+typedef union {
+  struct {
+    UINT32  CF:1;           ///< Carry Flag.
+    UINT32  Reserved_0:1;   ///< Reserved.
+    UINT32  PF:1;           ///< Parity Flag.
+    UINT32  Reserved_1:1;   ///< Reserved.
+    UINT32  AF:1;           ///< Auxiliary Carry Flag.
+    UINT32  Reserved_2:1;   ///< Reserved.
+    UINT32  ZF:1;           ///< Zero Flag.
+    UINT32  SF:1;           ///< Sign Flag.
+    UINT32  TF:1;           ///< Trap Flag.
+    UINT32  IF:1;           ///< Interrupt Enable Flag.
+    UINT32  DF:1;           ///< Direction Flag.
+    UINT32  OF:1;           ///< Overflow Flag.
+    UINT32  IOPL:2;         ///< I/O Privilege Level.
+    UINT32  NT:1;           ///< Nested Task.
+    UINT32  Reserved_3:1;   ///< Reserved.
+    UINT32  RF:1;           ///< Resume Flag.
+    UINT32  VM:1;           ///< Virtual 8086 Mode.
+    UINT32  AC:1;           ///< Alignment Check.
+    UINT32  VIF:1;          ///< Virtual Interrupt Flag.
+    UINT32  VIP:1;          ///< Virtual Interrupt Pending.
+    UINT32  ID:1;           ///< ID Flag.
+    UINT32  Reserved_4:10;  ///< Reserved.
+  } Bits;
+  UINTN     UintN;
+} IA32_EFLAGS32;
+
+///
+/// Byte packed structure for Control Register 0 (CR0).
+/// 32-bits on IA-32.
+/// 64-bits on x64.  The upper 32-bits on x64 are reserved.
+///
+typedef union {
+  struct {
+    UINT32  PE:1;           ///< Protection Enable.
+    UINT32  MP:1;           ///< Monitor Coprocessor.
+    UINT32  EM:1;           ///< Emulation.
+    UINT32  TS:1;           ///< Task Switched.
+    UINT32  ET:1;           ///< Extension Type.
+    UINT32  NE:1;           ///< Numeric Error.
+    UINT32  Reserved_0:10;  ///< Reserved.
+    UINT32  WP:1;           ///< Write Protect.
+    UINT32  Reserved_1:1;   ///< Reserved.
+    UINT32  AM:1;           ///< Alignment Mask.
+    UINT32  Reserved_2:10;  ///< Reserved.
+    UINT32  NW:1;           ///< Mot Write-through.
+    UINT32  CD:1;           ///< Cache Disable.
+    UINT32  PG:1;           ///< Paging.
+  } Bits;
+  UINTN     UintN;
+} IA32_CR0;
+
+///
+/// Byte packed structure for Control Register 4 (CR4).
+/// 32-bits on IA-32.
+/// 64-bits on x64.  The upper 32-bits on x64 are reserved.
+///
+typedef union {
+  struct {
+    UINT32  VME:1;          ///< Virtual-8086 Mode Extensions.
+    UINT32  PVI:1;          ///< Protected-Mode Virtual Interrupts.
+    UINT32  TSD:1;          ///< Time Stamp Disable.
+    UINT32  DE:1;           ///< Debugging Extensions.
+    UINT32  PSE:1;          ///< Page Size Extensions.
+    UINT32  PAE:1;          ///< Physical Address Extension.
+    UINT32  MCE:1;          ///< Machine Check Enable.
+    UINT32  PGE:1;          ///< Page Global Enable.
+    UINT32  PCE:1;          ///< Performance Monitoring Counter
+                            ///< Enable.
+    UINT32  OSFXSR:1;       ///< Operating System Support for
+                            ///< FXSAVE and FXRSTOR instructions
+    UINT32  OSXMMEXCPT:1;   ///< Operating System Support for
+                            ///< Unmasked SIMD Floating Point
+                            ///< Exceptions.
+    UINT32  Reserved_0:2;   ///< Reserved.
+    UINT32  VMXE:1;         ///< VMX Enable
+    UINT32  Reserved_1:18;  ///< Reserved.
+  } Bits;
+  UINTN     UintN;
+} IA32_CR4;
+
+///
+/// Byte packed structure for a segment descriptor in a GDT/LDT.
+///
+typedef union {
+  struct {
+    UINT32  LimitLow:16;
+    UINT32  BaseLow:16;
+    UINT32  BaseMid:8;
+    UINT32  Type:4;
+    UINT32  S:1;
+    UINT32  DPL:2;
+    UINT32  P:1;
+    UINT32  LimitHigh:4;
+    UINT32  AVL:1;
+    UINT32  L:1;
+    UINT32  DB:1;
+    UINT32  G:1;
+    UINT32  BaseHigh:8;
+  } Bits;
+  UINT64  Uint64;
+} IA32_SEGMENT_DESCRIPTOR;
+
+///
+/// Byte packed structure for an IDTR, GDTR, LDTR descriptor.
+///
+#pragma pack (1)
+typedef struct {
+  UINT16  Limit;
+  UINTN   Base;
+} IA32_DESCRIPTOR;
+#pragma pack ()
+
+#define IA32_IDT_GATE_TYPE_TASK          0x85
+#define IA32_IDT_GATE_TYPE_INTERRUPT_16  0x86
+#define IA32_IDT_GATE_TYPE_TRAP_16       0x87
+#define IA32_IDT_GATE_TYPE_INTERRUPT_32  0x8E
+#define IA32_IDT_GATE_TYPE_TRAP_32       0x8F
+
+
+#if defined (MDE_CPU_IA32)
+///
+/// Byte packed structure for an IA-32 Interrupt Gate Descriptor.
+///
+typedef union {
+  struct {
+    UINT32  OffsetLow:16;   ///< Offset bits 15..0.
+    UINT32  Selector:16;    ///< Selector.
+    UINT32  Reserved_0:8;   ///< Reserved.
+    UINT32  GateType:8;     ///< Gate Type.  See #defines above.
+    UINT32  OffsetHigh:16;  ///< Offset bits 31..16.
+  } Bits;
+  UINT64  Uint64;
+} IA32_IDT_GATE_DESCRIPTOR;
+
+#endif
+
+#if defined (MDE_CPU_X64)
+///
+/// Byte packed structure for an x64 Interrupt Gate Descriptor.
+///
+typedef union {
+  struct {
+    UINT32  OffsetLow:16;   ///< Offset bits 15..0.
+    UINT32  Selector:16;    ///< Selector.
+    UINT32  Reserved_0:8;   ///< Reserved.
+    UINT32  GateType:8;     ///< Gate Type.  See #defines above.
+    UINT32  OffsetHigh:16;  ///< Offset bits 31..16.
+    UINT32  OffsetUpper:32; ///< Offset bits 63..32.
+    UINT32  Reserved_1:32;  ///< Reserved.
+  } Bits;
+  struct {
+    UINT64  Uint64;
+    UINT64  Uint64_1;
+  } Uint128;   
+} IA32_IDT_GATE_DESCRIPTOR;
+
+#endif
+
+///
+/// Byte packed structure for an FP/SSE/SSE2 context.
+///
+typedef struct {
+  UINT8  Buffer[512];
+} IA32_FX_BUFFER;
+
+///
+/// Structures for the 16-bit real mode thunks.
+///
+typedef struct {
+  UINT32                            Reserved1;
+  UINT32                            Reserved2;
+  UINT32                            Reserved3;
+  UINT32                            Reserved4;
+  UINT8                             BL;
+  UINT8                             BH;
+  UINT16                            Reserved5;
+  UINT8                             DL;
+  UINT8                             DH;
+  UINT16                            Reserved6;
+  UINT8                             CL;
+  UINT8                             CH;
+  UINT16                            Reserved7;
+  UINT8                             AL;
+  UINT8                             AH;
+  UINT16                            Reserved8;
+} IA32_BYTE_REGS;
+
+typedef struct {
+  UINT16                            DI;
+  UINT16                            Reserved1;
+  UINT16                            SI;
+  UINT16                            Reserved2;
+  UINT16                            BP;
+  UINT16                            Reserved3;
+  UINT16                            SP;
+  UINT16                            Reserved4;
+  UINT16                            BX;
+  UINT16                            Reserved5;
+  UINT16                            DX;
+  UINT16                            Reserved6;
+  UINT16                            CX;
+  UINT16                            Reserved7;
+  UINT16                            AX;
+  UINT16                            Reserved8;
+} IA32_WORD_REGS;
+
+typedef struct {
+  UINT32                            EDI;
+  UINT32                            ESI;
+  UINT32                            EBP;
+  UINT32                            ESP;
+  UINT32                            EBX;
+  UINT32                            EDX;
+  UINT32                            ECX;
+  UINT32                            EAX;
+  UINT16                            DS;
+  UINT16                            ES;
+  UINT16                            FS;
+  UINT16                            GS;
+  IA32_EFLAGS32                     EFLAGS;
+  UINT32                            Eip;
+  UINT16                            CS;
+  UINT16                            SS;
+} IA32_DWORD_REGS;
+
+typedef union {
+  IA32_DWORD_REGS                   E;
+  IA32_WORD_REGS                    X;
+  IA32_BYTE_REGS                    H;
+} IA32_REGISTER_SET;
+
+///
+/// Byte packed structure for an 16-bit real mode thunks.
+///
+typedef struct {
+  IA32_REGISTER_SET                 *RealModeState;
+  VOID                              *RealModeBuffer;
+  UINT32                            RealModeBufferSize;
+  UINT32                            ThunkAttributes;
+} THUNK_CONTEXT;
+
+#define THUNK_ATTRIBUTE_BIG_REAL_MODE             0x00000001
+#define THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15   0x00000002
+#define THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL 0x00000004
+
+/**
+  Retrieves CPUID information.
+
+  Executes the CPUID instruction with EAX set to the value specified by Index.
+  This function always returns Index.
+  If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.
+  If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.
+  If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.
+  If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.
+  This function is only available on IA-32 and x64.
+
+  @param  Index The 32-bit value to load into EAX prior to invoking the CPUID
+                instruction.
+  @param  Eax   The pointer to the 32-bit EAX value returned by the CPUID
+                instruction. This is an optional parameter that may be NULL.
+  @param  Ebx   The pointer to the 32-bit EBX value returned by the CPUID
+                instruction. This is an optional parameter that may be NULL.
+  @param  Ecx   The pointer to the 32-bit ECX value returned by the CPUID
+                instruction. This is an optional parameter that may be NULL.
+  @param  Edx   The pointer to the 32-bit EDX value returned by the CPUID
+                instruction. This is an optional parameter that may be NULL.
+
+  @return Index.
+
+**/
+UINT32
+EFIAPI
+AsmCpuid (
+  IN      UINT32                    Index,
+  OUT     UINT32                    *Eax,  OPTIONAL
+  OUT     UINT32                    *Ebx,  OPTIONAL
+  OUT     UINT32                    *Ecx,  OPTIONAL
+  OUT     UINT32                    *Edx   OPTIONAL
+  );
+
+
+/**
+  Retrieves CPUID information using an extended leaf identifier.
+
+  Executes the CPUID instruction with EAX set to the value specified by Index
+  and ECX set to the value specified by SubIndex. This function always returns
+  Index. This function is only available on IA-32 and x64.
+
+  If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.
+  If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.
+  If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.
+  If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.
+
+  @param  Index     The 32-bit value to load into EAX prior to invoking the
+                    CPUID instruction.
+  @param  SubIndex  The 32-bit value to load into ECX prior to invoking the
+                    CPUID instruction.
+  @param  Eax       The pointer to the 32-bit EAX value returned by the CPUID
+                    instruction. This is an optional parameter that may be
+                    NULL.
+  @param  Ebx       The pointer to the 32-bit EBX value returned by the CPUID
+                    instruction. This is an optional parameter that may be
+                    NULL.
+  @param  Ecx       The pointer to the 32-bit ECX value returned by the CPUID
+                    instruction. This is an optional parameter that may be
+                    NULL.
+  @param  Edx       The pointer to the 32-bit EDX value returned by the CPUID
+                    instruction. This is an optional parameter that may be
+                    NULL.
+
+  @return Index.
+
+**/
+UINT32
+EFIAPI
+AsmCpuidEx (
+  IN      UINT32                    Index,
+  IN      UINT32                    SubIndex,
+  OUT     UINT32                    *Eax,  OPTIONAL
+  OUT     UINT32                    *Ebx,  OPTIONAL
+  OUT     UINT32                    *Ecx,  OPTIONAL
+  OUT     UINT32                    *Edx   OPTIONAL
+  );
+
+
+/**
+  Set CD bit and clear NW bit of CR0 followed by a WBINVD.
+
+  Disables the caches by setting the CD bit of CR0 to 1, clearing the NW bit of CR0 to 0,
+  and executing a WBINVD instruction.  This function is only available on IA-32 and x64.
+
+**/
+VOID
+EFIAPI
+AsmDisableCache (
+  VOID
+  );
+
+
+/**
+  Perform a WBINVD and clear both the CD and NW bits of CR0.
+
+  Enables the caches by executing a WBINVD instruction and then clear both the CD and NW
+  bits of CR0 to 0.  This function is only available on IA-32 and x64.
+
+**/
+VOID
+EFIAPI
+AsmEnableCache (
+  VOID
+  );
+
+
+/**
+  Returns the lower 32-bits of a Machine Specific Register(MSR).
+
+  Reads and returns the lower 32-bits of the MSR specified by Index.
+  No parameter checking is performed on Index, and some Index values may cause
+  CPU exceptions. The caller must either guarantee that Index is valid, or the
+  caller must set up exception handlers to catch the exceptions. This function
+  is only available on IA-32 and x64.
+
+  @param  Index The 32-bit MSR index to read.
+
+  @return The lower 32 bits of the MSR identified by Index.
+
+**/
+UINT32
+EFIAPI
+AsmReadMsr32 (
+  IN      UINT32                    Index
+  );
+
+
+/**
+  Writes a 32-bit value to a Machine Specific Register(MSR), and returns the value.
+  The upper 32-bits of the MSR are set to zero.
+
+  Writes the 32-bit value specified by Value to the MSR specified by Index. The
+  upper 32-bits of the MSR write are set to zero. The 32-bit value written to
+  the MSR is returned. No parameter checking is performed on Index or Value,
+  and some of these may cause CPU exceptions. The caller must either guarantee
+  that Index and Value are valid, or the caller must establish proper exception
+  handlers. This function is only available on IA-32 and x64.
+
+  @param  Index The 32-bit MSR index to write.
+  @param  Value The 32-bit value to write to the MSR.
+
+  @return Value
+
+**/
+UINT32
+EFIAPI
+AsmWriteMsr32 (
+  IN      UINT32                    Index,
+  IN      UINT32                    Value
+  );
+
+
+/**
+  Reads a 64-bit MSR, performs a bitwise OR on the lower 32-bits, and
+  writes the result back to the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise OR
+  between the lower 32-bits of the read result and the value specified by
+  OrData, and writes the result to the 64-bit MSR specified by Index. The lower
+  32-bits of the value written to the MSR is returned. No parameter checking is
+  performed on Index or OrData, and some of these may cause CPU exceptions. The
+  caller must either guarantee that Index and OrData are valid, or the caller
+  must establish proper exception handlers. This function is only available on
+  IA-32 and x64.
+
+  @param  Index   The 32-bit MSR index to write.
+  @param  OrData  The value to OR with the read value from the MSR.
+
+  @return The lower 32-bit value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrOr32 (
+  IN      UINT32                    Index,
+  IN      UINT32                    OrData
+  );
+
+
+/**
+  Reads a 64-bit MSR, performs a bitwise AND on the lower 32-bits, and writes
+  the result back to the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the
+  lower 32-bits of the read result and the value specified by AndData, and
+  writes the result to the 64-bit MSR specified by Index. The lower 32-bits of
+  the value written to the MSR is returned. No parameter checking is performed
+  on Index or AndData, and some of these may cause CPU exceptions. The caller
+  must either guarantee that Index and AndData are valid, or the caller must
+  establish proper exception handlers. This function is only available on IA-32
+  and x64.
+
+  @param  Index   The 32-bit MSR index to write.
+  @param  AndData The value to AND with the read value from the MSR.
+
+  @return The lower 32-bit value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrAnd32 (
+  IN      UINT32                    Index,
+  IN      UINT32                    AndData
+  );
+
+
+/**
+  Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise OR
+  on the lower 32-bits, and writes the result back to the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the
+  lower 32-bits of the read result and the value specified by AndData
+  preserving the upper 32-bits, performs a bitwise OR between the
+  result of the AND operation and the value specified by OrData, and writes the
+  result to the 64-bit MSR specified by Address. The lower 32-bits of the value
+  written to the MSR is returned. No parameter checking is performed on Index,
+  AndData, or OrData, and some of these may cause CPU exceptions. The caller
+  must either guarantee that Index, AndData, and OrData are valid, or the
+  caller must establish proper exception handlers. This function is only
+  available on IA-32 and x64.
+
+  @param  Index   The 32-bit MSR index to write.
+  @param  AndData The value to AND with the read value from the MSR.
+  @param  OrData  The value to OR with the result of the AND operation.
+
+  @return The lower 32-bit value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrAndThenOr32 (
+  IN      UINT32                    Index,
+  IN      UINT32                    AndData,
+  IN      UINT32                    OrData
+  );
+
+
+/**
+  Reads a bit field of an MSR.
+
+  Reads the bit field in the lower 32-bits of a 64-bit MSR. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned. The caller must either guarantee that Index is valid, or the caller
+  must set up exception handlers to catch the exceptions. This function is only
+  available on IA-32 and x64.
+
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+
+  @return The bit field read from the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrBitFieldRead32 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit
+  );
+
+
+/**
+  Writes a bit field to an MSR.
+
+  Writes Value to a bit field in the lower 32-bits of a 64-bit MSR. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination MSR are preserved. The lower 32-bits of the MSR written is
+  returned. The caller must either guarantee that Index and the data written 
+  is valid, or the caller must set up exception handlers to catch the exceptions. 
+  This function is only available on IA-32 and x64.
+
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  Value     New value of the bit field.
+
+  @return The lower 32-bit of the value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrBitFieldWrite32 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    Value
+  );
+
+
+/**
+  Reads a bit field in a 64-bit MSR, performs a bitwise OR, and writes the
+  result back to the bit field in the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise OR
+  between the read result and the value specified by OrData, and writes the
+  result to the 64-bit MSR specified by Index. The lower 32-bits of the value
+  written to the MSR are returned. Extra left bits in OrData are stripped. The
+  caller must either guarantee that Index and the data written is valid, or
+  the caller must set up exception handlers to catch the exceptions. This
+  function is only available on IA-32 and x64.
+
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  OrData    The value to OR with the read value from the MSR.
+
+  @return The lower 32-bit of the value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrBitFieldOr32 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    OrData
+  );
+
+
+/**
+  Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the
+  result back to the bit field in the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the
+  read result and the value specified by AndData, and writes the result to the
+  64-bit MSR specified by Index. The lower 32-bits of the value written to the
+  MSR are returned. Extra left bits in AndData are stripped. The caller must
+  either guarantee that Index and the data written is valid, or the caller must
+  set up exception handlers to catch the exceptions. This function is only
+  available on IA-32 and x64.
+
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the read value from the MSR.
+
+  @return The lower 32-bit of the value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrBitFieldAnd32 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    AndData
+  );
+
+
+/**
+  Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by a
+  bitwise OR between the read result and the value specified by
+  AndData, and writes the result to the 64-bit MSR specified by Index. The
+  lower 32-bits of the value written to the MSR are returned. Extra left bits
+  in both AndData and OrData are stripped. The caller must either guarantee
+  that Index and the data written is valid, or the caller must set up exception
+  handlers to catch the exceptions. This function is only available on IA-32
+  and x64.
+
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the read value from the MSR.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The lower 32-bit of the value written to the MSR.
+
+**/
+UINT32
+EFIAPI
+AsmMsrBitFieldAndThenOr32 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT32                    AndData,
+  IN      UINT32                    OrData
+  );
+
+
+/**
+  Returns a 64-bit Machine Specific Register(MSR).
+
+  Reads and returns the 64-bit MSR specified by Index. No parameter checking is
+  performed on Index, and some Index values may cause CPU exceptions. The
+  caller must either guarantee that Index is valid, or the caller must set up
+  exception handlers to catch the exceptions. This function is only available
+  on IA-32 and x64.
+
+  @param  Index The 32-bit MSR index to read.
+
+  @return The value of the MSR identified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadMsr64 (
+  IN      UINT32                    Index
+  );
+
+
+/**
+  Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
+  value.
+
+  Writes the 64-bit value specified by Value to the MSR specified by Index. The
+  64-bit value written to the MSR is returned. No parameter checking is
+  performed on Index or Value, and some of these may cause CPU exceptions. The
+  caller must either guarantee that Index and Value are valid, or the caller
+  must establish proper exception handlers. This function is only available on
+  IA-32 and x64.
+
+  @param  Index The 32-bit MSR index to write.
+  @param  Value The 64-bit value to write to the MSR.
+
+  @return Value
+
+**/
+UINT64
+EFIAPI
+AsmWriteMsr64 (
+  IN      UINT32                    Index,
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Reads a 64-bit MSR, performs a bitwise OR, and writes the result
+  back to the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise OR
+  between the read result and the value specified by OrData, and writes the
+  result to the 64-bit MSR specified by Index. The value written to the MSR is
+  returned. No parameter checking is performed on Index or OrData, and some of
+  these may cause CPU exceptions. The caller must either guarantee that Index
+  and OrData are valid, or the caller must establish proper exception handlers.
+  This function is only available on IA-32 and x64.
+
+  @param  Index   The 32-bit MSR index to write.
+  @param  OrData  The value to OR with the read value from the MSR.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrOr64 (
+  IN      UINT32                    Index,
+  IN      UINT64                    OrData
+  );
+
+
+/**
+  Reads a 64-bit MSR, performs a bitwise AND, and writes the result back to the
+  64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the
+  read result and the value specified by OrData, and writes the result to the
+  64-bit MSR specified by Index. The value written to the MSR is returned. No
+  parameter checking is performed on Index or OrData, and some of these may
+  cause CPU exceptions. The caller must either guarantee that Index and OrData
+  are valid, or the caller must establish proper exception handlers. This
+  function is only available on IA-32 and x64.
+
+  @param  Index   The 32-bit MSR index to write.
+  @param  AndData The value to AND with the read value from the MSR.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrAnd64 (
+  IN      UINT32                    Index,
+  IN      UINT64                    AndData
+  );
+
+
+/**
+  Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise 
+  OR, and writes the result back to the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between read
+  result and the value specified by AndData, performs a bitwise OR
+  between the result of the AND operation and the value specified by OrData,
+  and writes the result to the 64-bit MSR specified by Index. The value written
+  to the MSR is returned. No parameter checking is performed on Index, AndData,
+  or OrData, and some of these may cause CPU exceptions. The caller must either
+  guarantee that Index, AndData, and OrData are valid, or the caller must
+  establish proper exception handlers. This function is only available on IA-32
+  and x64.
+
+  @param  Index   The 32-bit MSR index to write.
+  @param  AndData The value to AND with the read value from the MSR.
+  @param  OrData  The value to OR with the result of the AND operation.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrAndThenOr64 (
+  IN      UINT32                    Index,
+  IN      UINT64                    AndData,
+  IN      UINT64                    OrData
+  );
+
+
+/**
+  Reads a bit field of an MSR.
+
+  Reads the bit field in the 64-bit MSR. The bit field is specified by the
+  StartBit and the EndBit. The value of the bit field is returned. The caller
+  must either guarantee that Index is valid, or the caller must set up
+  exception handlers to catch the exceptions. This function is only available
+  on IA-32 and x64.
+
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+
+  @return The value read from the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrBitFieldRead64 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit
+  );
+
+
+/**
+  Writes a bit field to an MSR.
+
+  Writes Value to a bit field in a 64-bit MSR. The bit field is specified by
+  the StartBit and the EndBit. All other bits in the destination MSR are
+  preserved. The MSR written is returned. The caller must either guarantee 
+  that Index and the data written is valid, or the caller must set up exception 
+  handlers to catch the exceptions. This function is only available on IA-32 and x64.
+
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  Value     New value of the bit field.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrBitFieldWrite64 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Reads a bit field in a 64-bit MSR, performs a bitwise OR, and
+  writes the result back to the bit field in the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise OR
+  between the read result and the value specified by OrData, and writes the
+  result to the 64-bit MSR specified by Index. The value written to the MSR is
+  returned. Extra left bits in OrData are stripped. The caller must either
+  guarantee that Index and the data written is valid, or the caller must set up
+  exception handlers to catch the exceptions. This function is only available
+  on IA-32 and x64.
+
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  OrData    The value to OR with the read value from the bit field.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrBitFieldOr64 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    OrData
+  );
+
+
+/**
+  Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the
+  result back to the bit field in the 64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND between the
+  read result and the value specified by AndData, and writes the result to the
+  64-bit MSR specified by Index. The value written to the MSR is returned.
+  Extra left bits in AndData are stripped. The caller must either guarantee
+  that Index and the data written is valid, or the caller must set up exception
+  handlers to catch the exceptions. This function is only available on IA-32
+  and x64.
+
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  AndData   The value to AND with the read value from the bit field.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrBitFieldAnd64 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    AndData
+  );
+
+
+/**
+  Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  64-bit MSR.
+
+  Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by
+  a bitwise OR between the read result and the value specified by
+  AndData, and writes the result to the 64-bit MSR specified by Index. The
+  value written to the MSR is returned. Extra left bits in both AndData and
+  OrData are stripped. The caller must either guarantee that Index and the data
+  written is valid, or the caller must set up exception handlers to catch the
+  exceptions. This function is only available on IA-32 and x64.
+
+  If StartBit is greater than 63, then ASSERT().
+  If EndBit is greater than 63, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Index     The 32-bit MSR index to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..63.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..63.
+  @param  AndData   The value to AND with the read value from the bit field.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the MSR.
+
+**/
+UINT64
+EFIAPI
+AsmMsrBitFieldAndThenOr64 (
+  IN      UINT32                    Index,
+  IN      UINTN                     StartBit,
+  IN      UINTN                     EndBit,
+  IN      UINT64                    AndData,
+  IN      UINT64                    OrData
+  );
+
+
+/**
+  Reads the current value of the EFLAGS register.
+
+  Reads and returns the current value of the EFLAGS register. This function is
+  only available on IA-32 and x64. This returns a 32-bit value on IA-32 and a
+  64-bit value on x64.
+
+  @return EFLAGS on IA-32 or RFLAGS on x64.
+
+**/
+UINTN
+EFIAPI
+AsmReadEflags (
+  VOID
+  );
+
+
+/**
+  Reads the current value of the Control Register 0 (CR0).
+
+  Reads and returns the current value of CR0. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of the Control Register 0 (CR0).
+
+**/
+UINTN
+EFIAPI
+AsmReadCr0 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of the Control Register 2 (CR2).
+
+  Reads and returns the current value of CR2. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of the Control Register 2 (CR2).
+
+**/
+UINTN
+EFIAPI
+AsmReadCr2 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of the Control Register 3 (CR3).
+
+  Reads and returns the current value of CR3. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of the Control Register 3 (CR3).
+
+**/
+UINTN
+EFIAPI
+AsmReadCr3 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of the Control Register 4 (CR4).
+
+  Reads and returns the current value of CR4. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of the Control Register 4 (CR4).
+
+**/
+UINTN
+EFIAPI
+AsmReadCr4 (
+  VOID
+  );
+
+
+/**
+  Writes a value to Control Register 0 (CR0).
+
+  Writes and returns a new value to CR0. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Cr0 The value to write to CR0.
+
+  @return The value written to CR0.
+
+**/
+UINTN
+EFIAPI
+AsmWriteCr0 (
+  UINTN  Cr0
+  );
+
+
+/**
+  Writes a value to Control Register 2 (CR2).
+
+  Writes and returns a new value to CR2. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Cr2 The value to write to CR2.
+
+  @return The value written to CR2.
+
+**/
+UINTN
+EFIAPI
+AsmWriteCr2 (
+  UINTN  Cr2
+  );
+
+
+/**
+  Writes a value to Control Register 3 (CR3).
+
+  Writes and returns a new value to CR3. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Cr3 The value to write to CR3.
+
+  @return The value written to CR3.
+
+**/
+UINTN
+EFIAPI
+AsmWriteCr3 (
+  UINTN  Cr3
+  );
+
+
+/**
+  Writes a value to Control Register 4 (CR4).
+
+  Writes and returns a new value to CR4. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Cr4 The value to write to CR4.
+
+  @return The value written to CR4.
+
+**/
+UINTN
+EFIAPI
+AsmWriteCr4 (
+  UINTN  Cr4
+  );
+
+
+/**
+  Reads the current value of Debug Register 0 (DR0).
+
+  Reads and returns the current value of DR0. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 0 (DR0).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr0 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 1 (DR1).
+
+  Reads and returns the current value of DR1. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 1 (DR1).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr1 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 2 (DR2).
+
+  Reads and returns the current value of DR2. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 2 (DR2).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr2 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 3 (DR3).
+
+  Reads and returns the current value of DR3. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 3 (DR3).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr3 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 4 (DR4).
+
+  Reads and returns the current value of DR4. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 4 (DR4).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr4 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 5 (DR5).
+
+  Reads and returns the current value of DR5. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 5 (DR5).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr5 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 6 (DR6).
+
+  Reads and returns the current value of DR6. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 6 (DR6).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr6 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Debug Register 7 (DR7).
+
+  Reads and returns the current value of DR7. This function is only available
+  on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on
+  x64.
+
+  @return The value of Debug Register 7 (DR7).
+
+**/
+UINTN
+EFIAPI
+AsmReadDr7 (
+  VOID
+  );
+
+
+/**
+  Writes a value to Debug Register 0 (DR0).
+
+  Writes and returns a new value to DR0. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr0 The value to write to Dr0.
+
+  @return The value written to Debug Register 0 (DR0).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr0 (
+  UINTN  Dr0
+  );
+
+
+/**
+  Writes a value to Debug Register 1 (DR1).
+
+  Writes and returns a new value to DR1. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr1 The value to write to Dr1.
+
+  @return The value written to Debug Register 1 (DR1).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr1 (
+  UINTN  Dr1
+  );
+
+
+/**
+  Writes a value to Debug Register 2 (DR2).
+
+  Writes and returns a new value to DR2. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr2 The value to write to Dr2.
+
+  @return The value written to Debug Register 2 (DR2).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr2 (
+  UINTN  Dr2
+  );
+
+
+/**
+  Writes a value to Debug Register 3 (DR3).
+
+  Writes and returns a new value to DR3. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr3 The value to write to Dr3.
+
+  @return The value written to Debug Register 3 (DR3).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr3 (
+  UINTN  Dr3
+  );
+
+
+/**
+  Writes a value to Debug Register 4 (DR4).
+
+  Writes and returns a new value to DR4. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr4 The value to write to Dr4.
+
+  @return The value written to Debug Register 4 (DR4).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr4 (
+  UINTN  Dr4
+  );
+
+
+/**
+  Writes a value to Debug Register 5 (DR5).
+
+  Writes and returns a new value to DR5. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr5 The value to write to Dr5.
+
+  @return The value written to Debug Register 5 (DR5).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr5 (
+  UINTN  Dr5
+  );
+
+
+/**
+  Writes a value to Debug Register 6 (DR6).
+
+  Writes and returns a new value to DR6. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr6 The value to write to Dr6.
+
+  @return The value written to Debug Register 6 (DR6).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr6 (
+  UINTN  Dr6
+  );
+
+
+/**
+  Writes a value to Debug Register 7 (DR7).
+
+  Writes and returns a new value to DR7. This function is only available on
+  IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.
+
+  @param  Dr7 The value to write to Dr7.
+
+  @return The value written to Debug Register 7 (DR7).
+
+**/
+UINTN
+EFIAPI
+AsmWriteDr7 (
+  UINTN  Dr7
+  );
+
+
+/**
+  Reads the current value of Code Segment Register (CS).
+
+  Reads and returns the current value of CS. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of CS.
+
+**/
+UINT16
+EFIAPI
+AsmReadCs (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Data Segment Register (DS).
+
+  Reads and returns the current value of DS. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of DS.
+
+**/
+UINT16
+EFIAPI
+AsmReadDs (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Extra Segment Register (ES).
+
+  Reads and returns the current value of ES. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of ES.
+
+**/
+UINT16
+EFIAPI
+AsmReadEs (
+  VOID
+  );
+
+
+/**
+  Reads the current value of FS Data Segment Register (FS).
+
+  Reads and returns the current value of FS. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of FS.
+
+**/
+UINT16
+EFIAPI
+AsmReadFs (
+  VOID
+  );
+
+
+/**
+  Reads the current value of GS Data Segment Register (GS).
+
+  Reads and returns the current value of GS. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of GS.
+
+**/
+UINT16
+EFIAPI
+AsmReadGs (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Stack Segment Register (SS).
+
+  Reads and returns the current value of SS. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of SS.
+
+**/
+UINT16
+EFIAPI
+AsmReadSs (
+  VOID
+  );
+
+
+/**
+  Reads the current value of Task Register (TR).
+
+  Reads and returns the current value of TR. This function is only available on
+  IA-32 and x64.
+
+  @return The current value of TR.
+
+**/
+UINT16
+EFIAPI
+AsmReadTr (
+  VOID
+  );
+
+
+/**
+  Reads the current Global Descriptor Table Register(GDTR) descriptor.
+
+  Reads and returns the current GDTR descriptor and returns it in Gdtr. This
+  function is only available on IA-32 and x64.
+
+  If Gdtr is NULL, then ASSERT().
+
+  @param  Gdtr  The pointer to a GDTR descriptor.
+
+**/
+VOID
+EFIAPI
+AsmReadGdtr (
+  OUT     IA32_DESCRIPTOR           *Gdtr
+  );
+
+
+/**
+  Writes the current Global Descriptor Table Register (GDTR) descriptor.
+
+  Writes and the current GDTR descriptor specified by Gdtr. This function is
+  only available on IA-32 and x64.
+
+  If Gdtr is NULL, then ASSERT().
+
+  @param  Gdtr  The pointer to a GDTR descriptor.
+
+**/
+VOID
+EFIAPI
+AsmWriteGdtr (
+  IN      CONST IA32_DESCRIPTOR     *Gdtr
+  );
+
+
+/**
+  Reads the current Interrupt Descriptor Table Register(IDTR) descriptor.
+
+  Reads and returns the current IDTR descriptor and returns it in Idtr. This
+  function is only available on IA-32 and x64.
+
+  If Idtr is NULL, then ASSERT().
+
+  @param  Idtr  The pointer to a IDTR descriptor.
+
+**/
+VOID
+EFIAPI
+AsmReadIdtr (
+  OUT     IA32_DESCRIPTOR           *Idtr
+  );
+
+
+/**
+  Writes the current Interrupt Descriptor Table Register(IDTR) descriptor.
+
+  Writes the current IDTR descriptor and returns it in Idtr. This function is
+  only available on IA-32 and x64.
+
+  If Idtr is NULL, then ASSERT().
+
+  @param  Idtr  The pointer to a IDTR descriptor.
+
+**/
+VOID
+EFIAPI
+AsmWriteIdtr (
+  IN      CONST IA32_DESCRIPTOR     *Idtr
+  );
+
+
+/**
+  Reads the current Local Descriptor Table Register(LDTR) selector.
+
+  Reads and returns the current 16-bit LDTR descriptor value. This function is
+  only available on IA-32 and x64.
+
+  @return The current selector of LDT.
+
+**/
+UINT16
+EFIAPI
+AsmReadLdtr (
+  VOID
+  );
+
+
+/**
+  Writes the current Local Descriptor Table Register (LDTR) selector.
+
+  Writes and the current LDTR descriptor specified by Ldtr. This function is
+  only available on IA-32 and x64.
+
+  @param  Ldtr  16-bit LDTR selector value.
+
+**/
+VOID
+EFIAPI
+AsmWriteLdtr (
+  IN      UINT16                    Ldtr
+  );
+
+
+/**
+  Save the current floating point/SSE/SSE2 context to a buffer.
+
+  Saves the current floating point/SSE/SSE2 state to the buffer specified by
+  Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
+  available on IA-32 and x64.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 16-byte boundary, then ASSERT().
+
+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.
+
+**/
+VOID
+EFIAPI
+AsmFxSave (
+  OUT     IA32_FX_BUFFER            *Buffer
+  );
+
+
+/**
+  Restores the current floating point/SSE/SSE2 context from a buffer.
+
+  Restores the current floating point/SSE/SSE2 state from the buffer specified
+  by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
+  only available on IA-32 and x64.
+
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 16-byte boundary, then ASSERT().
+  If Buffer was not saved with AsmFxSave(), then ASSERT().
+
+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.
+
+**/
+VOID
+EFIAPI
+AsmFxRestore (
+  IN      CONST IA32_FX_BUFFER      *Buffer
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #0 (MM0).
+
+  Reads and returns the current value of MM0. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM0.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm0 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #1 (MM1).
+
+  Reads and returns the current value of MM1. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM1.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm1 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #2 (MM2).
+
+  Reads and returns the current value of MM2. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM2.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm2 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #3 (MM3).
+
+  Reads and returns the current value of MM3. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM3.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm3 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #4 (MM4).
+
+  Reads and returns the current value of MM4. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM4.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm4 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #5 (MM5).
+
+  Reads and returns the current value of MM5. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM5.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm5 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #6 (MM6).
+
+  Reads and returns the current value of MM6. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM6.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm6 (
+  VOID
+  );
+
+
+/**
+  Reads the current value of 64-bit MMX Register #7 (MM7).
+
+  Reads and returns the current value of MM7. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of MM7.
+
+**/
+UINT64
+EFIAPI
+AsmReadMm7 (
+  VOID
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #0 (MM0).
+
+  Writes the current value of MM0. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM0.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm0 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #1 (MM1).
+
+  Writes the current value of MM1. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM1.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm1 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #2 (MM2).
+
+  Writes the current value of MM2. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM2.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm2 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #3 (MM3).
+
+  Writes the current value of MM3. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM3.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm3 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #4 (MM4).
+
+  Writes the current value of MM4. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM4.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm4 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #5 (MM5).
+
+  Writes the current value of MM5. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM5.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm5 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #6 (MM6).
+
+  Writes the current value of MM6. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM6.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm6 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Writes the current value of 64-bit MMX Register #7 (MM7).
+
+  Writes the current value of MM7. This function is only available on IA32 and
+  x64.
+
+  @param  Value The 64-bit value to write to MM7.
+
+**/
+VOID
+EFIAPI
+AsmWriteMm7 (
+  IN      UINT64                    Value
+  );
+
+
+/**
+  Reads the current value of Time Stamp Counter (TSC).
+
+  Reads and returns the current value of TSC. This function is only available
+  on IA-32 and x64.
+
+  @return The current value of TSC
+
+**/
+UINT64
+EFIAPI
+AsmReadTsc (
+  VOID
+  );
+
+
+/**
+  Reads the current value of a Performance Counter (PMC).
+
+  Reads and returns the current value of performance counter specified by
+  Index. This function is only available on IA-32 and x64.
+
+  @param  Index The 32-bit Performance Counter index to read.
+
+  @return The value of the PMC specified by Index.
+
+**/
+UINT64
+EFIAPI
+AsmReadPmc (
+  IN      UINT32                    Index
+  );
+
+
+/**
+  Sets up a monitor buffer that is used by AsmMwait().
+
+  Executes a MONITOR instruction with the register state specified by Eax, Ecx
+  and Edx. Returns Eax. This function is only available on IA-32 and x64.
+
+  @param  Eax The value to load into EAX or RAX before executing the MONITOR
+              instruction.
+  @param  Ecx The value to load into ECX or RCX before executing the MONITOR
+              instruction.
+  @param  Edx The value to load into EDX or RDX before executing the MONITOR
+              instruction.
+
+  @return Eax
+
+**/
+UINTN
+EFIAPI
+AsmMonitor (
+  IN      UINTN                     Eax,
+  IN      UINTN                     Ecx,
+  IN      UINTN                     Edx
+  );
+
+
+/**
+  Executes an MWAIT instruction.
+
+  Executes an MWAIT instruction with the register state specified by Eax and
+  Ecx. Returns Eax. This function is only available on IA-32 and x64.
+
+  @param  Eax The value to load into EAX or RAX before executing the MONITOR
+              instruction.
+  @param  Ecx The value to load into ECX or RCX before executing the MONITOR
+              instruction.
+
+  @return Eax
+
+**/
+UINTN
+EFIAPI
+AsmMwait (
+  IN      UINTN                     Eax,
+  IN      UINTN                     Ecx
+  );
+
+
+/**
+  Executes a WBINVD instruction.
+
+  Executes a WBINVD instruction. This function is only available on IA-32 and
+  x64.
+
+**/
+VOID
+EFIAPI
+AsmWbinvd (
+  VOID
+  );
+
+
+/**
+  Executes a INVD instruction.
+
+  Executes a INVD instruction. This function is only available on IA-32 and
+  x64.
+
+**/
+VOID
+EFIAPI
+AsmInvd (
+  VOID
+  );
+
+
+/**
+  Flushes a cache line from all the instruction and data caches within the
+  coherency domain of the CPU.
+
+  Flushed the cache line specified by LinearAddress, and returns LinearAddress.
+  This function is only available on IA-32 and x64.
+
+  @param  LinearAddress The address of the cache line to flush. If the CPU is
+                        in a physical addressing mode, then LinearAddress is a
+                        physical address. If the CPU is in a virtual
+                        addressing mode, then LinearAddress is a virtual
+                        address.
+
+  @return LinearAddress.
+**/
+VOID *
+EFIAPI
+AsmFlushCacheLine (
+  IN      VOID                      *LinearAddress
+  );
+
+
+/**
+  Enables the 32-bit paging mode on the CPU.
+
+  Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables
+  must be properly initialized prior to calling this service. This function
+  assumes the current execution mode is 32-bit protected mode. This function is
+  only available on IA-32. After the 32-bit paging mode is enabled, control is
+  transferred to the function specified by EntryPoint using the new stack
+  specified by NewStack and passing in the parameters specified by Context1 and
+  Context2. Context1 and Context2 are optional and may be NULL. The function
+  EntryPoint must never return.
+
+  If the current execution mode is not 32-bit protected mode, then ASSERT().
+  If EntryPoint is NULL, then ASSERT().
+  If NewStack is NULL, then ASSERT().
+
+  There are a number of constraints that must be followed before calling this
+  function:
+  1)  Interrupts must be disabled.
+  2)  The caller must be in 32-bit protected mode with flat descriptors. This
+      means all descriptors must have a base of 0 and a limit of 4GB.
+  3)  CR0 and CR4 must be compatible with 32-bit protected mode with flat
+      descriptors.
+  4)  CR3 must point to valid page tables that will be used once the transition
+      is complete, and those page tables must guarantee that the pages for this
+      function and the stack are identity mapped.
+
+  @param  EntryPoint  A pointer to function to call with the new stack after
+                      paging is enabled.
+  @param  Context1    A pointer to the context to pass into the EntryPoint
+                      function as the first parameter after paging is enabled.
+  @param  Context2    A pointer to the context to pass into the EntryPoint
+                      function as the second parameter after paging is enabled.
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint
+                      function after paging is enabled.
+
+**/
+VOID
+EFIAPI
+AsmEnablePaging32 (
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
+  IN      VOID                      *Context1,  OPTIONAL
+  IN      VOID                      *Context2,  OPTIONAL
+  IN      VOID                      *NewStack
+  );
+
+
+/**
+  Disables the 32-bit paging mode on the CPU.
+
+  Disables the 32-bit paging mode on the CPU and returns to 32-bit protected
+  mode. This function assumes the current execution mode is 32-paged protected
+  mode. This function is only available on IA-32. After the 32-bit paging mode
+  is disabled, control is transferred to the function specified by EntryPoint
+  using the new stack specified by NewStack and passing in the parameters
+  specified by Context1 and Context2. Context1 and Context2 are optional and
+  may be NULL. The function EntryPoint must never return.
+
+  If the current execution mode is not 32-bit paged mode, then ASSERT().
+  If EntryPoint is NULL, then ASSERT().
+  If NewStack is NULL, then ASSERT().
+
+  There are a number of constraints that must be followed before calling this
+  function:
+  1)  Interrupts must be disabled.
+  2)  The caller must be in 32-bit paged mode.
+  3)  CR0, CR3, and CR4 must be compatible with 32-bit paged mode.
+  4)  CR3 must point to valid page tables that guarantee that the pages for
+      this function and the stack are identity mapped.
+
+  @param  EntryPoint  A pointer to function to call with the new stack after
+                      paging is disabled.
+  @param  Context1    A pointer to the context to pass into the EntryPoint
+                      function as the first parameter after paging is disabled.
+  @param  Context2    A pointer to the context to pass into the EntryPoint
+                      function as the second parameter after paging is
+                      disabled.
+  @param  NewStack    A pointer to the new stack to use for the EntryPoint
+                      function after paging is disabled.
+
+**/
+VOID
+EFIAPI
+AsmDisablePaging32 (
+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
+  IN      VOID                      *Context1,  OPTIONAL
+  IN      VOID                      *Context2,  OPTIONAL
+  IN      VOID                      *NewStack
+  );
+
+
+/**
+  Enables the 64-bit paging mode on the CPU.
+
+  Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables
+  must be properly initialized prior to calling this service. This function
+  assumes the current execution mode is 32-bit protected mode with flat
+  descriptors. This function is only available on IA-32. After the 64-bit
+  paging mode is enabled, control is transferred to the function specified by
+  EntryPoint using the new stack specified by NewStack and passing in the
+  parameters specified by Context1 and Context2. Context1 and Context2 are
+  optional and may be 0. The function EntryPoint must never return.
+
+  If the current execution mode is not 32-bit protected mode with flat
+  descriptors, then ASSERT().
+  If EntryPoint is 0, then ASSERT().
+  If NewStack is 0, then ASSERT().
+
+  @param  Cs          The 16-bit selector to load in the CS before EntryPoint
+                      is called. The descriptor in the GDT that this selector
+                      references must be setup for long mode.
+  @param  EntryPoint  The 64-bit virtual address of the function to call with
+                      the new stack after paging is enabled.
+  @param  Context1    The 64-bit virtual address of the context to pass into
+                      the EntryPoint function as the first parameter after
+                      paging is enabled.
+  @param  Context2    The 64-bit virtual address of the context to pass into
+                      the EntryPoint function as the second parameter after
+                      paging is enabled.
+  @param  NewStack    The 64-bit virtual address of the new stack to use for
+                      the EntryPoint function after paging is enabled.
+
+**/
+VOID
+EFIAPI
+AsmEnablePaging64 (
+  IN      UINT16                    Cs,
+  IN      UINT64                    EntryPoint,
+  IN      UINT64                    Context1,  OPTIONAL
+  IN      UINT64                    Context2,  OPTIONAL
+  IN      UINT64                    NewStack
+  );
+
+
+/**
+  Disables the 64-bit paging mode on the CPU.
+
+  Disables the 64-bit paging mode on the CPU and returns to 32-bit protected
+  mode. This function assumes the current execution mode is 64-paging mode.
+  This function is only available on x64. After the 64-bit paging mode is
+  disabled, control is transferred to the function specified by EntryPoint
+  using the new stack specified by NewStack and passing in the parameters
+  specified by Context1 and Context2. Context1 and Context2 are optional and
+  may be 0. The function EntryPoint must never return.
+
+  If the current execution mode is not 64-bit paged mode, then ASSERT().
+  If EntryPoint is 0, then ASSERT().
+  If NewStack is 0, then ASSERT().
+
+  @param  Cs          The 16-bit selector to load in the CS before EntryPoint
+                      is called. The descriptor in the GDT that this selector
+                      references must be setup for 32-bit protected mode.
+  @param  EntryPoint  The 64-bit virtual address of the function to call with
+                      the new stack after paging is disabled.
+  @param  Context1    The 64-bit virtual address of the context to pass into
+                      the EntryPoint function as the first parameter after
+                      paging is disabled.
+  @param  Context2    The 64-bit virtual address of the context to pass into
+                      the EntryPoint function as the second parameter after
+                      paging is disabled.
+  @param  NewStack    The 64-bit virtual address of the new stack to use for
+                      the EntryPoint function after paging is disabled.
+
+**/
+VOID
+EFIAPI
+AsmDisablePaging64 (
+  IN      UINT16                    Cs,
+  IN      UINT32                    EntryPoint,
+  IN      UINT32                    Context1,  OPTIONAL
+  IN      UINT32                    Context2,  OPTIONAL
+  IN      UINT32                    NewStack
+  );
+
+
+//
+// 16-bit thunking services
+//
+
+/**
+  Retrieves the properties for 16-bit thunk functions.
+
+  Computes the size of the buffer and stack below 1MB required to use the
+  AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This
+  buffer size is returned in RealModeBufferSize, and the stack size is returned
+  in ExtraStackSize. If parameters are passed to the 16-bit real mode code,
+  then the actual minimum stack size is ExtraStackSize plus the maximum number
+  of bytes that need to be passed to the 16-bit real mode code.
+  
+  If RealModeBufferSize is NULL, then ASSERT().
+  If ExtraStackSize is NULL, then ASSERT().
+
+  @param  RealModeBufferSize  A pointer to the size of the buffer below 1MB
+                              required to use the 16-bit thunk functions.
+  @param  ExtraStackSize      A pointer to the extra size of stack below 1MB
+                              that the 16-bit thunk functions require for
+                              temporary storage in the transition to and from
+                              16-bit real mode.
+
+**/
+VOID
+EFIAPI
+AsmGetThunk16Properties (
+  OUT     UINT32                    *RealModeBufferSize,
+  OUT     UINT32                    *ExtraStackSize
+  );
+
+
+/**
+  Prepares all structures a code required to use AsmThunk16().
+
+  Prepares all structures and code required to use AsmThunk16().
+  
+  This interface is limited to be used in either physical mode or virtual modes with paging enabled where the
+  virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1.
+
+  If ThunkContext is NULL, then ASSERT().
+
+  @param  ThunkContext  A pointer to the context structure that describes the
+                        16-bit real mode code to call.
+
+**/
+VOID
+EFIAPI
+AsmPrepareThunk16 (
+  IN OUT  THUNK_CONTEXT             *ThunkContext
+  );
+
+
+/**
+  Transfers control to a 16-bit real mode entry point and returns the results.
+
+  Transfers control to a 16-bit real mode entry point and returns the results.
+  AsmPrepareThunk16() must be called with ThunkContext before this function is used.
+  This function must be called with interrupts disabled.
+
+  The register state from the RealModeState field of ThunkContext is restored just prior 
+  to calling the 16-bit real mode entry point.  This includes the EFLAGS field of RealModeState, 
+  which is used to set the interrupt state when a 16-bit real mode entry point is called.
+  Control is transferred to the 16-bit real mode entry point specified by the CS and Eip fields of RealModeState.
+  The stack is initialized to the SS and ESP fields of RealModeState.  Any parameters passed to 
+  the 16-bit real mode code must be populated by the caller at SS:ESP prior to calling this function.  
+  The 16-bit real mode entry point is invoked with a 16-bit CALL FAR instruction,
+  so when accessing stack contents, the 16-bit real mode code must account for the 16-bit segment 
+  and 16-bit offset of the return address that were pushed onto the stack. The 16-bit real mode entry 
+  point must exit with a RETF instruction. The register state is captured into RealModeState immediately 
+  after the RETF instruction is executed.
+  
+  If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts, 
+  or any of the 16-bit real mode code makes a SW interrupt, then the caller is responsible for making sure 
+  the IDT at address 0 is initialized to handle any HW or SW interrupts that may occur while in 16-bit real mode. 
+  
+  If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts, 
+  then the caller is responsible for making sure the 8259 PIC is in a state compatible with 16-bit real mode.  
+  This includes the base vectors, the interrupt masks, and the edge/level trigger mode.
+  
+  If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the ThunkAttributes field of ThunkContext, then the user code 
+  is invoked in big real mode.  Otherwise, the user code is invoked in 16-bit real mode with 64KB segment limits.
+  
+  If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in 
+  ThunkAttributes, then it is assumed that the user code did not enable the A20 mask, and no attempt is made to 
+  disable the A20 mask.
+  
+  If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear in 
+  ThunkAttributes, then attempt to use the INT 15 service to disable the A20 mask.  If this INT 15 call fails, 
+  then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports.
+  
+  If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in 
+  ThunkAttributes, then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports.
+    
+  If ThunkContext is NULL, then ASSERT().
+  If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().
+  If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in 
+  ThunkAttributes, then ASSERT().
+
+  This interface is limited to be used in either physical mode or virtual modes with paging enabled where the
+  virtual to physical mappings for ThunkContext.RealModeBuffer are mapped 1:1.
+
+  @param  ThunkContext  A pointer to the context structure that describes the
+                        16-bit real mode code to call.
+
+**/
+VOID
+EFIAPI
+AsmThunk16 (
+  IN OUT  THUNK_CONTEXT             *ThunkContext
+  );
+
+
+/**
+  Prepares all structures and code for a 16-bit real mode thunk, transfers
+  control to a 16-bit real mode entry point, and returns the results.
+
+  Prepares all structures and code for a 16-bit real mode thunk, transfers
+  control to a 16-bit real mode entry point, and returns the results. If the
+  caller only need to perform a single 16-bit real mode thunk, then this
+  service should be used. If the caller intends to make more than one 16-bit
+  real mode thunk, then it is more efficient if AsmPrepareThunk16() is called
+  once and AsmThunk16() can be called for each 16-bit real mode thunk.
+
+  This interface is limited to be used in either physical mode or virtual modes with paging enabled where the
+  virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1.
+
+  See AsmPrepareThunk16() and AsmThunk16() for the detailed description and ASSERT() conditions.
+
+  @param  ThunkContext  A pointer to the context structure that describes the
+                        16-bit real mode code to call.
+
+**/
+VOID
+EFIAPI
+AsmPrepareAndThunk16 (
+  IN OUT  THUNK_CONTEXT             *ThunkContext
+  );
+
+/**
+  Generates a 16-bit random number through RDRAND instruction.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out]  Rand     Buffer pointer to store the random result.
+
+  @retval TRUE          RDRAND call was successful.
+  @retval FALSE         Failed attempts to call RDRAND.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdRand16 (
+  OUT     UINT16                    *Rand
+  );
+
+/**
+  Generates a 32-bit random number through RDRAND instruction.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out]  Rand     Buffer pointer to store the random result.
+
+  @retval TRUE          RDRAND call was successful.
+  @retval FALSE         Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdRand32 (
+  OUT     UINT32                    *Rand
+  );
+
+/**
+  Generates a 64-bit random number through RDRAND instruction.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out]  Rand     Buffer pointer to store the random result.
+
+  @retval TRUE          RDRAND call was successful.
+  @retval FALSE         Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdRand64  (
+  OUT     UINT64                    *Rand
+  );
+
+#endif
+#endif
+
+
diff --git a/sys/contrib/edk2/Include/Library/BaseMemoryLib.h b/sys/contrib/edk2/Include/Library/BaseMemoryLib.h
new file mode 100644
index 0000000000..31a403c56a
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/BaseMemoryLib.h
@@ -0,0 +1,489 @@
+/** @file
+  Provides copy memory, fill memory, zero memory, and GUID functions.
+   
+  The Base Memory Library provides optimized implementations for common memory-based operations. 
+  These functions should be used in place of coding your own loops to do equivalent common functions. 
+  This allows optimized library implementations to help increase performance. 
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __BASE_MEMORY_LIB__
+#define __BASE_MEMORY_LIB__
+
+/**
+  Copies a source buffer to a destination buffer, and returns the destination buffer.
+
+  This function copies Length bytes from SourceBuffer to DestinationBuffer, and returns
+  DestinationBuffer.  The implementation must be reentrant, and it must handle the case
+  where SourceBuffer overlaps DestinationBuffer.
+  
+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+  @param  DestinationBuffer   The pointer to the destination buffer of the memory copy.
+  @param  SourceBuffer        The pointer to the source buffer of the memory copy.
+  @param  Length              The number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+  @return DestinationBuffer.
+
+**/
+VOID *
+EFIAPI
+CopyMem (
+  OUT VOID       *DestinationBuffer,
+  IN CONST VOID  *SourceBuffer,
+  IN UINTN       Length
+  );
+
+/**
+  Fills a target buffer with a byte value, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with Value, and returns Buffer.
+  
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer    The memory to set.
+  @param  Length    The number of bytes to set.
+  @param  Value     The value with which to fill Length bytes of Buffer.
+
+  @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem (
+  OUT VOID  *Buffer,
+  IN UINTN  Length,
+  IN UINT8  Value
+  );
+
+/**
+  Fills a target buffer with a 16-bit value, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with the 16-bit value specified by
+  Value, and returns Buffer. Value is repeated every 16-bits in for Length
+  bytes of Buffer.
+
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Buffer  The pointer to the target buffer to fill.
+  @param  Length  The number of bytes in Buffer to fill.
+  @param  Value   The value with which to fill Length bytes of Buffer.
+
+  @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem16 (
+  OUT VOID   *Buffer,
+  IN UINTN   Length,
+  IN UINT16  Value
+  );
+
+/**
+  Fills a target buffer with a 32-bit value, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with the 32-bit value specified by
+  Value, and returns Buffer. Value is repeated every 32-bits in for Length
+  bytes of Buffer.
+
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Buffer  The pointer to the target buffer to fill.
+  @param  Length  The number of bytes in Buffer to fill.
+  @param  Value   The value with which to fill Length bytes of Buffer.
+
+  @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem32 (
+  OUT VOID   *Buffer,
+  IN UINTN   Length,
+  IN UINT32  Value
+  );
+
+/**
+  Fills a target buffer with a 64-bit value, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with the 64-bit value specified by
+  Value, and returns Buffer. Value is repeated every 64-bits in for Length
+  bytes of Buffer.
+
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is not aligned on a 64-bit boundary, then ASSERT().
+
+  @param  Buffer  The pointer to the target buffer to fill.
+  @param  Length  The number of bytes in Buffer to fill.
+  @param  Value   The value with which to fill Length bytes of Buffer.
+
+  @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMem64 (
+  OUT VOID   *Buffer,
+  IN UINTN   Length,
+  IN UINT64  Value
+  );
+
+/**
+  Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with the UINTN sized value specified by
+  Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+  bytes of Buffer.
+
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+  If Buffer is not aligned on a UINTN boundary, then ASSERT().
+  If Length is not aligned on a UINTN boundary, then ASSERT().
+
+  @param  Buffer  The pointer to the target buffer to fill.
+  @param  Length  The number of bytes in Buffer to fill.
+  @param  Value   The value with which to fill Length bytes of Buffer.
+
+  @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+  OUT VOID  *Buffer,
+  IN UINTN  Length,
+  IN UINTN  Value
+  );
+
+/**
+  Fills a target buffer with zeros, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with zeros, and returns Buffer.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the target buffer to fill with zeros.
+  @param  Length      The number of bytes in Buffer to fill with zeros.
+
+  @return Buffer.
+
+**/
+VOID *
+EFIAPI
+ZeroMem (
+  OUT VOID  *Buffer,
+  IN UINTN  Length
+  );
+
+/**
+  Compares the contents of two buffers.
+
+  This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.
+  If all Length bytes of the two buffers are identical, then 0 is returned.  Otherwise, the
+  value returned is the first mismatched byte in SourceBuffer subtracted from the first
+  mismatched byte in DestinationBuffer.
+  
+  If Length > 0 and DestinationBuffer is NULL, then ASSERT().
+  If Length > 0 and SourceBuffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - DestinationBuffer + 1), then ASSERT().
+  If Length is greater than (MAX_ADDRESS - SourceBuffer + 1), then ASSERT().
+
+  @param  DestinationBuffer The pointer to the destination buffer to compare.
+  @param  SourceBuffer      The pointer to the source buffer to compare.
+  @param  Length            The number of bytes to compare.
+
+  @return 0                 All Length bytes of the two buffers are identical.
+  @retval Non-zero          The first mismatched byte in SourceBuffer subtracted from the first
+                            mismatched byte in DestinationBuffer.
+                            
+**/
+INTN
+EFIAPI
+CompareMem (
+  IN CONST VOID  *DestinationBuffer,
+  IN CONST VOID  *SourceBuffer,
+  IN UINTN       Length
+  );
+
+/**
+  Scans a target buffer for an 8-bit value, and returns a pointer to the matching 8-bit value
+  in the target buffer.
+
+  This function searches target the buffer specified by Buffer and Length from the lowest
+  address to the highest address for an 8-bit value that matches Value.  If a match is found,
+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,
+  then NULL is returned.  If Length is 0, then NULL is returned.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the target buffer to scan.
+  @param  Length      The number of bytes in Buffer to scan.
+  @param  Value       The value to search for in the target buffer.
+
+  @return A pointer to the matching byte in the target buffer, otherwise NULL.
+
+**/
+VOID *
+EFIAPI
+ScanMem8 (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length,
+  IN UINT8       Value
+  );
+
+/**
+  Scans a target buffer for a 16-bit value, and returns a pointer to the matching 16-bit value
+  in the target buffer.
+
+  This function searches target the buffer specified by Buffer and Length from the lowest
+  address to the highest address for a 16-bit value that matches Value.  If a match is found,
+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,
+  then NULL is returned.  If Length is 0, then NULL is returned.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is not aligned on a 16-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the target buffer to scan.
+  @param  Length      The number of bytes in Buffer to scan.
+  @param  Value       The value to search for in the target buffer.
+
+  @return A pointer to the matching byte in the target buffer, otherwise NULL.
+
+**/
+VOID *
+EFIAPI
+ScanMem16 (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length,
+  IN UINT16      Value
+  );
+
+/**
+  Scans a target buffer for a 32-bit value, and returns a pointer to the matching 32-bit value
+  in the target buffer.
+
+  This function searches target the buffer specified by Buffer and Length from the lowest
+  address to the highest address for a 32-bit value that matches Value.  If a match is found,
+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,
+  then NULL is returned.  If Length is 0, then NULL is returned.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the target buffer to scan.
+  @param  Length      The number of bytes in Buffer to scan.
+  @param  Value       The value to search for in the target buffer.
+
+  @return A pointer to the matching byte in the target buffer, otherwise NULL.
+
+**/
+VOID *
+EFIAPI
+ScanMem32 (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length,
+  IN UINT32      Value
+  );
+
+/**
+  Scans a target buffer for a 64-bit value, and returns a pointer to the matching 64-bit value
+  in the target buffer.
+
+  This function searches target the buffer specified by Buffer and Length from the lowest
+  address to the highest address for a 64-bit value that matches Value.  If a match is found,
+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,
+  then NULL is returned.  If Length is 0, then NULL is returned.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is not aligned on a 64-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the target buffer to scan.
+  @param  Length      The number of bytes in Buffer to scan.
+  @param  Value       The value to search for in the target buffer.
+
+  @return A pointer to the matching byte in the target buffer, otherwise NULL.
+
+**/
+VOID *
+EFIAPI
+ScanMem64 (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length,
+  IN UINT64      Value
+  );
+
+/**
+  Scans a target buffer for a UINTN sized value, and returns a pointer to the matching 
+  UINTN sized value in the target buffer.
+
+  This function searches target the buffer specified by Buffer and Length from the lowest
+  address to the highest address for a UINTN sized value that matches Value.  If a match is found,
+  then a pointer to the matching byte in the target buffer is returned.  If no match is found,
+  then NULL is returned.  If Length is 0, then NULL is returned.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a UINTN boundary, then ASSERT().
+  If Length is not aligned on a UINTN boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the target buffer to scan.
+  @param  Length      The number of bytes in Buffer to scan.
+  @param  Value       The value to search for in the target buffer.
+
+  @return A pointer to the matching byte in the target buffer, otherwise NULL.
+
+**/
+VOID *
+EFIAPI
+ScanMemN (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length,
+  IN UINTN       Value
+  );
+  
+/**
+  Copies a source GUID to a destination GUID.
+
+  This function copies the contents of the 128-bit GUID specified by SourceGuid to
+  DestinationGuid, and returns DestinationGuid.
+  
+  If DestinationGuid is NULL, then ASSERT().
+  If SourceGuid is NULL, then ASSERT().
+
+  @param  DestinationGuid   The pointer to the destination GUID.
+  @param  SourceGuid        The pointer to the source GUID.
+
+  @return DestinationGuid.
+
+**/
+GUID *
+EFIAPI
+CopyGuid (
+  OUT GUID       *DestinationGuid,
+  IN CONST GUID  *SourceGuid
+  );
+
+/**
+  Compares two GUIDs.
+
+  This function compares Guid1 to Guid2.  If the GUIDs are identical then TRUE is returned.
+  If there are any bit differences in the two GUIDs, then FALSE is returned.
+  
+  If Guid1 is NULL, then ASSERT().
+  If Guid2 is NULL, then ASSERT().
+
+  @param  Guid1       A pointer to a 128 bit GUID.
+  @param  Guid2       A pointer to a 128 bit GUID.
+
+  @retval TRUE        Guid1 and Guid2 are identical.
+  @retval FALSE       Guid1 and Guid2 are not identical.
+
+**/
+BOOLEAN
+EFIAPI
+CompareGuid (
+  IN CONST GUID  *Guid1,
+  IN CONST GUID  *Guid2
+  );
+
+/**
+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+  in the target buffer.
+
+  This function searches target the buffer specified by Buffer and Length from
+  the lowest address to the highest address at 128-bit increments for the 128-bit
+  GUID value that matches Guid.  If a match is found, then a pointer to the matching
+  GUID in the target buffer is returned.  If no match is found, then NULL is returned.
+  If Length is 0, then NULL is returned.
+  
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+  If Length is not aligned on a 128-bit boundary, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer  The pointer to the target buffer to scan.
+  @param  Length  The number of bytes in Buffer to scan.
+  @param  Guid    The value to search for in the target buffer.
+
+  @return A pointer to the matching Guid in the target buffer, otherwise NULL.
+
+**/
+VOID *
+EFIAPI
+ScanGuid (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length,
+  IN CONST GUID  *Guid
+  );
+
+/**
+  Checks if the given GUID is a zero GUID.
+
+  This function checks whether the given GUID is a zero GUID. If the GUID is
+  identical to a zero GUID then TRUE is returned. Otherwise, FALSE is returned.
+
+  If Guid is NULL, then ASSERT().
+
+  @param  Guid        The pointer to a 128 bit GUID.
+
+  @retval TRUE        Guid is a zero GUID.
+  @retval FALSE       Guid is not a zero GUID.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroGuid (
+  IN CONST GUID  *Guid
+  );
+
+/**
+  Checks if the contents of a buffer are all zeros.
+
+  This function checks whether the contents of a buffer are all zeros. If the
+  contents are all zeros, return TRUE. Otherwise, return FALSE.
+
+  If Length > 0 and Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+  @param  Buffer      The pointer to the buffer to be checked.
+  @param  Length      The size of the buffer (in bytes) to be checked.
+
+  @retval TRUE        Contents of the buffer are all zeros.
+  @retval FALSE       Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroBuffer (
+  IN CONST VOID  *Buffer,
+  IN UINTN       Length
+  );
+
+#endif
diff --git a/sys/contrib/edk2/Include/Library/DebugLib.h b/sys/contrib/edk2/Include/Library/DebugLib.h
new file mode 100644
index 0000000000..a26b635a22
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/DebugLib.h
@@ -0,0 +1,529 @@
+/** @file
+  Provides services to print debug and assert messages to a debug output device.
+  
+  The Debug library supports debug print and asserts based on a combination of macros and code.
+  The debug library can be turned on and off so that the debug code does not increase the size of an image.
+
+  Note that a reserved macro named MDEPKG_NDEBUG is introduced for the intention
+  of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is
+  defined, then debug and assert related macros wrapped by it are the NULL implementations.
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEBUG_LIB_H__
+#define __DEBUG_LIB_H__
+
+//
+// Declare bits for PcdDebugPropertyMask
+//
+#define DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED       0x01
+#define DEBUG_PROPERTY_DEBUG_PRINT_ENABLED        0x02
+#define DEBUG_PROPERTY_DEBUG_CODE_ENABLED         0x04
+#define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED       0x08
+#define DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED  0x10
+#define DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED    0x20
+
+//
+// Declare bits for PcdDebugPrintErrorLevel and the ErrorLevel parameter of DebugPrint()
+//
+#define DEBUG_INIT      0x00000001  // Initialization
+#define DEBUG_WARN      0x00000002  // Warnings
+#define DEBUG_LOAD      0x00000004  // Load events
+#define DEBUG_FS        0x00000008  // EFI File system
+#define DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+#define DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+#define DEBUG_INFO      0x00000040  // Informational debug messages
+#define DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+#define DEBUG_VARIABLE  0x00000100  // Variable
+#define DEBUG_BM        0x00000400  // Boot Manager
+#define DEBUG_BLKIO     0x00001000  // BlkIo Driver
+#define DEBUG_NET       0x00004000  // Network Io Driver
+#define DEBUG_UNDI      0x00010000  // UNDI Driver
+#define DEBUG_LOADFILE  0x00020000  // LoadFile
+#define DEBUG_EVENT     0x00080000  // Event messages
+#define DEBUG_GCD       0x00100000  // Global Coherency Database changes
+#define DEBUG_CACHE     0x00200000  // Memory range cachability changes
+#define DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+                                    // significantly impact boot performance
+#define DEBUG_ERROR     0x80000000  // Error
+
+//
+// Aliases of debug message mask bits
+//
+#define EFI_D_INIT      DEBUG_INIT
+#define EFI_D_WARN      DEBUG_WARN
+#define EFI_D_LOAD      DEBUG_LOAD
+#define EFI_D_FS        DEBUG_FS
+#define EFI_D_POOL      DEBUG_POOL
+#define EFI_D_PAGE      DEBUG_PAGE
+#define EFI_D_INFO      DEBUG_INFO
+#define EFI_D_DISPATCH  DEBUG_DISPATCH
+#define EFI_D_VARIABLE  DEBUG_VARIABLE
+#define EFI_D_BM        DEBUG_BM
+#define EFI_D_BLKIO     DEBUG_BLKIO
+#define EFI_D_NET       DEBUG_NET
+#define EFI_D_UNDI      DEBUG_UNDI
+#define EFI_D_LOADFILE  DEBUG_LOADFILE
+#define EFI_D_EVENT     DEBUG_EVENT
+#define EFI_D_VERBOSE   DEBUG_VERBOSE
+#define EFI_D_ERROR     DEBUG_ERROR
+
+/**
+  Prints a debug message to the debug output device if the specified error level is enabled.
+
+  If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 
+  GetDebugPrintErrorLevel (), then print the message specified by Format and the 
+  associated variable argument list to the debug output device.
+
+  If Format is NULL, then ASSERT().
+
+  @param  ErrorLevel  The error level of the debug message.
+  @param  Format      The format string for the debug message to print.
+  @param  ...         The variable argument list whose contents are accessed 
+                      based on the format string specified by Format.
+
+**/
+VOID
+EFIAPI
+DebugPrint (
+  IN  UINTN        ErrorLevel,
+  IN  CONST CHAR8  *Format,
+  ...
+  );
+
+
+/**
+  Prints an assert message containing a filename, line number, and description.  
+  This may be followed by a breakpoint or a dead loop.
+
+  Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
+  to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of 
+  PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if 
+  DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then 
+  CpuDeadLoop() is called.  If neither of these bits are set, then this function 
+  returns immediately after the message is printed to the debug output device.
+  DebugAssert() must actively prevent recursion.  If DebugAssert() is called while
+  processing another DebugAssert(), then DebugAssert() must return immediately.
+
+  If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
+  If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
+
+  @param  FileName     The pointer to the name of the source file that generated the assert condition.
+  @param  LineNumber   The line number in the source file that generated the assert condition
+  @param  Description  The pointer to the description of the assert condition.
+
+**/
+VOID
+EFIAPI
+DebugAssert (
+  IN CONST CHAR8  *FileName,
+  IN UINTN        LineNumber,
+  IN CONST CHAR8  *Description
+  );
+
+
+/**
+  Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
+
+  This function fills Length bytes of Buffer with the value specified by 
+  PcdDebugClearMemoryValue, and returns Buffer.
+
+  If Buffer is NULL, then ASSERT().
+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 
+
+  @param   Buffer  The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
+  @param   Length  The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. 
+
+  @return  Buffer  The pointer to the target buffer filled with PcdDebugClearMemoryValue.
+
+**/
+VOID *
+EFIAPI
+DebugClearMemory (
+  OUT VOID  *Buffer,
+  IN UINTN  Length
+  );
+
+
+/**
+  Returns TRUE if ASSERT() macros are enabled.
+
+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of 
+  PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
+
+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugAssertEnabled (
+  VOID
+  );
+
+
+/**  
+  Returns TRUE if DEBUG() macros are enabled.
+
+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of 
+  PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
+
+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintEnabled (
+  VOID
+  );
+
+
+/**  
+  Returns TRUE if DEBUG_CODE() macros are enabled.
+
+  This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of 
+  PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
+
+  @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
+  @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugCodeEnabled (
+  VOID
+  );
+
+
+/**  
+  Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
+
+  This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of 
+  PcdDebugProperyMask is set.  Otherwise, FALSE is returned.
+
+  @retval  TRUE    The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
+  @retval  FALSE   The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+
+**/
+BOOLEAN
+EFIAPI
+DebugClearMemoryEnabled (
+  VOID
+  );
+
+/**
+  Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
+
+  This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
+
+  @retval  TRUE    Current ErrorLevel is supported.
+  @retval  FALSE   Current ErrorLevel is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+DebugPrintLevelEnabled (
+  IN  CONST UINTN        ErrorLevel
+  );
+
+/**  
+  Internal worker macro that calls DebugAssert().
+
+  This macro calls DebugAssert(), passing in the filename, line number, and an
+  expression that evaluated to FALSE.
+
+  @param  Expression  Boolean expression that evaluated to FALSE
+
+**/
+#define _ASSERT(Expression)  DebugAssert (__FILE__, __LINE__, #Expression)
+
+
+/**  
+  Internal worker macro that calls DebugPrint().
+
+  This macro calls DebugPrint() passing in the debug error level, a format 
+  string, and a variable argument list.
+  __VA_ARGS__ is not supported by EBC compiler, Microsoft Visual Studio .NET 2003
+  and Microsoft Windows Server 2003 Driver Development Kit (Microsoft WINDDK) version 3790.1830.
+
+  @param  Expression  Expression containing an error level, a format string, 
+                      and a variable argument list based on the format string.
+
+**/
+
+#if !defined(MDE_CPU_EBC) && (!defined (_MSC_VER) || _MSC_VER > 1400)
+  #define _DEBUG_PRINT(PrintLevel, ...)              \
+    do {                                             \
+      if (DebugPrintLevelEnabled (PrintLevel)) {     \
+        DebugPrint (PrintLevel, ##__VA_ARGS__);      \
+      }                                              \
+    } while (FALSE)
+  #define _DEBUG(Expression)   _DEBUG_PRINT Expression
+#else
+#define _DEBUG(Expression)   DebugPrint Expression
+#endif
+
+/**  
+  Macro that calls DebugAssert() if an expression evaluates to FALSE.
+
+  If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 
+  bit of PcdDebugProperyMask is set, then this macro evaluates the Boolean 
+  expression specified by Expression.  If Expression evaluates to FALSE, then 
+  DebugAssert() is called passing in the source filename, source line number, 
+  and Expression.
+
+  @param  Expression  Boolean expression.
+
+**/
+#if !defined(MDEPKG_NDEBUG)       
+  #define ASSERT(Expression)        \
+    do {                            \
+      if (DebugAssertEnabled ()) {  \
+        if (!(Expression)) {        \
+          _ASSERT (Expression);     \
+          ANALYZER_UNREACHABLE ();  \
+        }                           \
+      }                             \
+    } while (FALSE)
+#else
+  #define ASSERT(Expression)
+#endif
+
+/**  
+  Macro that calls DebugPrint().
+
+  If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED 
+  bit of PcdDebugProperyMask is set, then this macro passes Expression to 
+  DebugPrint().
+
+  @param  Expression  Expression containing an error level, a format string, 
+                      and a variable argument list based on the format string.
+  
+
+**/
+#if !defined(MDEPKG_NDEBUG)      
+  #define DEBUG(Expression)        \
+    do {                           \
+      if (DebugPrintEnabled ()) {  \
+        _DEBUG (Expression);       \
+      }                            \
+    } while (FALSE)
+#else
+  #define DEBUG(Expression)
+#endif
+
+/**  
+  Macro that calls DebugAssert() if an EFI_STATUS evaluates to an error code.
+
+  If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED 
+  bit of PcdDebugProperyMask is set, then this macro evaluates the EFI_STATUS 
+  value specified by StatusParameter.  If StatusParameter is an error code, 
+  then DebugAssert() is called passing in the source filename, source line 
+  number, and StatusParameter.
+
+  @param  StatusParameter  EFI_STATUS value to evaluate.
+
+**/
+#if !defined(MDEPKG_NDEBUG)
+  #define ASSERT_EFI_ERROR(StatusParameter)                                              \
+    do {                                                                                 \
+      if (DebugAssertEnabled ()) {                                                       \
+        if (EFI_ERROR (StatusParameter)) {                                               \
+          DEBUG ((EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", StatusParameter));  \
+          _ASSERT (!EFI_ERROR (StatusParameter));                                        \
+        }                                                                                \
+      }                                                                                  \
+    } while (FALSE)
+#else
+  #define ASSERT_EFI_ERROR(StatusParameter)
+#endif
+
+/**
+  Macro that calls DebugAssert() if a RETURN_STATUS evaluates to an error code.
+
+  If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED
+  bit of PcdDebugProperyMask is set, then this macro evaluates the
+  RETURN_STATUS value specified by StatusParameter.  If StatusParameter is an
+  error code, then DebugAssert() is called passing in the source filename,
+  source line number, and StatusParameter.
+
+  @param  StatusParameter  RETURN_STATUS value to evaluate.
+
+**/
+#if !defined(MDEPKG_NDEBUG)
+  #define ASSERT_RETURN_ERROR(StatusParameter)                          \
+    do {                                                                \
+      if (DebugAssertEnabled ()) {                                      \
+        if (RETURN_ERROR (StatusParameter)) {                           \
+          DEBUG ((DEBUG_ERROR, "\nASSERT_RETURN_ERROR (Status = %r)\n", \
+            StatusParameter));                                          \
+          _ASSERT (!RETURN_ERROR (StatusParameter));                    \
+        }                                                               \
+      }                                                                 \
+    } while (FALSE)
+#else
+  #define ASSERT_RETURN_ERROR(StatusParameter)
+#endif
+
+/**  
+  Macro that calls DebugAssert() if a protocol is already installed in the 
+  handle database.
+
+  If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 
+  of PcdDebugProperyMask is clear, then return.
+
+  If Handle is NULL, then a check is made to see if the protocol specified by Guid 
+  is present on any handle in the handle database.  If Handle is not NULL, then 
+  a check is made to see if the protocol specified by Guid is present on the 
+  handle specified by Handle.  If the check finds the protocol, then DebugAssert() 
+  is called passing in the source filename, source line number, and Guid.
+
+  If Guid is NULL, then ASSERT().
+
+  @param  Handle  The handle to check for the protocol.  This is an optional 
+                  parameter that may be NULL.  If it is NULL, then the entire 
+                  handle database is searched.
+
+  @param  Guid    The pointer to a protocol GUID.
+
+**/
+#if !defined(MDEPKG_NDEBUG)
+  #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)                               \
+    do {                                                                                \
+      if (DebugAssertEnabled ()) {                                                      \
+        VOID  *Instance;                                                                \
+        ASSERT (Guid != NULL);                                                          \
+        if (Handle == NULL) {                                                           \
+          if (!EFI_ERROR (gBS->LocateProtocol ((EFI_GUID *)Guid, NULL, &Instance))) {   \
+            _ASSERT (Guid already installed in database);                               \
+          }                                                                             \
+        } else {                                                                        \
+          if (!EFI_ERROR (gBS->HandleProtocol (Handle, (EFI_GUID *)Guid, &Instance))) { \
+            _ASSERT (Guid already installed on Handle);                                 \
+          }                                                                             \
+        }                                                                               \
+      }                                                                                 \
+    } while (FALSE)
+#else
+  #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)
+#endif
+
+/**
+  Macro that marks the beginning of debug source code.
+
+  If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 
+  then this macro marks the beginning of source code that is included in a module.
+  Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 
+  are not included in a module.
+
+**/
+#define DEBUG_CODE_BEGIN()  do { if (DebugCodeEnabled ()) { UINT8  __DebugCodeLocal
+
+
+/**  
+  The macro that marks the end of debug source code.
+
+  If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 
+  then this macro marks the end of source code that is included in a module.  
+  Otherwise, the source lines between DEBUG_CODE_BEGIN() and DEBUG_CODE_END() 
+  are not included in a module.
+
+**/
+#define DEBUG_CODE_END()    __DebugCodeLocal = 0; __DebugCodeLocal++; } } while (FALSE)
+
+
+/**  
+  The macro that declares a section of debug source code.
+
+  If the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set, 
+  then the source code specified by Expression is included in a module.  
+  Otherwise, the source specified by Expression is not included in a module.
+
+**/
+#define DEBUG_CODE(Expression)  \
+  DEBUG_CODE_BEGIN ();          \
+  Expression                    \
+  DEBUG_CODE_END ()
+
+
+/**  
+  The macro that calls DebugClearMemory() to clear a buffer to a default value.
+
+  If the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set, 
+  then this macro calls DebugClearMemory() passing in Address and Length.
+
+  @param  Address  The pointer to a buffer.
+  @param  Length   The number of bytes in the buffer to set.
+
+**/
+#define DEBUG_CLEAR_MEMORY(Address, Length)  \
+  do {                                       \
+    if (DebugClearMemoryEnabled ()) {        \
+      DebugClearMemory (Address, Length);    \
+    }                                        \
+  } while (FALSE)
+
+
+/**
+  Macro that calls DebugAssert() if the containing record does not have a 
+  matching signature.  If the signatures matches, then a pointer to the data 
+  structure that contains a specified field of that data structure is returned.  
+  This is a lightweight method hide information by placing a public data 
+  structure inside a larger private data structure and using a pointer to the 
+  public data structure to retrieve a pointer to the private data structure.
+
+  If MDEPKG_NDEBUG is defined or the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit 
+  of PcdDebugProperyMask is clear, then this macro computes the offset, in bytes,
+  of the field specified by Field from the beginning of the data structure specified 
+  by TYPE.  This offset is subtracted from Record, and is used to return a pointer 
+  to a data structure of the type specified by TYPE.
+
+  If MDEPKG_NDEBUG is not defined and the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit
+  of PcdDebugProperyMask is set, then this macro computes the offset, in bytes, 
+  of field specified by Field from the beginning of the data structure specified 
+  by TYPE.  This offset is subtracted from Record, and is used to compute a pointer
+  to a data structure of the type specified by TYPE.  The Signature field of the 
+  data structure specified by TYPE is compared to TestSignature.  If the signatures 
+  match, then a pointer to the pointer to a data structure of the type specified by 
+  TYPE is returned.  If the signatures do not match, then DebugAssert() is called 
+  with a description of "CR has a bad signature" and Record is returned.  
+
+  If the data type specified by TYPE does not contain the field specified by Field, 
+  then the module will not compile.
+
+  If TYPE does not contain a field called Signature, then the module will not 
+  compile.
+
+  @param  Record         The pointer to the field specified by Field within a data 
+                         structure of type TYPE.
+
+  @param  TYPE           The name of the data structure type to return  This 
+                         data structure must contain the field specified by Field. 
+
+  @param  Field          The name of the field in the data structure specified 
+                         by TYPE to which Record points.
+
+  @param  TestSignature  The 32-bit signature value to match.
+
+**/
+#if !defined(MDEPKG_NDEBUG)
+  #define CR(Record, TYPE, Field, TestSignature)                                              \
+    (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ?  \
+    (TYPE *) (_ASSERT (CR has Bad Signature), Record) :                                       \
+    BASE_CR (Record, TYPE, Field)
+#else
+  #define CR(Record, TYPE, Field, TestSignature)                                              \
+    BASE_CR (Record, TYPE, Field)
+#endif
+    
+#endif
diff --git a/sys/contrib/edk2/Include/Library/DevicePathLib.h b/sys/contrib/edk2/Include/Library/DevicePathLib.h
new file mode 100644
index 0000000000..61fa19ce69
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/DevicePathLib.h
@@ -0,0 +1,566 @@
+/** @file
+  Provides library functions to construct and parse UEFI Device Paths.
+
+  This library provides defines, macros, and functions to help create and parse 
+  EFI_DEVICE_PATH_PROTOCOL structures.
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DEVICE_PATH_LIB_H__
+#define __DEVICE_PATH_LIB_H__
+
+#define END_DEVICE_PATH_LENGTH               (sizeof (EFI_DEVICE_PATH_PROTOCOL))
+
+/**
+  Determine whether a given device path is valid.
+  If DevicePath is NULL, then ASSERT().
+
+  @param  DevicePath  A pointer to a device path data structure.
+  @param  MaxSize     The maximum size of the device path data structure.
+
+  @retval TRUE        DevicePath is valid.
+  @retval FALSE       The length of any node node in the DevicePath is less
+                      than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+  @retval FALSE       If MaxSize is not zero, the size of the DevicePath
+                      exceeds MaxSize.
+  @retval FALSE       If PcdMaximumDevicePathNodeCount is not zero, the node
+                      count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathValid (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN       UINTN                    MaxSize
+  );
+
+/**
+  Returns the Type field of a device path node.
+
+  Returns the Type field of the device path node specified by Node.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return The Type field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathType (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Returns the SubType field of a device path node.
+
+  Returns the SubType field of the device path node specified by Node.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return The SubType field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathSubType (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Returns the 16-bit Length field of a device path node.
+
+  Returns the 16-bit Length field of the device path node specified by Node.  
+  Node is not required to be aligned on a 16-bit boundary, so it is recommended
+  that a function such as ReadUnaligned16() be used to extract the contents of 
+  the Length field.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return The 16-bit Length field of the device path node specified by Node.
+
+**/
+UINTN
+EFIAPI
+DevicePathNodeLength (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Returns a pointer to the next node in a device path.
+
+  Returns a pointer to the device path node that follows the device path node specified by Node.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @return a pointer to the device path node that follows the device path node specified by Node.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+NextDevicePathNode (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Determines if a device path node is an end node of a device path.
+  This includes nodes that are the end of a device path instance and nodes that 
+  are the end of an entire device path.
+
+  Determines if the device path node specified by Node is an end node of a device path.  
+  This includes nodes that are the end of a device path instance and nodes that are the 
+  end of an entire device path.  If Node represents an end node of a device path, 
+  then TRUE is returned.  Otherwise, FALSE is returned.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @retval TRUE      The device path node specified by Node is an end node of a device path.
+  @retval FALSE     The device path node specified by Node is not an end node of a device path.
+  
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEndType (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Determines if a device path node is an end node of an entire device path.
+
+  Determines if a device path node specified by Node is an end node of an entire device path.
+  If Node represents the end of an entire device path, then TRUE is returned.
+  Otherwise, FALSE is returned.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @retval TRUE      The device path node specified by Node is the end of an entire device path.
+  @retval FALSE     The device path node specified by Node is not the end of an entire device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEnd (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Determines if a device path node is an end node of a device path instance.
+
+  Determines if a device path node specified by Node is an end node of a device path instance.
+  If Node represents the end of a device path instance, then TRUE is returned.
+  Otherwise, FALSE is returned.
+
+  If Node is NULL, then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+
+  @retval TRUE      The device path node specified by Node is the end of a device path instance.
+  @retval FALSE     The device path node specified by Node is not the end of a device path instance.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEndInstance (
+  IN CONST VOID  *Node
+  );
+
+/**
+  Sets the length, in bytes, of a device path node.
+
+  Sets the length of the device path node specified by Node to the value specified 
+  by NodeLength.  NodeLength is returned.  Node is not required to be aligned on 
+  a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
+  be used to set the contents of the Length field.
+
+  If Node is NULL, then ASSERT().
+  If NodeLength >= 0x10000, then ASSERT().
+  If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
+
+  @param  Node      A pointer to a device path node data structure.
+  @param  Length    The length, in bytes, of the device path node.
+
+  @return Length
+
+**/
+UINT16
+EFIAPI
+SetDevicePathNodeLength (
+  IN OUT VOID  *Node,
+  IN UINTN     Length
+  );
+
+/**
+  Fills in all the fields of a device path node that is the end of an entire device path.
+
+  Fills in all the fields of a device path node specified by Node so Node represents 
+  the end of an entire device path.  The Type field of Node is set to 
+  END_DEVICE_PATH_TYPE, the SubType field of Node is set to 
+  END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to 
+  END_DEVICE_PATH_LENGTH.  Node is not required to be aligned on a 16-bit boundary, 
+  so it is recommended that a function such as WriteUnaligned16() be used to set 
+  the contents of the Length field. 
+
+  If Node is NULL, then ASSERT(). 
+
+  @param  Node      A pointer to a device path node data structure.
+
+**/
+VOID
+EFIAPI
+SetDevicePathEndNode (
+  OUT VOID  *Node
+  );
+
+/**
+  Returns the size of a device path in bytes.
+
+  This function returns the size, in bytes, of the device path data structure 
+  specified by DevicePath including the end of device path node.
+  If DevicePath is NULL or invalid, then 0 is returned.
+
+  @param  DevicePath  A pointer to a device path data structure.
+
+  @retval 0           If DevicePath is NULL or invalid.
+  @retval Others      The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+GetDevicePathSize (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+/**
+  Creates a new copy of an existing device path.
+
+  This function allocates space for a new copy of the device path specified by DevicePath.  If
+  DevicePath is NULL, then NULL is returned.  If the memory is successfully allocated, then the
+  contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer
+  is returned.  Otherwise, NULL is returned.  
+  The memory for the new device path is allocated from EFI boot services memory. 
+  It is the responsibility of the caller to free the memory allocated. 
+  
+  @param  DevicePath                 A pointer to a device path data structure.
+
+  @retval NULL    DevicePath is NULL or invalid.
+  @retval Others  A pointer to the duplicated device path.
+  
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DuplicateDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+/**
+  Creates a new device path by appending a second device path to a first device path.
+
+  This function creates a new device path by appending a copy of SecondDevicePath to a copy of
+  FirstDevicePath in a newly allocated buffer.  Only the end-of-device-path device node from
+  SecondDevicePath is retained. The newly created device path is returned.  
+  If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned.  
+  If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned.  
+  If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is
+  returned.  
+  If there is not enough memory for the newly allocated buffer, then NULL is returned.
+  The memory for the new device path is allocated from EFI boot services memory. It is the
+  responsibility of the caller to free the memory allocated.
+
+  @param  FirstDevicePath            A pointer to a device path data structure.
+  @param  SecondDevicePath           A pointer to a device path data structure.
+  
+  @retval NULL      If there is not enough memory for the newly allocated buffer.
+  @retval NULL      If FirstDevicePath or SecondDevicePath is invalid.
+  @retval Others    A pointer to the new device path if success.
+                    Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,  OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath  OPTIONAL
+  );
+
+/**
+  Creates a new path by appending the device node to the device path.
+
+  This function creates a new device path by appending a copy of the device node specified by
+  DevicePathNode to a copy of the device path specified by DevicePath in an allocated buffer.
+  The end-of-device-path device node is moved after the end of the appended device node.
+  If DevicePathNode is NULL then a copy of DevicePath is returned.
+  If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device path device
+  node is returned.
+  If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path device node
+  is returned.
+  If there is not enough memory to allocate space for the new device path, then NULL is returned.  
+  The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+  free the memory allocated.
+
+  @param  DevicePath                 A pointer to a device path data structure.
+  @param  DevicePathNode             A pointer to a single device path node.
+
+  @retval NULL      There is not enough memory for the new device path.
+  @retval Others    A pointer to the new device path if success.
+                    A copy of DevicePathNode followed by an end-of-device-path node 
+                    if both FirstDevicePath and SecondDevicePath are NULL.
+                    A copy of an end-of-device-path node if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathNode (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,     OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode  OPTIONAL
+  );
+
+/**
+  Creates a new device path by appending the specified device path instance to the specified device
+  path.
+ 
+  This function creates a new device path by appending a copy of the device path instance specified
+  by DevicePathInstance to a copy of the device path secified by DevicePath in a allocated buffer.
+  The end-of-device-path device node is moved after the end of the appended device path instance
+  and a new end-of-device-path-instance node is inserted between. 
+  If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+  If DevicePathInstance is NULL, then NULL is returned.
+  If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then NULL is returned.  
+  The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+  free the memory allocated.
+  
+  @param  DevicePath                 A pointer to a device path data structure.
+  @param  DevicePathInstance         A pointer to a device path instance.
+
+  @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathInstance (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL
+  );
+
+/**
+  Creates a copy of the current device path instance and returns a pointer to the next device path
+  instance.
+
+  This function creates a copy of the current device path instance. It also updates DevicePath to
+  point to the next device path instance in the device path (or NULL if no more) and updates Size
+  to hold the size of the device path instance copy.
+  If DevicePath is NULL, then NULL is returned.
+  If DevicePath points to a invalid device path, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then NULL is returned.  
+  The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+  free the memory allocated.
+  If Size is NULL, then ASSERT().
+ 
+  @param  DevicePath                 On input, this holds the pointer to the current device path
+                                     instance. On output, this holds the pointer to the next device
+                                     path instance or NULL if there are no more device path
+                                     instances in the device path pointer to a device path data
+                                     structure.
+  @param  Size                       On output, this holds the size of the device path instance, in
+                                     bytes or zero, if DevicePath is NULL.
+
+  @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+GetNextDevicePathInstance (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
+  OUT UINTN                          *Size
+  );
+
+/**
+  Creates a device node.
+
+  This function creates a new device node in a newly allocated buffer of size NodeLength and
+  initializes the device path node header with NodeType and NodeSubType.  The new device path node
+  is returned.
+  If NodeLength is smaller than a device path header, then NULL is returned.  
+  If there is not enough memory to allocate space for the new device path, then NULL is returned.  
+  The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+  free the memory allocated.
+
+  @param  NodeType                   The device node type for the new device node.
+  @param  NodeSubType                The device node sub-type for the new device node.
+  @param  NodeLength                 The length of the new device node.
+
+  @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+CreateDeviceNode (
+  IN UINT8                           NodeType,
+  IN UINT8                           NodeSubType,
+  IN UINT16                          NodeLength
+  );
+
+/**
+  Determines if a device path is single or multi-instance.
+
+  This function returns TRUE if the device path specified by DevicePath is multi-instance.
+  Otherwise, FALSE is returned.
+  If DevicePath is NULL or invalid, then FALSE is returned.
+
+  @param  DevicePath                 A pointer to a device path data structure.
+
+  @retval  TRUE                      DevicePath is multi-instance.
+  @retval  FALSE                     DevicePath is not multi-instance, or DevicePath is NULL or invalid.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathMultiInstance (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  );
+
+/**
+  Retrieves the device path protocol from a handle.
+
+  This function returns the device path protocol from the handle specified by Handle.  If Handle is
+  NULL or Handle does not contain a device path protocol, then NULL is returned.
+ 
+  @param  Handle                     The handle from which to retrieve the device path protocol.
+
+  @return The device path protocol from the handle specified by Handle.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DevicePathFromHandle (
+  IN EFI_HANDLE                      Handle
+  );
+
+/**
+  Allocates a device path for a file and appends it to an existing device path.
+
+  If Device is a valid device handle that contains a device path protocol, then a device path for
+  the file specified by FileName  is allocated and appended to the device path associated with the
+  handle Device.  The allocated device path is returned.  If Device is NULL or Device is a handle
+  that does not support the device path protocol, then a device path containing a single device
+  path node for the file specified by FileName is allocated and returned.
+  The memory for the new device path is allocated from EFI boot services memory. It is the responsibility
+  of the caller to free the memory allocated.
+  
+  If FileName is NULL, then ASSERT().
+  If FileName is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Device                     A pointer to a device handle.  This parameter is optional and
+                                     may be NULL.
+  @param  FileName                   A pointer to a Null-terminated Unicode string.
+
+  @return The allocated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+FileDevicePath (
+  IN EFI_HANDLE                      Device,     OPTIONAL
+  IN CONST CHAR16                    *FileName
+  );
+
+/**
+  Converts a device path to its text representation.
+
+  @param DevicePath      A Pointer to the device to be converted.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+  @return A pointer to the allocated text representation of the device path or
+          NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
+  IN BOOLEAN                          DisplayOnly,
+  IN BOOLEAN                          AllowShortcuts
+  );
+
+/**
+  Converts a device node to its string representation.
+
+  @param DeviceNode        A Pointer to the device node to be converted.
+  @param DisplayOnly       If DisplayOnly is TRUE, then the shorter text representation
+                           of the display node is used, where applicable. If DisplayOnly
+                           is FALSE, then the longer text representation of the display node
+                           is used.
+  @param AllowShortcuts    If AllowShortcuts is TRUE, then the shortcut forms of text
+                           representation for a device node can be used, where applicable.
+
+  @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+          is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,
+  IN BOOLEAN                         DisplayOnly,
+  IN BOOLEAN                         AllowShortcuts
+  );
+
+/**
+  Convert text to the binary representation of a device node.
+
+  @param TextDeviceNode  TextDeviceNode points to the text representation of a device
+                         node. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+          insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDeviceNode (
+  IN CONST CHAR16 *TextDeviceNode
+  );
+
+/**
+  Convert text to the binary representation of a device path.
+
+  @param TextDevicePath  TextDevicePath points to the text representation of a device
+                         path. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+          there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDevicePath (
+  IN CONST CHAR16 *TextDevicePath
+  );
+
+#endif
diff --git a/sys/contrib/edk2/Include/Library/MemoryAllocationLib.h b/sys/contrib/edk2/Include/Library/MemoryAllocationLib.h
new file mode 100644
index 0000000000..204a8b5123
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/MemoryAllocationLib.h
@@ -0,0 +1,493 @@
+/** @file
+  Provides services to allocate and free memory buffers of various memory types and alignments.
+  
+  The Memory Allocation Library abstracts various common memory allocation operations. This library 
+  allows code to be written in a phase-independent manner because the allocation of memory in PEI, DXE, 
+  and SMM (for example) is done via a different mechanism. Using a common library interface makes it 
+  much easier to port algorithms from phase to phase. 
+  
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __MEMORY_ALLOCATION_LIB_H__
+#define __MEMORY_ALLOCATION_LIB_H__
+
+/**
+  Allocates one or more 4KB pages of type EfiBootServicesData.
+
+  Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePages (
+  IN UINTN  Pages
+  );
+
+/**
+  Allocates one or more 4KB pages of type EfiRuntimeServicesData.
+
+  Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimePages (
+  IN UINTN  Pages
+  );
+
+/**
+  Allocates one or more 4KB pages of type EfiReservedMemoryType.
+
+  Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
+  allocated buffer.  The buffer returned is aligned on a 4KB boundary.  If Pages is 0, then NULL
+  is returned.  If there is not enough memory remaining to satisfy the request, then NULL is
+  returned.
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedPages (
+  IN UINTN  Pages
+  );
+
+/**
+  Frees one or more 4KB pages that were previously allocated with one of the page allocation
+  functions in the Memory Allocation Library.
+
+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
+  must have been allocated on a previous call to the page allocation services of the Memory
+  Allocation Library.  If it is not possible to free allocated pages, then this function will
+  perform no actions.
+  
+  If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
+  then ASSERT().
+  If Pages is zero, then ASSERT().
+ 
+  @param  Buffer                Pointer to the buffer of pages to free.
+  @param  Pages                 The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreePages (
+  IN VOID   *Buffer,
+  IN UINTN  Pages
+  );
+
+/**
+  Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
+  request, then NULL is returned.
+  
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedPages (
+  IN UINTN  Pages,
+  IN UINTN  Alignment
+  );
+
+/**
+  Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
+  request, then NULL is returned.
+  
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedRuntimePages (
+  IN UINTN  Pages,
+  IN UINTN  Alignment
+  );
+
+/**
+  Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
+
+  Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
+  alignment specified by Alignment.  The allocated buffer is returned.  If Pages is 0, then NULL is
+  returned.  If there is not enough memory at the specified alignment remaining to satisfy the
+  request, then NULL is returned.
+  
+  If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+  If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
+
+  @param  Pages                 The number of 4 KB pages to allocate.
+  @param  Alignment             The requested alignment of the allocation.  Must be a power of two.
+                                If Alignment is zero, then byte alignment is used.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedReservedPages (
+  IN UINTN  Pages,
+  IN UINTN  Alignment
+  );
+
+/**
+  Frees one or more 4KB pages that were previously allocated with one of the aligned page
+  allocation functions in the Memory Allocation Library.
+
+  Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer.  Buffer
+  must have been allocated on a previous call to the aligned page allocation services of the Memory
+  Allocation Library.  If it is not possible to free allocated pages, then this function will 
+  perform no actions.
+  
+  If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
+  Library, then ASSERT().
+  If Pages is zero, then ASSERT().
+  
+  @param  Buffer                Pointer to the buffer of pages to free.
+  @param  Pages                 The number of 4 KB pages to free.
+
+**/
+VOID
+EFIAPI
+FreeAlignedPages (
+  IN VOID   *Buffer,
+  IN UINTN  Pages
+  );
+
+/**
+  Allocates a buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
+  pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePool (
+  IN UINTN  AllocationSize
+  );
+
+/**
+  Allocates a buffer of type EfiRuntimeServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
+  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimePool (
+  IN UINTN  AllocationSize
+  );
+
+/**
+  Allocates a buffer of type EfiReservedMemoryType.
+
+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
+  a pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
+  returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedPool (
+  IN UINTN  AllocationSize
+  );
+
+/**
+  Allocates and zeros a buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateZeroPool (
+  IN UINTN  AllocationSize
+  );
+
+/**
+  Allocates and zeros a buffer of type EfiRuntimeServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimeZeroPool (
+  IN UINTN  AllocationSize
+  );
+
+/**
+  Allocates and zeros a buffer of type EfiReservedMemoryType.
+
+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
+  buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
+  valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
+  request, then NULL is returned.
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedZeroPool (
+  IN UINTN  AllocationSize
+  );
+
+/**
+  Copies a buffer to an allocated buffer of type EfiBootServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+  
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateCopyPool (
+  IN UINTN       AllocationSize,
+  IN CONST VOID  *Buffer
+  );
+
+/**
+  Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
+
+  Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+  
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateRuntimeCopyPool (
+  IN UINTN       AllocationSize,
+  IN CONST VOID  *Buffer
+  );
+
+/**
+  Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
+
+  Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
+  AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
+  allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is returned.  If there
+  is not enough memory remaining to satisfy the request, then NULL is returned.
+  
+  If Buffer is NULL, then ASSERT().
+  If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 
+
+  @param  AllocationSize        The number of bytes to allocate and zero.
+  @param  Buffer                The buffer to copy to the allocated buffer.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateReservedCopyPool (
+  IN UINTN       AllocationSize,
+  IN CONST VOID  *Buffer
+  );
+
+/**
+  Reallocates a buffer of type EfiBootServicesData.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of type
+  EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and 
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and 
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.  
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not 
+  enough memory remaining to satisfy the request, then NULL is returned.
+  
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional 
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocatePool (
+  IN UINTN  OldSize,
+  IN UINTN  NewSize,
+  IN VOID   *OldBuffer  OPTIONAL
+  );
+
+/**
+  Reallocates a buffer of type EfiRuntimeServicesData.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of type
+  EfiRuntimeServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and 
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and 
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.  
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not 
+  enough memory remaining to satisfy the request, then NULL is returned.
+
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional 
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocateRuntimePool (
+  IN UINTN  OldSize,
+  IN UINTN  NewSize,
+  IN VOID   *OldBuffer  OPTIONAL
+  );
+
+/**
+  Reallocates a buffer of type EfiReservedMemoryType.
+
+  Allocates and zeros the number bytes specified by NewSize from memory of type
+  EfiReservedMemoryType.  If OldBuffer is not NULL, then the smaller of OldSize and 
+  NewSize bytes are copied from OldBuffer to the newly allocated buffer, and 
+  OldBuffer is freed.  A pointer to the newly allocated buffer is returned.  
+  If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not 
+  enough memory remaining to satisfy the request, then NULL is returned.
+
+  If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
+  is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
+
+  @param  OldSize        The size, in bytes, of OldBuffer.
+  @param  NewSize        The size, in bytes, of the buffer to reallocate.
+  @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional 
+                         parameter that may be NULL.
+
+  @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+ReallocateReservedPool (
+  IN UINTN  OldSize,
+  IN UINTN  NewSize,
+  IN VOID   *OldBuffer  OPTIONAL
+  );
+
+/**
+  Frees a buffer that was previously allocated with one of the pool allocation functions in the
+  Memory Allocation Library.
+
+  Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
+  pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
+  resources, then this function will perform no actions.
+  
+  If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
+  then ASSERT().
+
+  @param  Buffer                Pointer to the buffer to free.
+
+**/
+VOID
+EFIAPI
+FreePool (
+  IN VOID   *Buffer
+  );
+
+#endif
diff --git a/sys/contrib/edk2/Include/Library/PcdLib.h b/sys/contrib/edk2/Include/Library/PcdLib.h
new file mode 100644
index 0000000000..fdb2df87aa
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/PcdLib.h
@@ -0,0 +1,2260 @@
+/** @file
+  Provides library services to get and set Platform Configuration Database entries.
+
+  PCD Library Class provides a PCD usage macro interface for all PCD types.
+  It should be included in any module that uses PCD. If a module uses dynamic/dynamicex
+  PCD, module should be linked to a PEIM/DXE library instance to access that PCD.
+  If a module uses PatchableInModule type PCD, it also needs the library instance to produce
+  LibPatchPcdSetPtr() interface. For FeatureFlag/Fixed PCD, the macro interface is
+  translated to a variable or macro that is auto-generated by build tool in
+  module's autogen.h/autogen.c.
+  The PcdGetXX(), PcdSetXX(), PcdToken(), and PcdGetNextTokenSpace() operations are 
+  only available prior to ExitBootServices().  If access to PCD values are required 
+  at runtime, then their values must be collected prior to ExitBootServices().
+  There are no restrictions on the use of FeaturePcd(), FixedPcdGetXX(),
+  PatchPcdGetXX(), and PatchPcdSetXX().
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PCD_LIB_H__
+#define __PCD_LIB_H__
+
+
+/**
+  Retrieves a token number based on a token name.
+
+  Returns the token number associated with the PCD token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve the token number for.
+
+  @return  The token number associated with the PCD.
+
+**/
+#define PcdToken(TokenName)                 _PCD_TOKEN_##TokenName
+
+
+/**
+  Retrieves a Boolean PCD feature flag based on a token name.
+
+  Returns the Boolean value for the PCD feature flag specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a feature flag PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  Boolean value for the PCD feature flag.
+
+**/
+#define FeaturePcdGet(TokenName)            _PCD_GET_MODE_BOOL_##TokenName
+
+
+/**
+  Retrieves an 8-bit fixed PCD token value based on a token name.
+
+  Returns the 8-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a fixed at build PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  8-bit value for the token specified by TokenName.
+
+**/
+#define FixedPcdGet8(TokenName)             _PCD_VALUE_##TokenName
+
+
+/**
+  Retrieves a 16-bit fixed PCD token value based on a token name.
+
+  Returns the 16-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a fixed at build PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  16-bit value for the token specified by TokenName.
+
+**/
+#define FixedPcdGet16(TokenName)            _PCD_VALUE_##TokenName
+
+
+/**
+  Retrieves a 32-bit fixed PCD token value based on a token name.
+
+  Returns the 32-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a fixed at build PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  32-bit value for the token specified by TokenName.
+
+**/
+#define FixedPcdGet32(TokenName)            _PCD_VALUE_##TokenName
+
+
+/**
+  Retrieves a 64-bit fixed PCD token value based on a token name.
+
+  Returns the 64-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a fixed at build PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  64-bit value for the token specified by TokenName.
+
+**/
+#define FixedPcdGet64(TokenName)            _PCD_VALUE_##TokenName
+
+
+/**
+  Retrieves a Boolean fixed PCD token value based on a token name.
+
+  Returns the Boolean value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a fixed at build PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  The Boolean value for the token. 
+
+**/
+#define FixedPcdGetBool(TokenName)          _PCD_VALUE_##TokenName
+
+
+/**
+  Retrieves a pointer to a fixed PCD token buffer based on a token name.
+
+  Returns a pointer to the buffer for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a fixed at build PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A pointer to the buffer. 
+
+**/
+#define FixedPcdGetPtr(TokenName)           ((VOID *)_PCD_VALUE_##TokenName)
+
+
+/**
+  Retrieves an 8-bit binary patchable PCD token value based on a token name.
+
+  Returns the 8-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  An 8-bit binary patchable PCD token value.
+
+**/
+#define PatchPcdGet8(TokenName)             _gPcd_BinaryPatch_##TokenName
+
+/**
+  Retrieves a 16-bit binary patchable PCD token value based on a token name.
+
+  Returns the 16-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A 16-bit binary patchable PCD token value.
+
+**/
+#define PatchPcdGet16(TokenName)            _gPcd_BinaryPatch_##TokenName
+
+
+/**
+  Retrieves a 32-bit binary patchable PCD token value based on a token name.
+
+  Returns the 32-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A 32-bit binary patchable PCD token value.
+
+**/
+#define PatchPcdGet32(TokenName)            _gPcd_BinaryPatch_##TokenName
+
+
+/**
+  Retrieves a 64-bit binary patchable PCD token value based on a token name.
+
+  Returns the 64-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A 64-bit binary patchable PCD token value.
+
+**/
+#define PatchPcdGet64(TokenName)            _gPcd_BinaryPatch_##TokenName
+
+
+/**
+  Retrieves a Boolean binary patchable PCD token value based on a token name.
+
+  Returns the Boolean value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  The Boolean value for the token.
+
+**/
+#define PatchPcdGetBool(TokenName)          _gPcd_BinaryPatch_##TokenName
+
+
+/**
+  Retrieves a pointer to a binary patchable PCD token buffer based on a token name.
+
+  Returns a pointer to the buffer for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A pointer to the buffer for the token.
+
+**/
+#define PatchPcdGetPtr(TokenName)           ((VOID *)_gPcd_BinaryPatch_##TokenName)
+
+
+/**
+  Sets an 8-bit binary patchable PCD token value based on a token name.
+
+  Sets the 8-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the binary patchable PCD token to set the current value for.
+  @param   Value      The 8-bit value to set.
+  
+  @return Return the Value that was set.
+
+**/
+#define PatchPcdSet8(TokenName, Value)      (_gPcd_BinaryPatch_##TokenName = (Value))
+
+
+/**
+  Sets a 16-bit binary patchable PCD token value based on a token name.
+
+  Sets the 16-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the binary patchable PCD token to set the current value for.
+  @param   Value      The 16-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PatchPcdSet16(TokenName, Value)     (_gPcd_BinaryPatch_##TokenName = (Value))
+
+
+/**
+  Sets a 32-bit binary patchable PCD token value based on a token name.
+
+  Sets the 32-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the binary patchable PCD token to set the current value for.
+  @param   Value      The 32-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PatchPcdSet32(TokenName, Value)     (_gPcd_BinaryPatch_##TokenName = (Value))
+
+
+/**
+  Sets a 64-bit binary patchable PCD token value based on a token name.
+
+  Sets the 64-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the binary patchable PCD token to set the current value for.
+  @param   Value      The 64-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PatchPcdSet64(TokenName, Value)     (_gPcd_BinaryPatch_##TokenName = (Value))
+
+
+/**
+  Sets a Boolean binary patchable PCD token value based on a token name.
+
+  Sets the Boolean value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+
+  @param   TokenName  The name of the binary patchable PCD token to set the current value for.
+  @param   Value      The boolean value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PatchPcdSetBool(TokenName, Value)   (_gPcd_BinaryPatch_##TokenName = (Value))
+
+
+/**
+  Sets a pointer to a binary patchable PCD token buffer based on a token name.
+
+  Sets the buffer for the token specified by TokenName.  Buffer is returned.  
+  If SizeOfBuffer is greater than the maximum size supported by TokenName, then set SizeOfBuffer
+  to the maximum size supported by TokenName and return NULL to indicate that the set operation 
+  was not actually performed.  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be 
+  set to the maximum size supported by TokenName and NULL must be returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  If TokenName is not a patchable in module PCD, then the module will not build.
+  
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+  
+  @param   TokenName      The name of the binary patchable PCD token to set the current value for.
+  @param   SizeOfBuffer   A pointer to the size, in bytes, of Buffer.
+  @param   Buffer         Pointer to the value to set.
+
+  @return Return the pointer to the Buffer that was set.
+
+**/
+#define PatchPcdSetPtr(TokenName, Size, Buffer) \
+                                            LibPatchPcdSetPtrAndSize (                 \
+                                              (VOID *)_gPcd_BinaryPatch_##TokenName,   \
+                                              &_gPcd_BinaryPatch_Size_##TokenName,     \
+                                              (UINTN)_PCD_PATCHABLE_##TokenName##_SIZE, \
+                                              (Size),                                  \
+                                              (Buffer)                                 \
+                                              )
+/**
+  Retrieves an 8-bit PCD token value based on a token name.
+  
+  Returns the 8-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  8-bit value for the token specified by TokenName.
+
+**/
+#define PcdGet8(TokenName)                  _PCD_GET_MODE_8_##TokenName
+
+
+/**
+  Retrieves a 16-bit PCD token value based on a token name.
+
+  Returns the 16-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  16-bit value for the token specified by TokenName.
+
+**/
+#define PcdGet16(TokenName)                 _PCD_GET_MODE_16_##TokenName
+
+
+/**
+  Retrieves a 32-bit PCD token value based on a token name.
+
+  Returns the 32-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  32-bit value for the token specified by TokenName.
+
+**/
+#define PcdGet32(TokenName)                 _PCD_GET_MODE_32_##TokenName
+
+
+/**
+  Retrieves a 64-bit PCD token value based on a token name.
+
+  Returns the 64-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  64-bit value for the token specified by TokenName.
+
+**/
+#define PcdGet64(TokenName)                 _PCD_GET_MODE_64_##TokenName
+
+
+/**
+  Retrieves a pointer to a PCD token buffer based on a token name.
+
+  Returns a pointer to the buffer for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A pointer to the buffer.
+
+**/
+#define PcdGetPtr(TokenName)                _PCD_GET_MODE_PTR_##TokenName
+
+
+/**
+  Retrieves a Boolean PCD token value based on a token name.
+
+  Returns the Boolean value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+
+  @return  A Boolean PCD token value.
+
+**/
+#define PcdGetBool(TokenName)               _PCD_GET_MODE_BOOL_##TokenName
+
+
+/**
+  Retrieves the size of a fixed PCD token based on a token name.
+
+  Returns the size of the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param[in]  TokenName  The name of the PCD token to retrieve a current value size for.
+
+  @return     Return the size
+
+**/
+#define FixedPcdGetSize(TokenName)    _PCD_SIZE_##TokenName
+
+
+/**
+  Retrieves the size of a binary patchable PCD token based on a token name.
+
+  Returns the size of the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param[in]  TokenName  The name of the PCD token to retrieve a current value size for.
+
+  @return     Return the size
+
+**/
+#define PatchPcdGetSize(TokenName)    _gPcd_BinaryPatch_Size_##TokenName
+
+
+/**
+  Retrieves the size of the PCD token based on a token name.
+  
+  Returns the size of the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  
+  @param[in]   TokenName  The name of the PCD token to retrieve a current value size for.
+
+  @return      Return the size
+
+**/
+#define PcdGetSize(TokenName)         _PCD_GET_MODE_SIZE_##TokenName
+
+
+/**
+  Retrieve the size of a given PCD token.
+  
+  Returns the size of the token specified by TokenNumber and Guid. 
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that designates 
+                            which namespace to retrieve a value from.
+  @param[in]  TokenNumber   The PCD token number to retrieve a current value size for.
+
+  @return     Return the size.
+
+**/
+#define PcdGetExSize(Guid, TokenName) LibPcdGetExSize ((Guid), PcdTokenEx(Guid,TokenName))
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+/**
+  Sets an 8-bit PCD token value based on a token name.
+
+  Sets the 8-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+  @param   Value      The 8-bit value to set.
+  
+  @return Return the Value that was set.
+
+**/
+#define PcdSet8(TokenName, Value)           _PCD_SET_MODE_8_##TokenName     ((Value))
+
+
+/**
+  Sets a 16-bit PCD token value based on a token name.
+
+  Sets the 16-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+  @param   Value      The 16-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSet16(TokenName, Value)          _PCD_SET_MODE_16_##TokenName    ((Value))
+
+
+/**
+  Sets a 32-bit PCD token value based on a token name.
+
+  Sets the 32-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+  @param   Value      The 32-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSet32(TokenName, Value)          _PCD_SET_MODE_32_##TokenName    ((Value))
+
+
+/**
+  Sets a 64-bit PCD token value based on a token name.
+
+  Sets the 64-bit value for the token specified by TokenName. Value is returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName  The name of the PCD token to retrieve a current value for.
+  @param   Value      The 64-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSet64(TokenName, Value)          _PCD_SET_MODE_64_##TokenName    ((Value))
+
+
+/**
+  Sets a pointer to a PCD token buffer based on a token name.
+
+  Sets the buffer for the token specified by TokenName. Buffer is returned.  
+  If SizeOfBuffer is greater than the maximum size supported by TokenName, 
+  then set SizeOfBuffer to the maximum size supported by TokenName and return NULL 
+  to indicate that the set operation was not actually performed.  If SizeOfBuffer 
+  is set to MAX_ADDRESS, then SizeOfBuffer must be set to the maximum size supported 
+  by TokenName and NULL must be returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+  
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+  
+  @param   TokenName      The name of the PCD token to set the current value for.
+  @param   SizeOfBuffer   A pointer to the size, in bytes, of Buffer.
+  @param   Buffer         A pointer to the buffer to set.
+
+  @return Return the pointer to the Buffer that was set.
+
+**/
+#define PcdSetPtr(TokenName, SizeOfBuffer, Buffer) \
+                                            _PCD_SET_MODE_PTR_##TokenName   ((SizeOfBuffer), (Buffer))
+                                            
+/**
+  Sets a Boolean PCD token value based on a token name.
+
+  Sets the Boolean value for the token specified by TokenName. Value is returned. 
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   TokenName      The name of the PCD token to set the current value for.
+  @param   Buffer         The Boolean value to set.
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSetBool(TokenName, Value)        _PCD_SET_MODE_BOOL_##TokenName  ((Value))
+#endif
+
+/**
+  Sets a 8-bit PCD token value based on a token name.
+
+  Sets the 8-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param TokenName  The name of the PCD token to retrieve a current value for.
+  @param Value      The 8-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSet8S(TokenName, Value)          _PCD_SET_MODE_8_S_##TokenName    ((Value))
+
+/**
+  Sets a 16-bit PCD token value based on a token name.
+
+  Sets the 16-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param TokenName  The name of the PCD token to retrieve a current value for.
+  @param Value      The 16-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSet16S(TokenName, Value)         _PCD_SET_MODE_16_S_##TokenName    ((Value))
+
+/**
+  Sets a 32-bit PCD token value based on a token name.
+
+  Sets the 32-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param TokenName  The name of the PCD token to retrieve a current value for.
+  @param Value      The 32-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSet32S(TokenName, Value)         _PCD_SET_MODE_32_S_##TokenName    ((Value))
+
+/**
+  Sets a 64-bit PCD token value based on a token name.
+
+  Sets the 64-bit value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param TokenName  The name of the PCD token to retrieve a current value for.
+  @param Value      The 64-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSet64S(TokenName, Value)         _PCD_SET_MODE_64_S_##TokenName    ((Value))
+
+/**
+  Sets a pointer to a PCD token buffer based on a token name.
+
+  Sets the buffer for the token specified by TokenName.
+  If SizeOfBuffer is greater than the maximum size supported by TokenName,
+  then set SizeOfBuffer to the maximum size supported by TokenName and return
+  RETURN_INVALID_PARAMETER to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to the maximum size
+  supported by TokenName and RETURN_INVALID_PARAMETER must be returned.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param TokenName      The name of the PCD token to set the current value for.
+  @param SizeOfBuffer   A pointer to the size, in bytes, of Buffer.
+  @param Buffer         A pointer to the buffer to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetPtrS(TokenName, SizeOfBuffer, Buffer) \
+                                            _PCD_SET_MODE_PTR_S_##TokenName   ((SizeOfBuffer), (Buffer))
+
+
+
+/**
+  Sets a boolean PCD token value based on a token name.
+
+  Sets the boolean value for the token specified by TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param TokenName  The name of the PCD token to retrieve a current value for.
+  @param Value      The boolean value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetBoolS(TokenName, Value)       _PCD_SET_MODE_BOOL_S_##TokenName    ((Value))
+
+/**
+  Retrieves a token number based on a GUID and a token name.
+
+  Returns the token number for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space, then the module will not build.
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  Return the token number.
+
+**/
+#define PcdTokenEx(Guid,TokenName)  _PCD_TOKEN_EX_##TokenName(Guid)
+
+/**
+  Retrieves an 8-bit PCD token value based on a GUID and a token name.
+
+  Returns the 8-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+  
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  An 8-bit PCD token value.
+
+**/
+#define PcdGetEx8(Guid, TokenName)          LibPcdGetEx8 ((Guid), PcdTokenEx(Guid,TokenName))
+
+/**
+  Retrieves a 16-bit PCD token value based on a GUID and a token name.
+
+  Returns the 16-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  A 16-bit PCD token value.
+
+**/
+#define PcdGetEx16(Guid, TokenName)         LibPcdGetEx16 ((Guid), PcdTokenEx(Guid,TokenName))
+
+
+/**
+  Retrieves a 32-bit PCD token value based on a GUID and a token name.
+
+  Returns the 32-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  A 32-bit PCD token value.
+
+**/
+#define PcdGetEx32(Guid, TokenName)         LibPcdGetEx32 ((Guid), PcdTokenEx(Guid,TokenName))
+
+
+/**
+  Retrieves a 64-bit PCD token value based on a GUID and a token name.
+
+  Returns the 64-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  A 64-bit PCD token value.
+
+**/
+#define PcdGetEx64(Guid, TokenName)         LibPcdGetEx64 ((Guid), PcdTokenEx(Guid,TokenName))
+
+
+/**
+  Retrieves a pointer to a PCD token buffer based on a GUID and a token name.
+
+  Returns a pointer to the buffer for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  A pointer to a PCD token buffer.
+
+**/
+#define PcdGetExPtr(Guid, TokenName)        LibPcdGetExPtr ((Guid), PcdTokenEx(Guid,TokenName))
+
+
+/**
+  Retrieves a Boolean PCD token value based on a GUID and a token name.
+
+  Returns the Boolean value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to retrieve a current value for.                 
+
+  @return  A Boolean PCD token value.
+
+**/
+#define PcdGetExBool(Guid, TokenName)       LibPcdGetExBool  ((Guid), PcdTokenEx(Guid,TokenName))
+
+
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+/**
+  Sets an 8-bit PCD token value based on a GUID and a token name.
+
+  Sets the 8-bit value for the token specified by Guid and TokenName. Value is returned.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to set the current value for.
+  @param   Value       The 8-bit value to set.                   
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSetEx8(Guid, TokenName, Value)   LibPcdSetEx8   ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+
+/**
+  Sets a 16-bit PCD token value based on a GUID and a token name.
+
+  Sets the 16-bit value for the token specified by Guid and TokenName. Value is returned.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to set the current value for.
+  @param   Value       The 16-bit value to set.                   
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSetEx16(Guid, TokenName, Value)  LibPcdSetEx16  ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+
+/**
+  Sets a 32-bit PCD token value based on a GUID and a token name.
+
+  Sets the 32-bit value for the token specified by Guid and TokenName. Value is returned.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+                       which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to set the current value for.
+  @param   Value       The 32-bit value to set.                   
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSetEx32(Guid, TokenName, Value)  LibPcdSetEx32  ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+
+/**
+  Sets a 64-bit PCD token value based on a GUID and a token name.
+
+  Sets the 64-bit value for the token specified by Guid and TokenName. Value is returned.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid        Pointer to a 128-bit unique value that designates 
+  which namespace to retrieve a value from.
+  @param   TokenName   The name of the PCD token to set the current value for.
+  @param   Value       The 64-bit value to set.                   
+
+  @return Return the Value that was set.
+
+**/
+#define PcdSetEx64(Guid, TokenName, Value)  LibPcdSetEx64  ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+
+/**
+  Sets a pointer to a PCD token buffer based on a GUID and a token name.
+
+  Sets the buffer for the token specified by Guid and TokenName. Buffer is returned.  
+  If SizeOfBuffer is greater than the maximum size supported by Guid and TokenName, 
+  then set SizeOfBuffer to the maximum size supported by Guid and TokenName and return 
+  NULL to indicate that the set operation was not actually performed. If SizeOfBuffer 
+  is set to MAX_ADDRESS, then SizeOfBuffer must be set to the maximum size supported by
+  Guid and TokenName and NULL must be returned.
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+  
+  If Guid is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param   Guid           Pointer to a 128-bit unique value that designates 
+                          which namespace to retrieve a value from.
+  @param   TokenName      The name of the PCD token to set the current value for.
+  @param   SizeOfBuffer   A pointer to the size, in bytes, of Buffer.                  
+  @param   Buffer         Pointer to the buffer to set.
+    
+  @return Return the pointer to the Buffer that was set.
+
+**/
+#define PcdSetExPtr(Guid, TokenName, SizeOfBuffer, Buffer) \
+                                            LibPcdSetExPtr ((Guid), PcdTokenEx(Guid,TokenName), (SizeOfBuffer), (Buffer))
+
+
+/**
+  Sets a Boolean PCD token value based on a GUID and a token name.
+
+  Sets the Boolean value for the token specified by Guid and TokenName. Value is returned. 
+  If TokenName is not a valid token in the token space specified by Guid, 
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param   Guid           Pointer to a 128-bit unique value that designates 
+                          which namespace to retrieve a value from.
+  @param   TokenName      The name of the PCD token to set the current value for.              
+  @param   Value          The Boolean value to set.
+
+  @return Return the Value that was set.
+
+**/                                         
+#define PcdSetExBool(Guid, TokenName, Value) \
+                                            LibPcdSetExBool((Guid), PcdTokenEx(Guid,TokenName), (Value))
+#endif
+
+/**
+  Sets an 8-bit PCD token value based on a GUID and a token name.
+
+  Sets the 8-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid,
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param Guid       Pointer to a 128-bit unique value that designates
+                    which namespace to retrieve a value from.
+  @param TokenName  The name of the PCD token to set the current value for.
+  @param Value      The 8-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetEx8S(Guid, TokenName, Value)     LibPcdSetEx8S ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+/**
+  Sets an 16-bit PCD token value based on a GUID and a token name.
+
+  Sets the 16-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid,
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param Guid       Pointer to a 128-bit unique value that designates
+                    which namespace to retrieve a value from.
+  @param TokenName  The name of the PCD token to set the current value for.
+  @param Value      The 16-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetEx16S(Guid, TokenName, Value)    LibPcdSetEx16S ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+/**
+  Sets an 32-bit PCD token value based on a GUID and a token name.
+
+  Sets the 32-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid,
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param Guid       Pointer to a 128-bit unique value that designates
+                    which namespace to retrieve a value from.
+  @param TokenName  The name of the PCD token to set the current value for.
+  @param Value      The 32-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetEx32S(Guid, TokenName, Value)    LibPcdSetEx32S ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+/**
+  Sets an 64-bit PCD token value based on a GUID and a token name.
+
+  Sets the 64-bit value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid,
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param Guid       Pointer to a 128-bit unique value that designates
+                    which namespace to retrieve a value from.
+  @param TokenName  The name of the PCD token to set the current value for.
+  @param Value      The 64-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetEx64S(Guid, TokenName, Value)    LibPcdSetEx64S ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+/**
+  Sets a pointer to a PCD token buffer based on a GUID and a token name.
+
+  Sets the buffer for the token specified by Guid and TokenName.
+  If SizeOfBuffer is greater than the maximum size supported by Guid and TokenName,
+  then set SizeOfBuffer to the maximum size supported by Guid and TokenName and return
+  RETURN_INVALID_PARAMETER to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to the maximum size
+  supported by Guid and TokenName and RETURN_INVALID_PARAMETER must be returned.
+  If TokenName is not a valid token in the token space specified by Guid,
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param Guid           Pointer to a 128-bit unique value that designates
+                        which namespace to retrieve a value from.
+  @param TokenName      The name of the PCD token to set the current value for.
+  @param SizeOfBuffer   A pointer to the size, in bytes, of Buffer.
+  @param Buffer         Pointer to the buffer to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetExPtrS(Guid, TokenName, SizeOfBuffer, Buffer) \
+                                            LibPcdSetExPtrS ((Guid), PcdTokenEx(Guid,TokenName), (SizeOfBuffer), (Buffer))
+
+
+/**
+  Sets an boolean PCD token value based on a GUID and a token name.
+
+  Sets the boolean value for the token specified by Guid and TokenName.
+  If TokenName is not a valid token in the token space specified by Guid,
+  then the module will not build.
+
+  If Guid is NULL, then ASSERT().
+
+  @param Guid       Pointer to a 128-bit unique value that designates
+                    which namespace to retrieve a value from.
+  @param TokenName  The name of the PCD token to set the current value for.
+  @param Value      The boolean value to set.
+
+  @return The status of the set operation.
+
+**/
+#define PcdSetExBoolS(Guid, TokenName, Value) \
+                                            LibPcdSetExBoolS ((Guid), PcdTokenEx(Guid,TokenName), (Value))
+
+/**
+  This function provides a means by which SKU support can be established in the PCD infrastructure.
+
+  Sets the current SKU in the PCD database to the value specified by SkuId.  SkuId is returned.
+
+  @param  SkuId   The SKU value that will be used when the PCD service retrieves and sets values
+                  associated with a PCD token.
+
+  @return  Return the SKU ID that was set.
+
+**/
+UINTN
+EFIAPI
+LibPcdSetSku (
+  IN UINTN   SkuId
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the 8-bit value for the token specified by TokenNumber. 
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the 8-bit value for the token specified by TokenNumber. 
+
+**/
+UINT8
+EFIAPI
+LibPcdGet8 (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the 16-bit value for the token specified by TokenNumber. 
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the 16-bit value for the token specified by TokenNumber. 
+
+**/
+UINT16
+EFIAPI
+LibPcdGet16 (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the 32-bit value for the token specified by TokenNumber. 
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the 32-bit value for the token specified by TokenNumber.
+
+**/
+UINT32
+EFIAPI
+LibPcdGet32 (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the 64-bit value for the token specified by TokenNumber.
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the 64-bit value for the token specified by TokenNumber.
+
+**/
+UINT64
+EFIAPI
+LibPcdGet64 (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the pointer to the buffer of the token specified by TokenNumber.
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the pointer to the token specified by TokenNumber.
+
+**/
+VOID *
+EFIAPI
+LibPcdGetPtr (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the Boolean value of the token specified by TokenNumber. 
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the Boolean value of the token specified by TokenNumber. 
+
+**/
+BOOLEAN 
+EFIAPI
+LibPcdGetBool (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve the size of a given PCD token.
+
+  @param[in]  TokenNumber The PCD token number to retrieve a current value for.
+
+  @return Returns the size of the token specified by TokenNumber. 
+
+**/
+UINTN
+EFIAPI
+LibPcdGetSize (
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the 8-bit value for the token specified by TokenNumber and Guid.
+  
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid         Pointer to a 128-bit unique value that designates 
+                           which namespace to retrieve a value from.
+  @param[in]  TokenNumber  The PCD token number to retrieve a current value for.
+
+  @return Return the UINT8.
+
+**/
+UINT8
+EFIAPI
+LibPcdGetEx8 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+
+  Returns the 16-bit value for the token specified by TokenNumber and Guid.
+  
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid         Pointer to a 128-bit unique value that designates 
+                           which namespace to retrieve a value from.
+  @param[in]  TokenNumber  The PCD token number to retrieve a current value for.
+
+  @return Return the UINT16.
+
+**/
+UINT16
+EFIAPI
+LibPcdGetEx16 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  Returns the 32-bit value for the token specified by TokenNumber and Guid.
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid         Pointer to a 128-bit unique value that designates 
+                           which namespace to retrieve a value from.
+  @param[in]  TokenNumber  The PCD token number to retrieve a current value for.
+
+  @return Return the UINT32.
+
+**/
+UINT32
+EFIAPI
+LibPcdGetEx32 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the 64-bit value for the token specified by TokenNumber and Guid.
+  
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that designates 
+                            which namespace to retrieve a value from.
+  @param[in]  TokenNumber   The PCD token number to retrieve a current value for.
+
+  @return Return the UINT64.
+
+**/
+UINT64
+EFIAPI
+LibPcdGetEx64 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the pointer to the buffer of token specified by TokenNumber and Guid.
+  
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that designates 
+                            which namespace to retrieve a value from.
+  @param[in]  TokenNumber   The PCD token number to retrieve a current value for.
+
+  @return Return the VOID* pointer.
+
+**/
+VOID *
+EFIAPI
+LibPcdGetExPtr (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve a value for a given PCD token.
+  
+  Returns the Boolean value of the token specified by TokenNumber and Guid. 
+  
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that designates 
+                            which namespace to retrieve a value from.
+  @param[in]  TokenNumber   The PCD token number to retrieve a current value for.
+
+  @return Return the BOOLEAN.
+
+**/
+BOOLEAN
+EFIAPI
+LibPcdGetExBool (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+/**
+  This function provides a means by which to retrieve the size of a given PCD token.
+  
+  Returns the size of the token specified by TokenNumber and Guid. 
+  
+  If Guid is NULL, then ASSERT(). 
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that designates 
+                            which namespace to retrieve a value from.
+  @param[in]  TokenNumber   The PCD token number to retrieve a current value for.
+
+  @return Return the size.
+
+**/
+UINTN
+EFIAPI
+LibPcdGetExSize (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber
+  );
+
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 8-bit value for the token specified by TokenNumber 
+  to the value specified by Value.  Value is returned.
+
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 8-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT8
+EFIAPI
+LibPcdSet8 (
+  IN UINTN             TokenNumber,
+  IN UINT8             Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 16-bit value for the token specified by TokenNumber 
+  to the value specified by Value.  Value is returned.
+
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 16-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT16
+EFIAPI
+LibPcdSet16 (
+  IN UINTN             TokenNumber,
+  IN UINT16            Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 32-bit value for the token specified by TokenNumber 
+  to the value specified by Value.  Value is returned.
+
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 32-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT32
+EFIAPI
+LibPcdSet32 (
+  IN UINTN             TokenNumber,
+  IN UINT32            Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 64-bit value for the token specified by TokenNumber 
+  to the value specified by Value.  Value is returned.
+
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 64-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT64
+EFIAPI
+LibPcdSet64 (
+  IN UINTN             TokenNumber,
+  IN UINT64            Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets a buffer for the token specified by TokenNumber to the value 
+  specified by Buffer and SizeOfBuffer.  Buffer is returned.  
+  If SizeOfBuffer is greater than the maximum size support by TokenNumber, 
+  then set SizeOfBuffer to the maximum size supported by TokenNumber and 
+  return NULL to indicate that the set operation was not actually performed.
+
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to the 
+  maximum size supported by TokenName and NULL must be returned.
+  
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+  
+  @param[in]      TokenNumber   The PCD token number to set a current value for.
+  @param[in, out] SizeOfBuffer  The size, in bytes, of Buffer.
+  @param[in]      Buffer        A pointer to the buffer to set.
+
+  @return Return the pointer for the Buffer that was set.
+
+**/
+VOID *
+EFIAPI
+LibPcdSetPtr (
+  IN        UINTN             TokenNumber,
+  IN OUT    UINTN             *SizeOfBuffer,
+  IN CONST  VOID              *Buffer
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the Boolean value for the token specified by TokenNumber 
+  to the value specified by Value.  Value is returned.
+
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The boolean value to set.
+
+  @return Return the Value that was set.
+
+**/
+BOOLEAN
+EFIAPI
+LibPcdSetBool (
+  IN UINTN             TokenNumber,
+  IN BOOLEAN           Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 8-bit value for the token specified by TokenNumber and 
+  Guid to the value specified by Value. Value is returned.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that 
+                            designates which namespace to set a value from.
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 8-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT8
+EFIAPI
+LibPcdSetEx8 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber,
+  IN UINT8             Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 16-bit value for the token specified by TokenNumber and 
+  Guid to the value specified by Value. Value is returned.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that 
+                            designates which namespace to set a value from.
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 16-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT16
+EFIAPI
+LibPcdSetEx16 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber,
+  IN UINT16            Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 32-bit value for the token specified by TokenNumber and 
+  Guid to the value specified by Value. Value is returned.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that 
+                            designates which namespace to set a value from.
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 32-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT32
+EFIAPI
+LibPcdSetEx32 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber,
+  IN UINT32            Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the 64-bit value for the token specified by TokenNumber and 
+  Guid to the value specified by Value. Value is returned.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that 
+                            designates which namespace to set a value from.
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The 64-bit value to set.
+
+  @return Return the Value that was set.
+
+**/
+UINT64
+EFIAPI
+LibPcdSetEx64 (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber,
+  IN UINT64            Value
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets a buffer for the token specified by TokenNumber to the value specified by 
+  Buffer and SizeOfBuffer.  Buffer is returned.  If SizeOfBuffer is greater than 
+  the maximum size support by TokenNumber, then set SizeOfBuffer to the maximum size 
+  supported by TokenNumber and return NULL to indicate that the set operation 
+  was not actually performed.
+  
+  If Guid is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+  
+  @param[in]  Guid              Pointer to a 128-bit unique value that 
+                                designates which namespace to set a value from.
+  @param[in]  TokenNumber       The PCD token number to set a current value for.
+  @param[in, out] SizeOfBuffer  The size, in bytes, of Buffer.
+  @param[in]  Buffer            A pointer to the buffer to set.
+
+  @return Return the pointer to the Buffer that was set.
+
+**/
+VOID *
+EFIAPI
+LibPcdSetExPtr (
+  IN      CONST GUID        *Guid,
+  IN      UINTN             TokenNumber,
+  IN OUT  UINTN             *SizeOfBuffer,
+  IN      VOID              *Buffer
+  );
+
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+  
+  Sets the Boolean value for the token specified by TokenNumber and 
+  Guid to the value specified by Value. Value is returned.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in]  Guid          Pointer to a 128-bit unique value that 
+                            designates which namespace to set a value from.
+  @param[in]  TokenNumber   The PCD token number to set a current value for.
+  @param[in]  Value         The Boolean value to set.
+
+  @return Return the Value that was set.
+
+**/
+BOOLEAN
+EFIAPI
+LibPcdSetExBool (
+  IN CONST GUID        *Guid,
+  IN UINTN             TokenNumber,
+  IN BOOLEAN           Value
+  );
+#endif
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 8-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 8-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSet8S (
+  IN UINTN          TokenNumber,
+  IN UINT8          Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 16-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 16-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSet16S (
+  IN UINTN          TokenNumber,
+  IN UINT16         Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 32-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 32-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSet32S (
+  IN UINTN          TokenNumber,
+  IN UINT32         Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 64-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 64-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSet64S (
+  IN UINTN          TokenNumber,
+  IN UINT64         Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets a buffer for the token specified by TokenNumber to the value specified
+  by Buffer and SizeOfBuffer. If SizeOfBuffer is greater than the maximum size
+  support by TokenNumber, then set SizeOfBuffer to the maximum size supported by
+  TokenNumber and return RETURN_INVALID_PARAMETER to indicate that the set operation
+  was not actually performed.
+
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to the
+  maximum size supported by TokenName and RETURN_INVALID_PARAMETER must be returned.
+
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[in]      TokenNumber   The PCD token number to set a current value for.
+  @param[in, out] SizeOfBuffer  The size, in bytes, of Buffer.
+  @param[in]      Buffer        A pointer to the buffer to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetPtrS (
+  IN       UINTN    TokenNumber,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN CONST VOID     *Buffer
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the boolean value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The boolean value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetBoolS (
+  IN UINTN          TokenNumber,
+  IN BOOLEAN        Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 8-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in] Guid           The pointer to a 128-bit unique value that
+                            designates which namespace to set a value from.
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 8-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetEx8S (
+  IN CONST GUID     *Guid,
+  IN UINTN          TokenNumber,
+  IN UINT8          Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 16-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in] Guid           The pointer to a 128-bit unique value that
+                            designates which namespace to set a value from.
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 16-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetEx16S (
+  IN CONST GUID     *Guid,
+  IN UINTN          TokenNumber,
+  IN UINT16         Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 32-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in] Guid           The pointer to a 128-bit unique value that
+                            designates which namespace to set a value from.
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 32-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetEx32S (
+  IN CONST GUID     *Guid,
+  IN UINTN          TokenNumber,
+  IN UINT32         Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the 64-bit value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in] Guid           The pointer to a 128-bit unique value that
+                            designates which namespace to set a value from.
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The 64-bit value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetEx64S (
+  IN CONST GUID     *Guid,
+  IN UINTN          TokenNumber,
+  IN UINT64         Value
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets a buffer for the token specified by TokenNumber to the value specified by
+  Buffer and SizeOfBuffer. If SizeOfBuffer is greater than the maximum size
+  support by TokenNumber, then set SizeOfBuffer to the maximum size supported by
+  TokenNumber and return RETURN_INVALID_PARAMETER to indicate that the set operation
+  was not actually performed.
+
+  If Guid is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[in]      Guid          Pointer to a 128-bit unique value that
+                                designates which namespace to set a value from.
+  @param[in]      TokenNumber   The PCD token number to set a current value for.
+  @param[in, out] SizeOfBuffer  The size, in bytes, of Buffer.
+  @param[in]      Buffer        A pointer to the buffer to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetExPtrS (
+  IN CONST GUID     *Guid,
+  IN       UINTN    TokenNumber,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN       VOID     *Buffer
+  );
+
+/**
+  This function provides a means by which to set a value for a given PCD token.
+
+  Sets the boolean value for the token specified by TokenNumber
+  to the value specified by Value.
+
+  If Guid is NULL, then ASSERT().
+
+  @param[in] Guid           The pointer to a 128-bit unique value that
+                            designates which namespace to set a value from.
+  @param[in] TokenNumber    The PCD token number to set a current value for.
+  @param[in] Value          The boolean value to set.
+
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPcdSetExBoolS (
+  IN CONST GUID     *Guid,
+  IN UINTN          TokenNumber,
+  IN BOOLEAN        Value
+  );
+
+/**
+  This notification function serves two purposes.
+
+  Firstly, it notifies the module that did the registration that the value of this
+  PCD token has been set.
+  Secondly, it provides a mechanism for the module that did the registration to intercept
+  the set operation and override the value been set if necessary. After the invocation of
+  the callback function, TokenData will be used by PCD service PEIM or driver to modify th
+  internal data in PCD database. 
+
+  @param[in]      CallBackGuid    The PCD token GUID being set.
+  @param[in]      CallBackToken   The PCD token number being set.
+  @param[in, out] TokenData       A pointer to the token data being set.
+  @param[in]      TokenDataSize   The size, in bytes, of the data being set.
+
+**/
+typedef
+VOID
+(EFIAPI *PCD_CALLBACK)(
+  IN        CONST GUID        *CallBackGuid, OPTIONAL
+  IN        UINTN             CallBackToken,
+  IN  OUT   VOID              *TokenData,
+  IN        UINTN             TokenDataSize
+  );
+
+
+/**
+  Set up a notification function that is called when a specified token is set.
+  
+  When the token specified by TokenNumber and Guid is set, 
+  then notification function specified by NotificationFunction is called.  
+  If Guid is NULL, then the default token space is used.
+  If NotificationFunction is NULL, then ASSERT().
+
+  @param[in]  Guid                  Pointer to a 128-bit unique value that designates which 
+                                    namespace to set a value from.  If NULL, then the default 
+                                    token space is used.
+  @param[in]  TokenNumber           The PCD token number to monitor.
+  @param[in]  NotificationFunction  The function to call when the token 
+                                    specified by Guid and TokenNumber is set.
+
+**/
+VOID
+EFIAPI
+LibPcdCallbackOnSet (
+  IN CONST GUID               *Guid,       OPTIONAL
+  IN UINTN                    TokenNumber,
+  IN PCD_CALLBACK             NotificationFunction
+  );
+
+
+/**
+  Disable a notification function that was established with LibPcdCallbackonSet().
+  
+  Disable a notification function that was previously established with LibPcdCallbackOnSet().
+  If NotificationFunction is NULL, then ASSERT().
+  If LibPcdCallbackOnSet() was not previously called with Guid, TokenNumber, 
+  and NotificationFunction, then ASSERT().
+  
+  @param[in]  Guid                 Specify the GUID token space.
+  @param[in]  TokenNumber          Specify the token number.
+  @param[in]  NotificationFunction The callback function to be unregistered.
+
+**/
+VOID
+EFIAPI
+LibPcdCancelCallback (
+  IN CONST GUID               *Guid,       OPTIONAL
+  IN UINTN                    TokenNumber,
+  IN PCD_CALLBACK             NotificationFunction
+  );
+
+
+/**
+  Retrieves the next token in a token space.
+  
+  Retrieves the next PCD token number from the token space specified by Guid.  
+  If Guid is NULL, then the default token space is used.  If TokenNumber is 0, 
+  then the first token number is returned.  Otherwise, the token number that 
+  follows TokenNumber in the token space is returned.  If TokenNumber is the last 
+  token number in the token space, then 0 is returned.  
+  
+  If TokenNumber is not 0 and is not in the token space specified by Guid, then ASSERT().
+
+  @param[in]  Guid        Pointer to a 128-bit unique value that designates which namespace 
+                          to set a value from.  If NULL, then the default token space is used.
+  @param[in]  TokenNumber The previous PCD token number.  If 0, then retrieves the first PCD 
+                          token number.
+
+  @return The next valid token number.
+
+**/
+UINTN           
+EFIAPI
+LibPcdGetNextToken (
+  IN CONST GUID               *Guid,       OPTIONAL
+  IN UINTN                    TokenNumber
+  );
+
+
+
+/**
+  Used to retrieve the list of available PCD token space GUIDs.
+  
+  Returns the PCD token space GUID that follows TokenSpaceGuid in the list of token spaces
+  in the platform.
+  If TokenSpaceGuid is NULL, then a pointer to the first PCD token spaces returned.
+  If TokenSpaceGuid is the last PCD token space GUID in the list, then NULL is returned.
+  
+  @param  TokenSpaceGuid  Pointer to the a PCD token space GUID
+
+  @return The next valid token namespace.
+
+**/
+GUID *
+EFIAPI
+LibPcdGetNextTokenSpace (
+  IN CONST GUID  *TokenSpaceGuid
+  );
+
+
+/**
+  Sets a value of a patchable PCD entry that is type pointer.
+  
+  Sets the PCD entry specified by PatchVariable to the value specified by Buffer 
+  and SizeOfBuffer.  Buffer is returned.  If SizeOfBuffer is greater than 
+  MaximumDatumSize, then set SizeOfBuffer to MaximumDatumSize and return 
+  NULL to indicate that the set operation was not actually performed.  
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to 
+  MaximumDatumSize and NULL must be returned.
+  
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module that is 
+                                the target of the set operation.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the target variable.
+  
+  @return Return the pointer to the Buffer that was set.
+
+**/
+VOID *
+EFIAPI
+LibPatchPcdSetPtr (
+  OUT        VOID       *PatchVariable,
+  IN        UINTN       MaximumDatumSize,
+  IN OUT    UINTN       *SizeOfBuffer,
+  IN CONST  VOID        *Buffer
+  );
+
+/**
+  Sets a value of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified
+  by Buffer and SizeOfBuffer. If SizeOfBuffer is greater than MaximumDatumSize,
+  then set SizeOfBuffer to MaximumDatumSize and return RETURN_INVALID_PARAMETER
+  to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and RETURN_INVALID_PARAMETER must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module that is
+                                the target of the set operation.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the target variable.
+  
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPatchPcdSetPtrS (
+  OUT      VOID     *PatchVariable,
+  IN       UINTN    MaximumDatumSize,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN CONST VOID     *Buffer
+  );
+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+  
+  Sets the PCD entry specified by PatchVariable to the value specified by Buffer 
+  and SizeOfBuffer. Buffer is returned.  If SizeOfBuffer is greater than 
+  MaximumDatumSize, then set SizeOfBuffer to MaximumDatumSize and return 
+  NULL to indicate that the set operation was not actually performed.  
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to 
+  MaximumDatumSize and NULL must be returned.
+  
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module that is 
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the target variable.
+  
+  @return Return the pointer to the Buffer that was set.
+
+**/
+VOID *
+EFIAPI
+LibPatchPcdSetPtrAndSize (
+  OUT       VOID        *PatchVariable,
+  OUT       UINTN       *SizeOfPatchVariable,
+  IN        UINTN       MaximumDatumSize,
+  IN OUT    UINTN       *SizeOfBuffer,
+  IN CONST  VOID        *Buffer
+  );
+
+/**
+  Sets a value and size of a patchable PCD entry that is type pointer.
+
+  Sets the PCD entry specified by PatchVariable to the value specified
+  by Buffer and SizeOfBuffer. If SizeOfBuffer is greater than MaximumDatumSize,
+  then set SizeOfBuffer to MaximumDatumSize and return RETURN_INVALID_PARAMETER
+  to indicate that the set operation was not actually performed.
+  If SizeOfBuffer is set to MAX_ADDRESS, then SizeOfBuffer must be set to
+  MaximumDatumSize and RETURN_INVALID_PARAMETER must be returned.
+
+  If PatchVariable is NULL, then ASSERT().
+  If SizeOfPatchVariable is NULL, then ASSERT().
+  If SizeOfBuffer is NULL, then ASSERT().
+  If SizeOfBuffer > 0 and Buffer is NULL, then ASSERT().
+
+  @param[out] PatchVariable     A pointer to the global variable in a module that is
+                                the target of the set operation.
+  @param[out] SizeOfPatchVariable A pointer to the size, in bytes, of PatchVariable.
+  @param[in] MaximumDatumSize   The maximum size allowed for the PCD entry specified by PatchVariable.
+  @param[in, out] SizeOfBuffer  A pointer to the size, in bytes, of Buffer.
+  @param[in] Buffer             A pointer to the buffer to used to set the target variable.
+  
+  @return The status of the set operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+LibPatchPcdSetPtrAndSizeS (
+  OUT      VOID     *PatchVariable,
+  OUT      UINTN    *SizeOfPatchVariable,
+  IN       UINTN    MaximumDatumSize,
+  IN OUT   UINTN    *SizeOfBuffer,
+  IN CONST VOID     *Buffer
+  );
+
+typedef enum {
+  PCD_TYPE_8,
+  PCD_TYPE_16,
+  PCD_TYPE_32,
+  PCD_TYPE_64,
+  PCD_TYPE_BOOL,
+  PCD_TYPE_PTR
+} PCD_TYPE;
+
+typedef struct {
+  ///
+  /// The returned information associated with the requested TokenNumber. If
+  /// TokenNumber is 0, then PcdType is set to PCD_TYPE_8.
+  ///
+  PCD_TYPE          PcdType;
+  ///
+  /// The size of the data in bytes associated with the TokenNumber specified. If
+  /// TokenNumber is 0, then PcdSize is set 0.
+  ///
+  UINTN             PcdSize;
+  ///
+  /// The null-terminated ASCII string associated with a given token. If the
+  /// TokenNumber specified was 0, then this field corresponds to the null-terminated
+  /// ASCII string associated with the token's namespace Guid. If NULL, there is no
+  /// name associated with this request.
+  ///
+  CHAR8             *PcdName;
+} PCD_INFO;
+
+
+/**
+  Retrieve additional information associated with a PCD token.
+
+  This includes information such as the type of value the TokenNumber is associated with as well as possible
+  human readable name that is associated with the token.
+
+  If TokenNumber is not in the default token space specified, then ASSERT().
+
+  @param[in]    TokenNumber The PCD token number.
+  @param[out]   PcdInfo     The returned information associated with the requested TokenNumber.
+                            The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfo (
+  IN        UINTN           TokenNumber,
+  OUT       PCD_INFO        *PcdInfo
+  );
+
+/**
+  Retrieve additional information associated with a PCD token.
+
+  This includes information such as the type of value the TokenNumber is associated with as well as possible
+  human readable name that is associated with the token.
+
+  If TokenNumber is not in the token space specified by Guid, then ASSERT().
+
+  @param[in]    Guid        The 128-bit unique value that designates the namespace from which to extract the value.
+  @param[in]    TokenNumber The PCD token number.
+  @param[out]   PcdInfo     The returned information associated with the requested TokenNumber.
+                            The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfoEx (
+  IN CONST  GUID            *Guid,
+  IN        UINTN           TokenNumber,
+  OUT       PCD_INFO        *PcdInfo
+  );
+
+/**
+  Retrieve the currently set SKU Id.
+
+  @return   The currently set SKU Id. If the platform has not set at a SKU Id, then the
+            default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+            Id is returned.
+**/
+UINTN
+EFIAPI
+LibPcdGetSku (
+  VOID
+  );
+
+#endif
diff --git a/sys/contrib/edk2/Include/Library/PrintLib.h b/sys/contrib/edk2/Include/Library/PrintLib.h
new file mode 100644
index 0000000000..1ffcfaea73
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/PrintLib.h
@@ -0,0 +1,1051 @@
+/** @file
+  Provides services to print a formatted string to a buffer. All combinations of
+  Unicode and ASCII strings are supported.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that 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.
+
+  The Print Library functions provide a simple means to produce formatted output 
+  strings.  Many of the output functions use a format string to describe how to 
+  format the output of variable arguments.  The format string consists of normal 
+  text and argument descriptors.  There are no restrictions for how the normal 
+  text and argument descriptors can be mixed.  The following end of line(EOL) 
+  translations must be performed on the contents of the format string:
+  
+     - '\\r' is translated to '\\r'
+     - '\\r\\n' is translated to '\\r\\n'
+     - '\\n' is translated to '\\r\\n' 
+     - '\\n\\r' is translated to '\\r\\n'
+  
+  This does not follow the ANSI C standard for sprint().  The format of argument 
+  descriptors is described below.  The ANSI C standard for sprint() has been 
+  followed for some of the format types, and has not been followed for others.  
+  The exceptions are noted below.
+
+    %[flags][width][.precision]type
+
+  [flags]:
+    - -       
+      - The field is left justified.  If not flag is not specified, then the 
+        field is right justified.
+    - space   
+      - Prefix a space character to a number.  Only valid for types X, x, and d.
+    - + 
+      - Prefix a plus character to a number.  Only valid for types X, x, and d.  
+        If both space and + are specified, then space is ignored.
+    - 0
+      - Pad with 0 characters to the left of a number.  Only valid for types 
+        X, x, and d.
+    - ,
+      - Place a comma every 3rd digit of the number.  Only valid for type d.
+        If 0 is also specified, then 0 is ignored.
+    - L, l
+      - The number being printed is size UINT64.  Only valid for types X, x, and d.
+        If this flag is not specified, then the number being printed is size int.
+    - NOTE: All invalid flags are ignored.
+
+  [width]:
+
+    - *
+      - The width of the field is specified by a UINTN argument in the 
+        argument list.
+    - number
+      - The number specified as a decimal value represents the width of 
+        the field.
+    - NOTE: If [width] is not specified, then a field width of 0 is assumed.
+
+  [.precision]:
+
+    - *
+      - The precision of the field is specified by a UINTN argument in the 
+        argument list.
+    - number
+      - The number specified as a decimal value represents the precision of 
+        the field.
+    - NOTE: If [.precision] is not specified, then a precision of 0 is assumed.
+
+  type:
+
+    - %
+      - Print a %%.
+    - c
+      - The argument is a Unicode character.  ASCII characters can be printed 
+        using this type too by making sure bits 8..15 of the argument are set to 0.
+    - x
+      - The argument is an unsigned hexadecimal number.  The characters used are 0..9 and 
+        A..F.  If the flag 'L' is not specified, then the argument is assumed 
+        to be size int.  This does not follow ANSI C.
+    - X
+      - The argument is an unsigned hexadecimal number and the number is padded with 
+        zeros.  This is equivalent to a format string of "0x". If the flag 
+        'L' is not specified, then the argument is assumed to be size int.  
+        This does not follow ANSI C.
+    - d
+      - The argument is a signed decimal number.  If the flag 'L' is not specified, 
+        then the argument is assumed to be size int.  
+    - u
+      - The argument is a unsigned decimal number.  If the flag 'L' is not specified, 
+        then the argument is assumed to be size int.
+    - p
+      - The argument is a pointer that is a (VOID *), and it is printed as an 
+        unsigned hexadecimal number  The characters used are 0..9 and A..F.
+    - a
+      - The argument is a pointer to an ASCII string.  
+        This does not follow ANSI C.
+    - S, s
+      - The argument is a pointer to a Unicode string.  
+        This does not follow ANSI C.
+    - g
+      - The argument is a pointer to a GUID structure.  The GUID is printed 
+        in the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.  
+        This does not follow ANSI C.
+    - t
+      - The argument is a pointer to an EFI_TIME structure.  The time and 
+        date are printed in the format "mm/dd/yyyy hh:mm" where mm is the 
+        month zero padded, dd is the day zero padded, yyyy is the year zero 
+        padded, hh is the hour zero padded, and mm is minutes zero padded.  
+        This does not follow ANSI C. 
+    - r
+      - The argument is a RETURN_STATUS value.  This value is converted to 
+        a string following the table below.  This does not follow ANSI C. 
+      - RETURN_SUCCESS               
+        - "Success"
+      - RETURN_LOAD_ERROR            
+        - "Load Error"
+      - RETURN_INVALID_PARAMETER     
+        - "Invalid Parameter"
+      - RETURN_UNSUPPORTED           
+        - "Unsupported"
+      - RETURN_BAD_BUFFER_SIZE       
+        - "Bad Buffer Size"
+      - RETURN_BUFFER_TOO_SMALL      
+        - "Buffer Too Small"
+      - RETURN_NOT_READY             
+        - "Not Ready"
+      - RETURN_DEVICE_ERROR          
+        - "Device Error"
+      - RETURN_WRITE_PROTECTED       
+        - "Write Protected"
+      - RETURN_OUT_OF_RESOURCES      
+        - "Out of Resources"
+      - RETURN_VOLUME_CORRUPTED      
+        - "Volume Corrupt"
+      - RETURN_VOLUME_FULL           
+        - "Volume Full"
+      - RETURN_NO_MEDIA              
+        - "No Media"
+      - RETURN_MEDIA_CHANGED         
+        - "Media changed"
+      - RETURN_NOT_FOUND             
+        - "Not Found"
+      - RETURN_ACCESS_DENIED         
+        - "Access Denied"
+      - RETURN_NO_RESPONSE           
+        - "No Response"
+      - RETURN_NO_MAPPING            
+        - "No mapping"
+      - RETURN_TIMEOUT               
+        - "Time out"
+      - RETURN_NOT_STARTED           
+        - "Not started"
+      - RETURN_ALREADY_STARTED       
+        - "Already started"
+      - RETURN_ABORTED               
+        - "Aborted"
+      - RETURN_ICMP_ERROR            
+        - "ICMP Error"
+      - RETURN_TFTP_ERROR            
+        - "TFTP Error"
+      - RETURN_PROTOCOL_ERROR        
+        - "Protocol Error"
+      - RETURN_WARN_UNKNOWN_GLYPH    
+        - "Warning Unknown Glyph"
+      - RETURN_WARN_DELETE_FAILURE   
+        - "Warning Delete Failure"
+      - RETURN_WARN_WRITE_FAILURE    
+        - "Warning Write Failure"
+      - RETURN_WARN_BUFFER_TOO_SMALL 
+        - "Warning Buffer Too Small"
+
+**/
+
+#ifndef __PRINT_LIB_H__
+#define __PRINT_LIB_H__
+
+///
+/// Define the maximum number of characters that are required to
+/// encode with a NULL terminator a decimal, hexadecimal, GUID,   
+/// or TIME value.
+///  
+///  Maximum Length Decimal String     = 28
+///    "-9,223,372,036,854,775,808"
+///  Maximum Length Hexadecimal String = 17
+///    "FFFFFFFFFFFFFFFF"
+///  Maximum Length GUID               = 37
+///    "00000000-0000-0000-0000-000000000000"
+///  Maximum Length TIME               = 18
+///    "12/12/2006  12:12"
+///
+#define MAXIMUM_VALUE_CHARACTERS  38
+
+///
+/// Flags bitmask values use in UnicodeValueToString() and 
+/// AsciiValueToString()
+///
+#define LEFT_JUSTIFY      0x01
+#define COMMA_TYPE        0x08
+#define PREFIX_ZERO       0x20
+#define RADIX_HEX         0x80
+
+/**
+  Produces a Null-terminated Unicode string in an output buffer based on
+  a Null-terminated Unicode format string and a VA_LIST argument list.
+
+  This function is similar as vsnprintf_s defined in C11.
+
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The Unicode string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on the
+  contents of the format string.
+  The number of Unicode characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
+  (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
+  buffer is unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          Unicode string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated Unicode format string.
+  @param  Marker          VA_LIST marker for the variable argument list.
+
+  @return The number of Unicode characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeVSPrint (
+  OUT CHAR16        *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR16  *FormatString,
+  IN  VA_LIST       Marker
+  );
+
+/**
+  Produces a Null-terminated Unicode string in an output buffer based on
+  a Null-terminated Unicode format string and a BASE_LIST argument list.
+
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The Unicode string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on the
+  contents of the format string.
+  The number of Unicode characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
+  (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
+  buffer is unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          Unicode string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated Unicode format string.
+  @param  Marker          BASE_LIST marker for the variable argument list.
+
+  @return The number of Unicode characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeBSPrint (
+  OUT CHAR16        *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR16  *FormatString,
+  IN  BASE_LIST     Marker
+  );
+
+/**
+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
+  Unicode format string and variable argument list.
+
+  This function is similar as snprintf_s defined in C11.
+
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The Unicode string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list based on the contents of the format string.
+  The number of Unicode characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
+  (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
+  buffer is unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          Unicode string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated Unicode format string.
+  @param  ...             Variable argument list whose contents are accessed based on the
+                          format string specified by FormatString.
+
+  @return The number of Unicode characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeSPrint (
+  OUT CHAR16        *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR16  *FormatString,
+  ...
+  );
+
+/**
+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
+  ASCII format string and a VA_LIST argument list.
+
+  This function is similar as vsnprintf_s defined in C11.
+
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The Unicode string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on the
+  contents of the format string.
+  The number of Unicode characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
+  (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
+  buffer is unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
+  PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          Unicode string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated ASCII format string.
+  @param  Marker          VA_LIST marker for the variable argument list.
+
+  @return The number of Unicode characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeVSPrintAsciiFormat (
+  OUT CHAR16       *StartOfBuffer,
+  IN  UINTN        BufferSize,
+  IN  CONST CHAR8  *FormatString,
+  IN  VA_LIST      Marker
+  );
+
+/**
+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
+  ASCII format string and a BASE_LIST argument list.
+
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The Unicode string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on the
+  contents of the format string.
+  The number of Unicode characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
+  (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
+  buffer is unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
+  PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          Unicode string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated ASCII format string.
+  @param  Marker          BASE_LIST marker for the variable argument list.
+
+  @return The number of Unicode characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeBSPrintAsciiFormat (
+  OUT CHAR16       *StartOfBuffer,
+  IN  UINTN        BufferSize,
+  IN  CONST CHAR8  *FormatString,
+  IN  BASE_LIST    Marker
+  );
+
+/**
+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
+  ASCII format string and  variable argument list.
+
+  This function is similar as snprintf_s defined in C11.
+
+  Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The Unicode string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list based on the contents of the
+  format string.
+  The number of Unicode characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
+  (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
+  buffer is unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
+  PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          Unicode string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated ASCII format string.
+  @param  ...             Variable argument list whose contents are accessed based on the
+                          format string specified by FormatString.
+
+  @return The number of Unicode characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeSPrintAsciiFormat (
+  OUT CHAR16       *StartOfBuffer,
+  IN  UINTN        BufferSize,
+  IN  CONST CHAR8  *FormatString,
+  ...
+  );
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Converts a decimal value to a Null-terminated Unicode string.
+  
+  Converts the decimal number specified by Value to a Null-terminated Unicode 
+  string specified by Buffer containing at most Width characters. No padding of spaces 
+  is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
+  The number of Unicode characters in Buffer is returned, not including the Null-terminator.
+  If the conversion contains more than Width characters, then only the first
+  Width characters are returned, and the total number of characters 
+  required to perform the conversion is returned.
+  Additional conversion parameters are specified in Flags.  
+  
+  The Flags bit LEFT_JUSTIFY is always ignored.
+  All conversions are left justified in Buffer.
+  If Width is 0, PREFIX_ZERO is ignored in Flags.
+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
+  are inserted every 3rd digit starting from the right.
+  If RADIX_HEX is set in Flags, then the output buffer will be 
+  formatted in hexadecimal format.
+  If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 
+  then Buffer is padded with '0' characters so the combination of the optional '-' 
+  sign character, '0' characters, digit characters for Value, and the Null-terminator
+  add up to Width characters.
+  If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
+  If Buffer is NULL, then ASSERT().
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+  If unsupported bits are set in Flags, then ASSERT().
+  If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
+
+  @param  Buffer  The pointer to the output buffer for the produced Null-terminated
+                  Unicode string.
+  @param  Flags   The bitmask of flags that specify left justification, zero pad, and commas.
+  @param  Value   The 64-bit signed value to convert to a string.
+  @param  Width   The maximum number of Unicode characters to place in Buffer, not including
+                  the Null-terminator.
+  
+  @return The number of Unicode characters in Buffer, not including the Null-terminator.
+
+**/
+UINTN
+EFIAPI
+UnicodeValueToString (
+  IN OUT CHAR16  *Buffer,
+  IN UINTN       Flags,
+  IN INT64       Value,
+  IN UINTN       Width
+  );
+
+#endif
+
+/**
+  Converts a decimal value to a Null-terminated Unicode string.
+
+  Converts the decimal number specified by Value to a Null-terminated Unicode
+  string specified by Buffer containing at most Width characters. No padding of
+  spaces is ever performed. If Width is 0 then a width of
+  MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
+  Width characters, then only the first Width characters are placed in Buffer.
+  Additional conversion parameters are specified in Flags.
+
+  The Flags bit LEFT_JUSTIFY is always ignored.
+  All conversions are left justified in Buffer.
+  If Width is 0, PREFIX_ZERO is ignored in Flags.
+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
+  commas are inserted every 3rd digit starting from the right.
+  If RADIX_HEX is set in Flags, then the output buffer will be formatted in
+  hexadecimal format.
+  If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
+  Buffer is a '-'.
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
+  Buffer is padded with '0' characters so the combination of the optional '-'
+  sign character, '0' characters, digit characters for Value, and the
+  Null-terminator add up to Width characters.
+
+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().
+  If an error would be returned, then the function will also ASSERT().
+
+  @param  Buffer      The pointer to the output buffer for the produced
+                      Null-terminated Unicode string.
+  @param  BufferSize  The size of Buffer in bytes, including the
+                      Null-terminator.
+  @param  Flags       The bitmask of flags that specify left justification,
+                      zero pad, and commas.
+  @param  Value       The 64-bit signed value to convert to a string.
+  @param  Width       The maximum number of Unicode characters to place in
+                      Buffer, not including the Null-terminator.
+
+  @retval RETURN_SUCCESS           The decimal value is converted.
+  @retval RETURN_BUFFER_TOO_SMALL  If BufferSize cannot hold the converted
+                                   value.
+  @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
+                                   If PcdMaximumUnicodeStringLength is not
+                                   zero, and BufferSize is greater than
+                                   (PcdMaximumUnicodeStringLength *
+                                   sizeof (CHAR16) + 1).
+                                   If unsupported bits are set in Flags.
+                                   If both COMMA_TYPE and RADIX_HEX are set in
+                                   Flags.
+                                   If Width >= MAXIMUM_VALUE_CHARACTERS.
+
+**/
+RETURN_STATUS
+EFIAPI
+UnicodeValueToStringS (
+  IN OUT CHAR16  *Buffer,
+  IN UINTN       BufferSize,
+  IN UINTN       Flags,
+  IN INT64       Value,
+  IN UINTN       Width
+  );
+
+/**
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
+  ASCII format string and a VA_LIST argument list.
+
+  This function is similar as vsnprintf_s defined in C11.
+
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The ASCII string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on
+  the contents of the format string.
+  The number of ASCII characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and BufferSize >
+  (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
+  is unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
+  PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          ASCII string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated ASCII format string.
+  @param  Marker          VA_LIST marker for the variable argument list.
+
+  @return The number of ASCII characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiVSPrint (
+  OUT CHAR8         *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR8   *FormatString,
+  IN  VA_LIST       Marker
+  );
+
+/**
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
+  ASCII format string and a BASE_LIST argument list.
+
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The ASCII string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on
+  the contents of the format string.
+  The number of ASCII characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and BufferSize >
+  (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
+  is unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
+  PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          ASCII string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated ASCII format string.
+  @param  Marker          BASE_LIST marker for the variable argument list.
+
+  @return The number of ASCII characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiBSPrint (
+  OUT CHAR8         *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR8   *FormatString,
+  IN  BASE_LIST     Marker
+  );
+
+/**
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
+  ASCII format string and  variable argument list.
+
+  This function is similar as snprintf_s defined in C11.
+
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The ASCII string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list based on the contents of the
+  format string.
+  The number of ASCII characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and BufferSize >
+  (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
+  is unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
+  PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          ASCII string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated ASCII format string.
+  @param  ...             Variable argument list whose contents are accessed based on the
+                          format string specified by FormatString.
+
+  @return The number of ASCII characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiSPrint (
+  OUT CHAR8        *StartOfBuffer,
+  IN  UINTN        BufferSize,
+  IN  CONST CHAR8  *FormatString,
+  ...
+  );
+
+/**
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
+  Unicode format string and a VA_LIST argument list.
+
+  This function is similar as vsnprintf_s defined in C11.
+
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The ASCII string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on
+  the contents of the format string.
+  The number of ASCII characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and BufferSize >
+  (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
+  is unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          ASCII string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated Unicode format string.
+  @param  Marker          VA_LIST marker for the variable argument list.
+
+  @return The number of ASCII characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiVSPrintUnicodeFormat (
+  OUT CHAR8         *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR16  *FormatString,
+  IN  VA_LIST       Marker
+  );
+
+/**
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
+  Unicode format string and a BASE_LIST argument list.
+
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The ASCII string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list specified by Marker based on
+  the contents of the format string.
+  The number of ASCII characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and BufferSize >
+  (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
+  is unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          ASCII string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated Unicode format string.
+  @param  Marker          BASE_LIST marker for the variable argument list.
+
+  @return The number of ASCII characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiBSPrintUnicodeFormat (
+  OUT CHAR8         *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR16  *FormatString,
+  IN  BASE_LIST     Marker
+  );
+
+/**
+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
+  Unicode format string and  variable argument list.
+
+  This function is similar as snprintf_s defined in C11.
+
+  Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
+  and BufferSize.
+  The ASCII string is produced by parsing the format string specified by FormatString.
+  Arguments are pulled from the variable argument list based on the contents of the
+  format string.
+  The number of ASCII characters in the produced output buffer is returned not including
+  the Null-terminator.
+
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
+  unmodified and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and BufferSize >
+  (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
+  is unmodified and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
+  ASSERT(). Also, the output buffer is unmodified and 0 is returned.
+
+  If BufferSize is 0, then no output buffer is produced and 0 is returned.
+
+  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
+                          ASCII string.
+  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
+  @param  FormatString    A Null-terminated Unicode format string.
+  @param  ...             Variable argument list whose contents are accessed based on the
+                          format string specified by FormatString.
+
+  @return The number of ASCII characters in the produced output buffer not including the
+          Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiSPrintUnicodeFormat (
+  OUT CHAR8         *StartOfBuffer,
+  IN  UINTN         BufferSize,
+  IN  CONST CHAR16  *FormatString,
+  ...
+  );
+
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
+/**
+  [ATTENTION] This function is deprecated for security reason.
+
+  Converts a decimal value to a Null-terminated ASCII string.
+  
+  Converts the decimal number specified by Value to a Null-terminated ASCII string 
+  specified by Buffer containing at most Width characters. No padding of spaces 
+  is ever performed.
+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.
+  The number of ASCII characters in Buffer is returned, not including the Null-terminator.
+  If the conversion contains more than Width characters, then only the first Width
+  characters are returned, and the total number of characters required to perform
+  the conversion is returned.
+  Additional conversion parameters are specified in Flags.  
+  The Flags bit LEFT_JUSTIFY is always ignored.
+  All conversions are left justified in Buffer.
+  If Width is 0, PREFIX_ZERO is ignored in Flags.
+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
+  are inserted every 3rd digit starting from the right.
+  If RADIX_HEX is set in Flags, then the output buffer will be 
+  formatted in hexadecimal format.
+  If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 
+  then Buffer is padded with '0' characters so the combination of the optional '-' 
+  sign character, '0' characters, digit characters for Value, and the Null-terminator
+  add up to Width characters.
+  
+  If Buffer is NULL, then ASSERT().
+  If unsupported bits are set in Flags, then ASSERT().
+  If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
+  If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
+
+  @param  Buffer  A pointer to the output buffer for the produced Null-terminated
+                  ASCII string.
+  @param  Flags   The bitmask of flags that specify left justification, zero pad, and commas.
+  @param  Value   The 64-bit signed value to convert to a string.
+  @param  Width   The maximum number of ASCII characters to place in Buffer, not including
+                  the Null-terminator.
+  
+  @return The number of ASCII characters in Buffer, not including the Null-terminator.
+
+**/
+UINTN
+EFIAPI
+AsciiValueToString (
+  OUT CHAR8      *Buffer,
+  IN  UINTN      Flags,
+  IN  INT64      Value,
+  IN  UINTN      Width
+  );
+
+#endif
+
+/**
+  Converts a decimal value to a Null-terminated Ascii string.
+
+  Converts the decimal number specified by Value to a Null-terminated Ascii
+  string specified by Buffer containing at most Width characters. No padding of
+  spaces is ever performed. If Width is 0 then a width of
+  MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
+  Width characters, then only the first Width characters are placed in Buffer.
+  Additional conversion parameters are specified in Flags.
+
+  The Flags bit LEFT_JUSTIFY is always ignored.
+  All conversions are left justified in Buffer.
+  If Width is 0, PREFIX_ZERO is ignored in Flags.
+  If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
+  commas are inserted every 3rd digit starting from the right.
+  If RADIX_HEX is set in Flags, then the output buffer will be formatted in
+  hexadecimal format.
+  If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
+  Buffer is a '-'.
+  If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
+  Buffer is padded with '0' characters so the combination of the optional '-'
+  sign character, '0' characters, digit characters for Value, and the
+  Null-terminator add up to Width characters.
+
+  If an error would be returned, then the function will ASSERT().
+
+  @param  Buffer      The pointer to the output buffer for the produced
+                      Null-terminated Ascii string.
+  @param  BufferSize  The size of Buffer in bytes, including the
+                      Null-terminator.
+  @param  Flags       The bitmask of flags that specify left justification,
+                      zero pad, and commas.
+  @param  Value       The 64-bit signed value to convert to a string.
+  @param  Width       The maximum number of Ascii characters to place in
+                      Buffer, not including the Null-terminator.
+
+  @retval RETURN_SUCCESS           The decimal value is converted.
+  @retval RETURN_BUFFER_TOO_SMALL  If BufferSize cannot hold the converted
+                                   value.
+  @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
+                                   If PcdMaximumAsciiStringLength is not
+                                   zero, and BufferSize is greater than
+                                   PcdMaximumAsciiStringLength.
+                                   If unsupported bits are set in Flags.
+                                   If both COMMA_TYPE and RADIX_HEX are set in
+                                   Flags.
+                                   If Width >= MAXIMUM_VALUE_CHARACTERS.
+
+**/
+RETURN_STATUS
+EFIAPI
+AsciiValueToStringS (
+  IN OUT CHAR8   *Buffer,
+  IN UINTN       BufferSize,
+  IN UINTN       Flags,
+  IN INT64       Value,
+  IN UINTN       Width
+  );
+
+/**
+  Returns the number of characters that would be produced by if the formatted 
+  output were produced not including the Null-terminator.
+
+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().
+
+  If FormatString is NULL, then ASSERT() and 0 is returned.
+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more
+  than PcdMaximumUnicodeStringLength Unicode characters not including the
+  Null-terminator, then ASSERT() and 0 is returned.
+
+  @param[in]  FormatString    A Null-terminated Unicode format string.
+  @param[in]  Marker          VA_LIST marker for the variable argument list.
+
+  @return The number of characters that would be produced, not including the 
+          Null-terminator.
+**/
+UINTN
+EFIAPI
+SPrintLength (
+  IN  CONST CHAR16   *FormatString,
+  IN  VA_LIST       Marker
+  );
+
+/**
+  Returns the number of characters that would be produced by if the formatted 
+  output were produced not including the Null-terminator.
+
+  If FormatString is NULL, then ASSERT() and 0 is returned.
+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more
+  than PcdMaximumAsciiStringLength Ascii characters not including the
+  Null-terminator, then ASSERT() and 0 is returned.
+
+  @param[in]  FormatString    A Null-terminated ASCII format string.
+  @param[in]  Marker          VA_LIST marker for the variable argument list.
+
+  @return The number of characters that would be produced, not including the 
+          Null-terminator.
+**/
+UINTN
+EFIAPI
+SPrintLengthAsciiFormat (
+  IN  CONST CHAR8   *FormatString,
+  IN  VA_LIST       Marker
+  );
+
+#endif
diff --git a/sys/contrib/edk2/Include/Library/UefiBootServicesTableLib.h b/sys/contrib/edk2/Include/Library/UefiBootServicesTableLib.h
new file mode 100644
index 0000000000..b382a8d51e
--- /dev/null
+++ b/sys/contrib/edk2/Include/Library/UefiBootServicesTableLib.h
@@ -0,0 +1,34 @@
+/** @file
+  Provides a service to retrieve a pointer to the EFI Boot Services Table.
+  Only available to DXE and UEFI module types.
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_BOOT_SERVICES_TABLE_LIB_H__
+#define __UEFI_BOOT_SERVICES_TABLE_LIB_H__
+
+///
+/// Cache the Image Handle
+///
+extern EFI_HANDLE         gImageHandle;
+
+///
+/// Cache pointer to the EFI System Table
+///
+extern EFI_SYSTEM_TABLE   *gST;
+
+///
+/// Cache pointer to the EFI Boot Services Table
+///
+extern EFI_BOOT_SERVICES  *gBS;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/DebugPort.h b/sys/contrib/edk2/Include/Protocol/DebugPort.h
new file mode 100644
index 0000000000..ba14591107
--- /dev/null
+++ b/sys/contrib/edk2/Include/Protocol/DebugPort.h
@@ -0,0 +1,146 @@
+/** @file
+  
+  The file defines the EFI Debugport protocol.
+  This protocol is used by debug agent to communicate with the
+  remote debug host.
+  
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __DEBUG_PORT_H__
+#define __DEBUG_PORT_H__
+
+
+///
+/// DebugPortIo protocol {EBA4E8D2-3858-41EC-A281-2647BA9660D0}
+///
+#define EFI_DEBUGPORT_PROTOCOL_GUID \
+  { \
+    0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \
+  }
+
+extern EFI_GUID gEfiDebugPortProtocolGuid;
+
+typedef struct _EFI_DEBUGPORT_PROTOCOL EFI_DEBUGPORT_PROTOCOL;
+
+//
+// DebugPort member functions
+//
+
+/**                                                                 
+  Resets the debugport.
+    
+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.
+                                
+  @retval EFI_SUCCESS           The debugport device was reset and is in usable state.
+  @retval EFI_DEVICE_ERROR      The debugport device could not be reset and is unusable.
+                                   
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DEBUGPORT_RESET)(
+  IN EFI_DEBUGPORT_PROTOCOL               *This
+  );
+
+/**                                                                 
+  Writes data to the debugport.
+    
+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.
+  @param  Timeout               The number of microseconds to wait before timing out a write operation.
+  @param  BufferSize            On input, the requested number of bytes of data to write. On output, the
+                                number of bytes of data actually written.
+  @param  Buffer                A pointer to a buffer containing the data to write.                                
+                                  
+  @retval EFI_SUCCESS           The data was written.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_TIMEOUT           The data write was stopped due to a timeout.
+                                   
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DEBUGPORT_WRITE)(
+  IN EFI_DEBUGPORT_PROTOCOL               *This,
+  IN UINT32                               Timeout,
+  IN OUT UINTN                            *BufferSize,
+  IN VOID                                 *Buffer
+  );
+
+/**                                                                 
+  Reads data from the debugport.
+    
+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.
+  @param  Timeout               The number of microseconds to wait before timing out a read operation.
+  @param  BufferSize            On input, the requested number of bytes of data to read. On output, the
+                                number of bytes of data actually number of bytes
+                                of data read and returned in Buffer.
+  @param  Buffer                A pointer to a buffer into which the data read will be saved.
+                                  
+  @retval EFI_SUCCESS           The data was read.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_TIMEOUT           The operation was stopped due to a timeout or overrun.
+                                   
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DEBUGPORT_READ)(
+  IN EFI_DEBUGPORT_PROTOCOL               *This,
+  IN UINT32                               Timeout,
+  IN OUT UINTN                            *BufferSize,
+  OUT VOID                                *Buffer
+  );
+
+/**                                                                 
+  Checks to see if any data is available to be read from the debugport device.
+    
+  @param  This                  A pointer to the EFI_DEBUGPORT_PROTOCOL instance.
+                                  
+  @retval EFI_SUCCESS           At least one byte of data is available to be read.
+  @retval EFI_DEVICE_ERROR      The debugport device is not functioning correctly.
+  @retval EFI_NOT_READY         No data is available to be read.
+                                   
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DEBUGPORT_POLL)(
+  IN EFI_DEBUGPORT_PROTOCOL               *This
+  );
+
+///
+/// This protocol provides the communication link between the debug agent and the remote host.
+///
+struct _EFI_DEBUGPORT_PROTOCOL {
+  EFI_DEBUGPORT_RESET Reset;
+  EFI_DEBUGPORT_WRITE Write;
+  EFI_DEBUGPORT_READ  Read;
+  EFI_DEBUGPORT_POLL  Poll;
+};
+
+//
+// DEBUGPORT variable definitions...
+//
+#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT"
+#define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID
+
+extern EFI_GUID  gEfiDebugPortVariableGuid;
+
+//
+// DebugPort device path definitions...
+//
+#define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID
+
+extern EFI_GUID  gEfiDebugPortDevicePathGuid;
+
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  EFI_GUID                  Guid;
+} DEBUGPORT_DEVICE_PATH;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/DevicePath.h b/sys/contrib/edk2/Include/Protocol/DevicePath.h
new file mode 100644
index 0000000000..1958a3dd18
--- /dev/null
+++ b/sys/contrib/edk2/Include/Protocol/DevicePath.h
@@ -0,0 +1,1331 @@
+/** @file
+  The device path protocol as defined in UEFI 2.0.
+
+  The device path represents a programmatic path to a device,
+  from a software point of view. The path must persist from boot to boot, so 
+  it can not contain things like PCI bus numbers that change from boot to boot.
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.                                          
+    
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.              
+
+**/
+
+#ifndef __EFI_DEVICE_PATH_PROTOCOL_H__
+#define __EFI_DEVICE_PATH_PROTOCOL_H__
+
+#include <Guid/PcAnsi.h>
+#include <IndustryStandard/Bluetooth.h>
+#include <IndustryStandard/Acpi60.h>
+
+///
+/// Device Path protocol.
+///
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+  { \
+    0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+///
+/// Device Path guid definition for backward-compatible with EFI1.1.
+///
+#define DEVICE_PATH_PROTOCOL  EFI_DEVICE_PATH_PROTOCOL_GUID
+
+#pragma pack(1)
+
+/**
+  This protocol can be used on any device handle to obtain generic path/location 
+  information concerning the physical device or logical device. If the handle does 
+  not logically map to a physical device, the handle may not necessarily support 
+  the device path protocol. The device path describes the location of the device 
+  the handle is for. The size of the Device Path can be determined from the structures 
+  that make up the Device Path.
+**/
+typedef struct {
+  UINT8 Type;       ///< 0x01 Hardware Device Path.
+                    ///< 0x02 ACPI Device Path.
+                    ///< 0x03 Messaging Device Path.
+                    ///< 0x04 Media Device Path.
+                    ///< 0x05 BIOS Boot Specification Device Path.
+                    ///< 0x7F End of Hardware Device Path.
+                    
+  UINT8 SubType;    ///< Varies by Type
+                    ///< 0xFF End Entire Device Path, or
+                    ///< 0x01 End This Instance of a Device Path and start a new
+                    ///< Device Path.
+                    
+  UINT8 Length[2];  ///< Specific Device Path data. Type and Sub-Type define
+                    ///< type of data. Size of data is included in Length.
+                    
+} EFI_DEVICE_PATH_PROTOCOL;
+
+///
+/// Device Path protocol definition for backward-compatible with EFI1.1.
+/// 
+typedef EFI_DEVICE_PATH_PROTOCOL  EFI_DEVICE_PATH;
+
+///
+/// Hardware Device Paths.
+///
+#define HARDWARE_DEVICE_PATH      0x01
+
+///
+/// PCI Device Path SubType.
+///
+#define HW_PCI_DP                 0x01
+
+///
+/// PCI Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// PCI Function Number.
+  ///
+  UINT8                           Function;
+  ///
+  /// PCI Device Number.
+  ///
+  UINT8                           Device;
+} PCI_DEVICE_PATH;
+
+///
+/// PCCARD Device Path SubType.
+///
+#define HW_PCCARD_DP              0x02
+
+///
+/// PCCARD Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Function Number (0 = First Function).
+  ///
+  UINT8                           FunctionNumber;
+} PCCARD_DEVICE_PATH;
+
+///
+/// Memory Mapped Device Path SubType.
+///
+#define HW_MEMMAP_DP              0x03
+
+///
+/// Memory Mapped Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// EFI_MEMORY_TYPE
+  ///
+  UINT32                          MemoryType;
+  ///
+  /// Starting Memory Address.
+  ///
+  EFI_PHYSICAL_ADDRESS            StartingAddress;
+  ///
+  /// Ending Memory Address.
+  ///
+  EFI_PHYSICAL_ADDRESS            EndingAddress;
+} MEMMAP_DEVICE_PATH;
+
+///
+/// Hardware Vendor Device Path SubType.
+///
+#define HW_VENDOR_DP              0x04
+
+///
+/// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must
+/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the
+/// contents on the n bytes that follow in the Vendor Device Path node.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Vendor-assigned GUID that defines the data that follows.
+  ///
+  EFI_GUID                        Guid;
+  ///
+  /// Vendor-defined variable size data.
+  ///
+} VENDOR_DEVICE_PATH;
+
+///
+/// Controller Device Path SubType.
+///
+#define HW_CONTROLLER_DP          0x05
+
+///
+/// Controller Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Controller number.
+  ///
+  UINT32                          ControllerNumber;
+} CONTROLLER_DEVICE_PATH;
+
+///
+/// BMC Device Path SubType.
+///
+#define HW_BMC_DP                 0x06
+
+///
+/// BMC Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Interface Type.
+  ///
+  UINT8                           InterfaceType;
+  ///
+  /// Base Address.
+  ///
+  UINT8                           BaseAddress[8];
+} BMC_DEVICE_PATH;
+
+///
+/// ACPI Device Paths.
+///
+#define ACPI_DEVICE_PATH          0x02
+
+///
+/// ACPI Device Path SubType.
+///
+#define ACPI_DP                   0x01
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Device's PnP hardware ID stored in a numeric 32-bit
+  /// compressed EISA-type ID. This value must match the
+  /// corresponding _HID in the ACPI name space.
+  ///
+  UINT32                          HID;
+  ///
+  /// Unique ID that is required by ACPI if two devices have the
+  /// same _HID. This value must also match the corresponding
+  /// _UID/_HID pair in the ACPI name space. Only the 32-bit
+  /// numeric value type of _UID is supported. Thus, strings must
+  /// not be used for the _UID in the ACPI name space.
+  ///
+  UINT32                          UID;
+} ACPI_HID_DEVICE_PATH;
+
+///
+/// Expanded ACPI Device Path SubType.
+///
+#define ACPI_EXTENDED_DP          0x02
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Device's PnP hardware ID stored in a numeric 32-bit
+  /// compressed EISA-type ID. This value must match the
+  /// corresponding _HID in the ACPI name space.
+  ///
+  UINT32                          HID;
+  ///
+  /// Unique ID that is required by ACPI if two devices have the
+  /// same _HID. This value must also match the corresponding
+  /// _UID/_HID pair in the ACPI name space.
+  ///
+  UINT32                          UID;
+  ///
+  /// Device's compatible PnP hardware ID stored in a numeric
+  /// 32-bit compressed EISA-type ID. This value must match at
+  /// least one of the compatible device IDs returned by the
+  /// corresponding _CID in the ACPI name space.
+  ///
+  UINT32                          CID;
+  ///
+  /// Optional variable length _HIDSTR.
+  /// Optional variable length _UIDSTR.
+  /// Optional variable length _CIDSTR.
+  ///
+} ACPI_EXTENDED_HID_DEVICE_PATH;
+
+//
+//  EISA ID Macro
+//  EISA ID Definition 32-bits
+//   bits[15:0] - three character compressed ASCII EISA ID.
+//   bits[31:16] - binary number
+//    Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
+//
+#define PNP_EISA_ID_CONST         0x41d0
+#define EISA_ID(_Name, _Num)      ((UINT32)((_Name) | (_Num) << 16))
+#define EISA_PNP_ID(_PNPId)       (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+#define EFI_PNP_ID(_PNPId)        (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
+
+#define PNP_EISA_ID_MASK          0xffff
+#define EISA_ID_TO_NUM(_Id)       ((_Id) >> 16)
+
+///
+/// ACPI _ADR Device Path SubType.
+///
+#define ACPI_ADR_DP               0x03
+
+///
+/// The _ADR device path is used to contain video output device attributes to support the Graphics
+/// Output Protocol. The device path can contain multiple _ADR entries if multiple video output
+/// devices are displaying the same output.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// _ADR value. For video output devices the value of this
+  /// field comes from Table B-2 of the ACPI 3.0 specification. At
+  /// least one _ADR value is required.
+  ///
+  UINT32                          ADR;
+  //
+  // This device path may optionally contain more than one _ADR entry.
+  //
+} ACPI_ADR_DEVICE_PATH;
+
+#define ACPI_ADR_DISPLAY_TYPE_OTHER             0
+#define ACPI_ADR_DISPLAY_TYPE_VGA               1
+#define ACPI_ADR_DISPLAY_TYPE_TV                2
+#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL  3
+#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL  4
+
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
+          ((UINT32)(  ((UINT32)((_DeviceIdScheme) & 0x1) << 31) |  \
+                      (((_HeadId)                 & 0x7) << 18) |  \
+                      (((_NonVgaOutput)           & 0x1) << 17) |  \
+                      (((_BiosCanDetect)          & 0x1) << 16) |  \
+                      (((_VendorInfo)             & 0xf) << 12) |  \
+                      (((_Type)                   & 0xf) << 8)  |  \
+                      (((_Port)                   & 0xf) << 4)  |  \
+                       ((_Index)                  & 0xf) ))
+
+///
+/// Messaging Device Paths.
+/// This Device Path is used to describe the connection of devices outside the resource domain of the
+/// system. This Device Path can describe physical messaging information like SCSI ID, or abstract
+/// information like networking protocol IP addresses.
+///
+#define MESSAGING_DEVICE_PATH     0x03
+
+///
+/// ATAPI Device Path SubType
+///
+#define MSG_ATAPI_DP              0x01
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Set to zero for primary, or one for secondary.
+  ///
+  UINT8                           PrimarySecondary;
+  ///
+  /// Set to zero for master, or one for slave mode.
+  ///
+  UINT8                           SlaveMaster;
+  ///
+  /// Logical Unit Number.
+  ///
+  UINT16                          Lun;
+} ATAPI_DEVICE_PATH;
+
+///
+/// SCSI Device Path SubType.
+///
+#define MSG_SCSI_DP               0x02
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Target ID on the SCSI bus (PUN).
+  ///
+  UINT16                          Pun;
+  ///
+  /// Logical Unit Number (LUN).
+  ///
+  UINT16                          Lun;
+} SCSI_DEVICE_PATH;
+
+///
+/// Fibre Channel SubType.
+///
+#define MSG_FIBRECHANNEL_DP       0x03
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved for the future.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// Fibre Channel World Wide Number.
+  ///
+  UINT64                          WWN;
+  ///
+  /// Fibre Channel Logical Unit Number.
+  ///
+  UINT64                          Lun;
+} FIBRECHANNEL_DEVICE_PATH;
+
+///
+/// Fibre Channel Ex SubType.
+///
+#define MSG_FIBRECHANNELEX_DP     0x15
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved for the future.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// 8 byte array containing Fibre Channel End Device Port Name.
+  ///
+  UINT8                           WWN[8];
+  ///
+  /// 8 byte array containing Fibre Channel Logical Unit Number.
+  ///
+  UINT8                           Lun[8];
+} FIBRECHANNELEX_DEVICE_PATH;
+
+///
+/// 1394 Device Path SubType
+///
+#define MSG_1394_DP               0x04
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved for the future.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// 1394 Global Unique ID (GUID).
+  ///
+  UINT64                          Guid;
+} F1394_DEVICE_PATH;
+
+///
+/// USB Device Path SubType.
+///
+#define MSG_USB_DP                0x05
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// USB Parent Port Number.
+  ///
+  UINT8                         ParentPortNumber;
+  ///
+  /// USB Interface Number.
+  ///
+  UINT8                         InterfaceNumber;
+} USB_DEVICE_PATH;
+
+///
+/// USB Class Device Path SubType.
+///
+#define MSG_USB_CLASS_DP          0x0f
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// Vendor ID assigned by USB-IF. A value of 0xFFFF will
+  /// match any Vendor ID.
+  ///
+  UINT16                        VendorId;
+  ///
+  /// Product ID assigned by USB-IF. A value of 0xFFFF will
+  /// match any Product ID.
+  ///
+  UINT16                        ProductId;
+  ///
+  /// The class code assigned by the USB-IF. A value of 0xFF
+  /// will match any class code.
+  ///
+  UINT8                         DeviceClass;
+  ///
+  /// The subclass code assigned by the USB-IF. A value of
+  /// 0xFF will match any subclass code.
+  ///
+  UINT8                         DeviceSubClass;
+  ///
+  /// The protocol code assigned by the USB-IF. A value of
+  /// 0xFF will match any protocol code.
+  ///
+  UINT8                         DeviceProtocol;
+} USB_CLASS_DEVICE_PATH;
+
+///
+/// USB WWID Device Path SubType.
+///
+#define MSG_USB_WWID_DP           0x10
+
+///
+/// This device path describes a USB device using its serial number.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// USB interface number.
+  ///
+  UINT16                        InterfaceNumber;
+  ///
+  /// USB vendor id of the device.
+  ///
+  UINT16                        VendorId;
+  ///
+  /// USB product id of the device.
+  ///
+  UINT16                        ProductId;
+  ///
+  /// Last 64-or-fewer UTF-16 characters of the USB
+  /// serial number. The length of the string is
+  /// determined by the Length field less the offset of the
+  /// Serial Number field (10)
+  ///
+  /// CHAR16                     SerialNumber[...];
+} USB_WWID_DEVICE_PATH;
+
+///
+/// Device Logical Unit SubType.
+///
+#define MSG_DEVICE_LOGICAL_UNIT_DP  0x11
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL      Header;
+  ///
+  /// Logical Unit Number for the interface.
+  ///
+  UINT8                         Lun;
+} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+
+///
+/// SATA Device Path SubType.
+///
+#define MSG_SATA_DP               0x12
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The HBA port number that facilitates the connection to the
+  /// device or a port multiplier. The value 0xFFFF is reserved.
+  ///
+  UINT16                          HBAPortNumber;
+  ///
+  /// The Port multiplier port number that facilitates the connection
+  /// to the device. Must be set to 0xFFFF if the device is directly
+  /// connected to the HBA.
+  ///
+  UINT16                          PortMultiplierPortNumber;
+  ///
+  /// Logical Unit Number.
+  ///
+  UINT16                          Lun;
+} SATA_DEVICE_PATH;
+
+///
+/// Flag for if the device is directly connected to the HBA.
+///
+#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000
+
+///
+/// I2O Device Path SubType.
+///
+#define MSG_I2O_DP                0x06
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Target ID (TID) for a device.
+  ///
+  UINT32                          Tid;
+} I2O_DEVICE_PATH;
+
+///
+/// MAC Address Device Path SubType.
+///
+#define MSG_MAC_ADDR_DP           0x0b
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The MAC address for a network interface padded with 0s.
+  ///
+  EFI_MAC_ADDRESS                 MacAddress;
+  ///
+  /// Network interface type(i.e. 802.3, FDDI).
+  ///
+  UINT8                           IfType;
+} MAC_ADDR_DEVICE_PATH;
+
+///
+/// IPv4 Device Path SubType
+///
+#define MSG_IPv4_DP               0x0c
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The local IPv4 address.
+  ///
+  EFI_IPv4_ADDRESS                LocalIpAddress;
+  ///
+  /// The remote IPv4 address.
+  ///
+  EFI_IPv4_ADDRESS                RemoteIpAddress;
+  ///
+  /// The local port number.
+  ///
+  UINT16                          LocalPort;
+  ///
+  /// The remote port number.
+  ///
+  UINT16                          RemotePort;
+  ///
+  /// The network protocol(i.e. UDP, TCP).
+  ///
+  UINT16                          Protocol;
+  ///
+  /// 0x00 - The Source IP Address was assigned though DHCP.
+  /// 0x01 - The Source IP Address is statically bound.
+  ///
+  BOOLEAN                         StaticIpAddress;
+  ///
+  /// The gateway IP address
+  ///
+  EFI_IPv4_ADDRESS                GatewayIpAddress;
+  ///
+  /// The subnet mask
+  ///
+  EFI_IPv4_ADDRESS                SubnetMask;
+} IPv4_DEVICE_PATH;
+
+///
+/// IPv6 Device Path SubType.
+///
+#define MSG_IPv6_DP               0x0d
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The local IPv6 address.
+  ///
+  EFI_IPv6_ADDRESS                LocalIpAddress;
+  ///
+  /// The remote IPv6 address.
+  ///
+  EFI_IPv6_ADDRESS                RemoteIpAddress;
+  ///
+  /// The local port number.
+  ///
+  UINT16                          LocalPort;
+  ///
+  /// The remote port number.
+  ///
+  UINT16                          RemotePort;
+  ///
+  /// The network protocol(i.e. UDP, TCP).
+  ///
+  UINT16                          Protocol;
+  ///
+  /// 0x00 - The Local IP Address was manually configured.
+  /// 0x01 - The Local IP Address is assigned through IPv6
+  /// stateless auto-configuration.
+  /// 0x02 - The Local IP Address is assigned through IPv6
+  /// stateful configuration.
+  ///
+  UINT8                           IpAddressOrigin;
+  ///
+  /// The prefix length
+  ///
+  UINT8                           PrefixLength;
+  ///
+  /// The gateway IP address
+  ///
+  EFI_IPv6_ADDRESS                GatewayIpAddress;
+} IPv6_DEVICE_PATH;
+
+///
+/// InfiniBand Device Path SubType.
+///
+#define MSG_INFINIBAND_DP         0x09
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Flags to help identify/manage InfiniBand device path elements:
+  /// Bit 0 - IOC/Service (0b = IOC, 1b = Service).
+  /// Bit 1 - Extend Boot Environment.
+  /// Bit 2 - Console Protocol.
+  /// Bit 3 - Storage Protocol.
+  /// Bit 4 - Network Protocol.
+  /// All other bits are reserved.
+  ///
+  UINT32                          ResourceFlags;
+  ///
+  /// 128-bit Global Identifier for remote fabric port.
+  ///
+  UINT8                           PortGid[16];
+  ///
+  /// 64-bit unique identifier to remote IOC or server process.
+  /// Interpretation of field specified by Resource Flags (bit 0).
+  ///
+  UINT64                          ServiceId;
+  ///
+  /// 64-bit persistent ID of remote IOC port.
+  ///
+  UINT64                          TargetPortId;
+  ///
+  /// 64-bit persistent ID of remote device.
+  ///
+  UINT64                          DeviceId;
+} INFINIBAND_DEVICE_PATH;
+
+#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE                0x01
+#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT  0x02
+#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL           0x04
+#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL           0x08
+#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL           0x10
+
+///
+/// UART Device Path SubType.
+///
+#define MSG_UART_DP               0x0e
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Reserved.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// The baud rate setting for the UART style device. A value of 0
+  /// means that the device's default baud rate will be used.
+  ///
+  UINT64                          BaudRate;
+  ///
+  /// The number of data bits for the UART style device. A value
+  /// of 0 means that the device's default number of data bits will be used.
+  ///
+  UINT8                           DataBits;
+  ///
+  /// The parity setting for the UART style device.
+  /// Parity 0x00 - Default Parity.
+  /// Parity 0x01 - No Parity.
+  /// Parity 0x02 - Even Parity.
+  /// Parity 0x03 - Odd Parity.
+  /// Parity 0x04 - Mark Parity.
+  /// Parity 0x05 - Space Parity.
+  ///
+  UINT8                           Parity;
+  ///
+  /// The number of stop bits for the UART style device.
+  /// Stop Bits 0x00 - Default Stop Bits.
+  /// Stop Bits 0x01 - 1 Stop Bit.
+  /// Stop Bits 0x02 - 1.5 Stop Bits.
+  /// Stop Bits 0x03 - 2 Stop Bits.
+  ///
+  UINT8                           StopBits;
+} UART_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MSG_VENDOR_DP             0x0a
+typedef VENDOR_DEVICE_PATH        VENDOR_DEFINED_DEVICE_PATH;
+
+#define DEVICE_PATH_MESSAGING_PC_ANSI     EFI_PC_ANSI_GUID
+#define DEVICE_PATH_MESSAGING_VT_100      EFI_VT_100_GUID
+#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID
+#define DEVICE_PATH_MESSAGING_VT_UTF8     EFI_VT_UTF8_GUID
+
+///
+/// A new device path node is defined to declare flow control characteristics.
+/// UART Flow Control Messaging Device Path
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID.
+  ///
+  EFI_GUID                        Guid;
+  ///
+  /// Bitmap of supported flow control types.
+  /// Bit 0 set indicates hardware flow control.
+  /// Bit 1 set indicates Xon/Xoff flow control.
+  /// All other bits are reserved and are clear.
+  ///
+  UINT32                          FlowControlMap;
+} UART_FLOW_CONTROL_DEVICE_PATH;
+
+#define UART_FLOW_CONTROL_HARDWARE         0x00000001
+#define UART_FLOW_CONTROL_XON_XOFF         0x00000010
+
+#define DEVICE_PATH_MESSAGING_SAS          EFI_SAS_DEVICE_PATH_GUID
+///
+/// Serial Attached SCSI (SAS) Device Path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// DEVICE_PATH_MESSAGING_SAS GUID.
+  ///
+  EFI_GUID                        Guid;
+  ///
+  /// Reserved for future use.
+  ///
+  UINT32                          Reserved;
+  ///
+  /// SAS Address for Serial Attached SCSI Target.
+  ///
+  UINT64                          SasAddress;
+  ///
+  /// SAS Logical Unit Number.
+  ///
+  UINT64                          Lun;
+  ///
+  /// More Information about the device and its interconnect.
+  ///
+  UINT16                          DeviceTopology;
+  ///
+  /// Relative Target Port (RTP).
+  ///
+  UINT16                          RelativeTargetPort;
+} SAS_DEVICE_PATH;
+
+///
+/// Serial Attached SCSI (SAS) Ex Device Path SubType
+///
+#define MSG_SASEX_DP              0x16
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port.
+  ///
+  UINT8                           SasAddress[8];
+  ///
+  /// 8-byte array of the SAS Logical Unit Number.
+  ///
+  UINT8                           Lun[8];
+  ///
+  /// More Information about the device and its interconnect.
+  ///
+  UINT16                          DeviceTopology;
+  ///
+  /// Relative Target Port (RTP).
+  ///
+  UINT16                          RelativeTargetPort;
+} SASEX_DEVICE_PATH;
+
+///
+/// NvmExpress Namespace Device Path SubType.
+///
+#define MSG_NVME_NAMESPACE_DP     0x17
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  UINT32                          NamespaceId;
+  UINT64                          NamespaceUuid;
+} NVME_NAMESPACE_DEVICE_PATH;
+
+///
+/// Uniform Resource Identifiers (URI) Device Path SubType
+///
+#define MSG_URI_DP                0x18
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Instance of the URI pursuant to RFC 3986.
+  ///
+  CHAR8                           Uri[];
+} URI_DEVICE_PATH;
+
+///
+/// Universal Flash Storage (UFS) Device Path SubType.
+///
+#define MSG_UFS_DP                0x19
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Target ID on the UFS bus (PUN).
+  ///
+  UINT8                           Pun;
+  ///
+  /// Logical Unit Number (LUN).
+  ///
+  UINT8                           Lun;
+} UFS_DEVICE_PATH;
+
+///
+/// SD (Secure Digital) Device Path SubType.
+///
+#define MSG_SD_DP                 0x1A
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  UINT8                           SlotNumber;
+} SD_DEVICE_PATH;
+
+///
+/// EMMC (Embedded MMC) Device Path SubType.
+///
+#define MSG_EMMC_DP                 0x1D
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  UINT8                           SlotNumber;
+} EMMC_DEVICE_PATH;
+
+///
+/// iSCSI Device Path SubType
+///
+#define MSG_ISCSI_DP              0x13
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Network Protocol (0 = TCP, 1+ = reserved).
+  ///
+  UINT16                          NetworkProtocol;
+  ///
+  /// iSCSI Login Options.
+  ///
+  UINT16                          LoginOption;
+  ///
+  /// iSCSI Logical Unit Number.
+  ///
+  UINT64                          Lun;
+  ///
+  /// iSCSI Target Portal group tag the initiator intends
+  /// to establish a session with.
+  ///
+  UINT16                          TargetPortalGroupTag;
+  ///
+  /// iSCSI NodeTarget Name. The length of the name
+  /// is determined by subtracting the offset of this field from Length.
+  ///
+  /// CHAR8                        iSCSI Target Name.
+} ISCSI_DEVICE_PATH;
+
+#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST             0x0000
+#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C   0x0002
+#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST               0x0000
+#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C     0x0008
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP              0x0000
+#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON               0x1000
+#define ISCSI_LOGIN_OPTION_CHAP_BI                      0x0000
+#define ISCSI_LOGIN_OPTION_CHAP_UNI                     0x2000
+
+///
+/// VLAN Device Path SubType.
+///
+#define MSG_VLAN_DP               0x14
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// VLAN identifier (0-4094).
+  ///
+  UINT16                          VlanId;
+} VLAN_DEVICE_PATH;
+
+///
+/// Bluetooth Device Path SubType.
+///
+#define MSG_BLUETOOTH_DP     0x1b
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// 48bit Bluetooth device address.
+  ///
+  BLUETOOTH_ADDRESS               BD_ADDR;
+} BLUETOOTH_DEVICE_PATH;
+
+///
+/// Wi-Fi Device Path SubType.
+///
+#define MSG_WIFI_DP               0x1C
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Service set identifier. A 32-byte octets string.
+  ///
+  UINT8                           SSId[32];
+} WIFI_DEVICE_PATH;
+
+//
+// Media Device Path
+//
+#define MEDIA_DEVICE_PATH         0x04
+
+///
+/// Hard Drive Media Device Path SubType.
+///
+#define MEDIA_HARDDRIVE_DP        0x01
+
+///
+/// The Hard Drive Media Device Path is used to represent a partition on a hard drive.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Describes the entry in a partition table, starting with entry 1.
+  /// Partition number zero represents the entire device. Valid
+  /// partition numbers for a MBR partition are [1, 4]. Valid
+  /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries].
+  ///
+  UINT32                          PartitionNumber;
+  ///
+  /// Starting LBA of the partition on the hard drive.
+  ///
+  UINT64                          PartitionStart;
+  ///
+  /// Size of the partition in units of Logical Blocks.
+  ///
+  UINT64                          PartitionSize;
+  ///
+  /// Signature unique to this partition:
+  /// If SignatureType is 0, this field has to be initialized with 16 zeros.
+  /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field.
+  /// The other 12 bytes are initialized with zeros.
+  /// If SignatureType is 2, this field contains a 16 byte signature.
+  ///
+  UINT8                           Signature[16];
+  ///
+  /// Partition Format: (Unused values reserved).
+  /// 0x01 - PC-AT compatible legacy MBR.
+  /// 0x02 - GUID Partition Table.
+  ///
+  UINT8                           MBRType;
+  ///
+  /// Type of Disk Signature: (Unused values reserved).
+  /// 0x00 - No Disk Signature.
+  /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR.
+  /// 0x02 - GUID signature.
+  ///
+  UINT8                           SignatureType;
+} HARDDRIVE_DEVICE_PATH;
+
+#define MBR_TYPE_PCAT             0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define NO_DISK_SIGNATURE         0x00
+#define SIGNATURE_TYPE_MBR        0x01
+#define SIGNATURE_TYPE_GUID       0x02
+
+///
+/// CD-ROM Media Device Path SubType.
+///
+#define MEDIA_CDROM_DP            0x02
+
+///
+/// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero.
+  ///
+  UINT32                          BootEntry;
+  ///
+  /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing.
+  ///
+  UINT64                          PartitionStart;
+  ///
+  /// Size of the partition in units of Blocks, also called Sectors.
+  ///
+  UINT64                          PartitionSize;
+} CDROM_DEVICE_PATH;
+
+//
+// Use VENDOR_DEVICE_PATH struct
+//
+#define MEDIA_VENDOR_DP           0x03  ///< Media vendor device path subtype.
+
+///
+/// File Path Media Device Path SubType
+///
+#define MEDIA_FILEPATH_DP         0x04
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// A NULL-terminated Path string including directory and file names.
+  ///
+  CHAR16                          PathName[1];
+} FILEPATH_DEVICE_PATH;
+
+#define SIZE_OF_FILEPATH_DEVICE_PATH  OFFSET_OF(FILEPATH_DEVICE_PATH,PathName)
+
+///
+/// Media Protocol Device Path SubType.
+///
+#define MEDIA_PROTOCOL_DP         0x05
+
+///
+/// The Media Protocol Device Path is used to denote the protocol that is being 
+/// used in a device path at the location of the path specified. 
+/// Many protocols are inherent to the style of device path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// The ID of the protocol.
+  ///
+  EFI_GUID                        Protocol;
+} MEDIA_PROTOCOL_DEVICE_PATH;
+
+///
+/// PIWG Firmware File SubType.
+///
+#define MEDIA_PIWG_FW_FILE_DP     0x06
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Firmware file name
+  ///
+  EFI_GUID                        FvFileName;
+} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;
+
+///
+/// PIWG Firmware Volume Device Path SubType.
+///
+#define MEDIA_PIWG_FW_VOL_DP      0x07
+
+///
+/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Firmware volume name.
+  ///
+  EFI_GUID                        FvName;
+} MEDIA_FW_VOL_DEVICE_PATH;
+
+///
+/// Media relative offset range device path.
+///
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08
+
+///
+/// Used to describe the offset range of media relative.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL  Header;
+  UINT32                    Reserved;
+  UINT64                    StartingOffset;
+  UINT64                    EndingOffset;
+} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in volatile memory.
+///
+#define EFI_VIRTUAL_DISK_GUID               EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE
+
+extern  EFI_GUID                            gEfiVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in volatile memory.
+///
+#define EFI_VIRTUAL_CD_GUID                 EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE
+
+extern  EFI_GUID                            gEfiVirtualCdGuid;
+
+///
+/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_DISK_GUID    EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT
+
+extern  EFI_GUID                            gEfiPersistentVirtualDiskGuid;
+
+///
+/// This GUID defines a RAM Disk supporting an ISO image in persistent memory.
+///
+#define EFI_PERSISTENT_VIRTUAL_CD_GUID      EFI_ACPI_6_0_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT
+
+extern  EFI_GUID                            gEfiPersistentVirtualCdGuid;
+
+///
+/// Media ram disk device path.
+///
+#define MEDIA_RAM_DISK_DP         0x09
+
+///
+/// Used to describe the ram disk device path.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Starting Memory Address.
+  ///
+  UINT32                          StartingAddr[2];
+  ///
+  /// Ending Memory Address.
+  ///
+  UINT32                          EndingAddr[2];
+  ///
+  /// GUID that defines the type of the RAM Disk.
+  ///
+  EFI_GUID                        TypeGuid;
+  ///
+  /// RAM Diskinstance number, if supported. The default value is zero.
+  ///
+  UINT16                          Instance;
+} MEDIA_RAM_DISK_DEVICE_PATH;
+
+///
+/// BIOS Boot Specification Device Path.
+///
+#define BBS_DEVICE_PATH           0x05
+
+///
+/// BIOS Boot Specification Device Path SubType.
+///
+#define BBS_BBS_DP                0x01
+
+///
+/// This Device Path is used to describe the booting of non-EFI-aware operating systems.
+///
+typedef struct {
+  EFI_DEVICE_PATH_PROTOCOL        Header;
+  ///
+  /// Device Type as defined by the BIOS Boot Specification.
+  ///
+  UINT16                          DeviceType;
+  ///
+  /// Status Flags as defined by the BIOS Boot Specification.
+  ///
+  UINT16                          StatusFlag;
+  ///
+  /// Null-terminated ASCII string that describes the boot device to a user.
+  ///
+  CHAR8                           String[1];
+} BBS_BBS_DEVICE_PATH;
+
+//
+// DeviceType definitions - from BBS specification
+//
+#define BBS_TYPE_FLOPPY           0x01
+#define BBS_TYPE_HARDDRIVE        0x02
+#define BBS_TYPE_CDROM            0x03
+#define BBS_TYPE_PCMCIA           0x04
+#define BBS_TYPE_USB              0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_BEV              0x80
+#define BBS_TYPE_UNKNOWN          0xFF
+
+
+///
+/// Union of all possible Device Paths and pointers to Device Paths.
+///
+typedef union {
+  EFI_DEVICE_PATH_PROTOCOL                   DevPath;
+  PCI_DEVICE_PATH                            Pci;
+  PCCARD_DEVICE_PATH                         PcCard;
+  MEMMAP_DEVICE_PATH                         MemMap;
+  VENDOR_DEVICE_PATH                         Vendor;
+
+  CONTROLLER_DEVICE_PATH                     Controller;
+  BMC_DEVICE_PATH                            Bmc;
+  ACPI_HID_DEVICE_PATH                       Acpi;
+  ACPI_EXTENDED_HID_DEVICE_PATH              ExtendedAcpi;
+  ACPI_ADR_DEVICE_PATH                       AcpiAdr;
+
+  ATAPI_DEVICE_PATH                          Atapi;
+  SCSI_DEVICE_PATH                           Scsi;
+  ISCSI_DEVICE_PATH                          Iscsi;
+  FIBRECHANNEL_DEVICE_PATH                   FibreChannel;
+  FIBRECHANNELEX_DEVICE_PATH                 FibreChannelEx;
+
+  F1394_DEVICE_PATH                          F1394;
+  USB_DEVICE_PATH                            Usb;
+  SATA_DEVICE_PATH                           Sata;
+  USB_CLASS_DEVICE_PATH                      UsbClass;
+  USB_WWID_DEVICE_PATH                       UsbWwid;
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH            LogicUnit;
+  I2O_DEVICE_PATH                            I2O;
+  MAC_ADDR_DEVICE_PATH                       MacAddr;
+  IPv4_DEVICE_PATH                           Ipv4;
+  IPv6_DEVICE_PATH                           Ipv6;
+  VLAN_DEVICE_PATH                           Vlan;
+  INFINIBAND_DEVICE_PATH                     InfiniBand;
+  UART_DEVICE_PATH                           Uart;
+  UART_FLOW_CONTROL_DEVICE_PATH              UartFlowControl;
+  SAS_DEVICE_PATH                            Sas;
+  SASEX_DEVICE_PATH                          SasEx;
+  NVME_NAMESPACE_DEVICE_PATH                 NvmeNamespace;
+  URI_DEVICE_PATH                            Uri;
+  BLUETOOTH_DEVICE_PATH                      Bluetooth;
+  WIFI_DEVICE_PATH                           WiFi;
+  UFS_DEVICE_PATH                            Ufs;
+  SD_DEVICE_PATH                             Sd;
+  EMMC_DEVICE_PATH                           Emmc;
+  HARDDRIVE_DEVICE_PATH                      HardDrive;
+  CDROM_DEVICE_PATH                          CD;
+
+  FILEPATH_DEVICE_PATH                       FilePath;
+  MEDIA_PROTOCOL_DEVICE_PATH                 MediaProtocol;
+
+  MEDIA_FW_VOL_DEVICE_PATH                   FirmwareVolume;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH          FirmwareFile;
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH    Offset;
+  MEDIA_RAM_DISK_DEVICE_PATH                 RamDisk;
+  BBS_BBS_DEVICE_PATH                        Bbs;
+} EFI_DEV_PATH;
+
+
+
+typedef union {
+  EFI_DEVICE_PATH_PROTOCOL                   *DevPath;
+  PCI_DEVICE_PATH                            *Pci;
+  PCCARD_DEVICE_PATH                         *PcCard;
+  MEMMAP_DEVICE_PATH                         *MemMap;
+  VENDOR_DEVICE_PATH                         *Vendor;
+
+  CONTROLLER_DEVICE_PATH                     *Controller;
+  BMC_DEVICE_PATH                            *Bmc;
+  ACPI_HID_DEVICE_PATH                       *Acpi;
+  ACPI_EXTENDED_HID_DEVICE_PATH              *ExtendedAcpi;
+  ACPI_ADR_DEVICE_PATH                       *AcpiAdr;
+
+  ATAPI_DEVICE_PATH                          *Atapi;
+  SCSI_DEVICE_PATH                           *Scsi;
+  ISCSI_DEVICE_PATH                          *Iscsi;
+  FIBRECHANNEL_DEVICE_PATH                   *FibreChannel;
+  FIBRECHANNELEX_DEVICE_PATH                 *FibreChannelEx;
+
+  F1394_DEVICE_PATH                          *F1394;
+  USB_DEVICE_PATH                            *Usb;
+  SATA_DEVICE_PATH                           *Sata;
+  USB_CLASS_DEVICE_PATH                      *UsbClass;
+  USB_WWID_DEVICE_PATH                       *UsbWwid;
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH            *LogicUnit;
+  I2O_DEVICE_PATH                            *I2O;
+  MAC_ADDR_DEVICE_PATH                       *MacAddr;
+  IPv4_DEVICE_PATH                           *Ipv4;
+  IPv6_DEVICE_PATH                           *Ipv6;
+  VLAN_DEVICE_PATH                           *Vlan;
+  INFINIBAND_DEVICE_PATH                     *InfiniBand;
+  UART_DEVICE_PATH                           *Uart;
+  UART_FLOW_CONTROL_DEVICE_PATH              *UartFlowControl;
+  SAS_DEVICE_PATH                            *Sas;
+  SASEX_DEVICE_PATH                          *SasEx;
+  NVME_NAMESPACE_DEVICE_PATH                 *NvmeNamespace;
+  URI_DEVICE_PATH                            *Uri;
+  BLUETOOTH_DEVICE_PATH                      *Bluetooth;
+  WIFI_DEVICE_PATH                           *WiFi;
+  UFS_DEVICE_PATH                            *Ufs;
+  SD_DEVICE_PATH                             *Sd;
+  EMMC_DEVICE_PATH                           *Emmc;
+  HARDDRIVE_DEVICE_PATH                      *HardDrive;
+  CDROM_DEVICE_PATH                          *CD;
+
+  FILEPATH_DEVICE_PATH                       *FilePath;
+  MEDIA_PROTOCOL_DEVICE_PATH                 *MediaProtocol;
+
+  MEDIA_FW_VOL_DEVICE_PATH                   *FirmwareVolume;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH          *FirmwareFile;
+  MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH    *Offset;
+  MEDIA_RAM_DISK_DEVICE_PATH                 *RamDisk;
+  BBS_BBS_DEVICE_PATH                        *Bbs;
+  UINT8                                      *Raw;
+} EFI_DEV_PATH_PTR;
+
+#pragma pack()
+                                             
+#define END_DEVICE_PATH_TYPE                 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE       0xFF
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE     0x01
+
+extern EFI_GUID gEfiDevicePathProtocolGuid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/DevicePathFromText.h b/sys/contrib/edk2/Include/Protocol/DevicePathFromText.h
new file mode 100644
index 0000000000..cbdbc466dc
--- /dev/null
+++ b/sys/contrib/edk2/Include/Protocol/DevicePathFromText.h
@@ -0,0 +1,72 @@
+/** @file
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL as defined in UEFI 2.0.  
+  This protocol provides service to convert text to device paths and device nodes.
+
+  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
+#define __DEVICE_PATH_FROM_TEXT_PROTOCOL_H__
+
+///
+/// Device Path From Text protocol
+///
+#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \
+  { \
+    0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e  } \
+  }
+
+/**
+  Convert text to the binary representation of a device node.
+
+  @param  TextDeviceNode TextDeviceNode points to the text representation of a device
+                         node. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  @retval a_pointer      Pointer to the EFI device node.
+  @retval NULL           if TextDeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE)(
+  IN CONST CHAR16                 *TextDeviceNode
+  );    
+  
+
+/**
+  Convert text to the binary representation of a device node.
+
+  @param  TextDeviceNode TextDevicePath points to the text representation of a device
+                         path. Conversion starts with the first character and continues
+                         until the first non-device path character.
+
+  @retval a_pointer      Pointer to the allocated device path.
+  @retval NULL           if TextDeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH)(
+  IN CONST CHAR16                 *TextDevicePath
+  );  
+
+///
+/// This protocol converts text to device paths and device nodes.
+///
+typedef struct {
+  EFI_DEVICE_PATH_FROM_TEXT_NODE  ConvertTextToDeviceNode;
+  EFI_DEVICE_PATH_FROM_TEXT_PATH  ConvertTextToDevicePath;
+} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/DevicePathToText.h b/sys/contrib/edk2/Include/Protocol/DevicePathToText.h
new file mode 100644
index 0000000000..923ee64840
--- /dev/null
+++ b/sys/contrib/edk2/Include/Protocol/DevicePathToText.h
@@ -0,0 +1,85 @@
+/** @file
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL as defined in UEFI 2.0.  
+  This protocol provides service to convert device nodes and paths to text.
+
+  Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __DEVICE_PATH_TO_TEXT_PROTOCOL_H__
+#define __DEVICE_PATH_TO_TEXT_PROTOCOL_H__
+
+///
+/// Device Path To Text protocol
+///
+#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
+  { \
+    0x8b843e20, 0x8132, 0x4852, {0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \
+  }
+
+/**
+  Convert a device node to its text representation.
+
+  @param  DeviceNode     Points to the device node to be converted.
+  @param  DisplayOnly    If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param  AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+  @retval a_pointer      a pointer to the allocated text representation of the device node data
+  @retval NULL           if DeviceNode is NULL or there was insufficient memory.
+
+**/
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DeviceNode,
+  IN BOOLEAN                          DisplayOnly,
+  IN BOOLEAN                          AllowShortcuts
+  );      
+
+/**
+  Convert a device path to its text representation.
+
+  @param  DevicePath     Points to the device path to be converted.
+  @param  DisplayOnly    If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.  
+  @param  AllowShortcuts The AllowShortcuts is FALSE, then the shortcut forms of
+                         text representation for a device node cannot be used.
+
+  @retval a_pointer      a pointer to the allocated text representation of the device node.
+  @retval NULL           if DevicePath is NULL or there was insufficient memory.
+
+**/
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
+  IN BOOLEAN                          DisplayOnly,
+  IN BOOLEAN                          AllowShortcuts
+  );    
+
+///
+/// This protocol converts device paths and device nodes to text.
+///
+typedef struct {
+  EFI_DEVICE_PATH_TO_TEXT_NODE        ConvertDeviceNodeToText;
+  EFI_DEVICE_PATH_TO_TEXT_PATH        ConvertDevicePathToText;
+} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathToTextProtocolGuid;
+
+#endif
+
+
diff --git a/sys/contrib/edk2/Include/Protocol/DevicePathUtilities.h b/sys/contrib/edk2/Include/Protocol/DevicePathUtilities.h
new file mode 100644
index 0000000000..35fd624f2c
--- /dev/null
+++ b/sys/contrib/edk2/Include/Protocol/DevicePathUtilities.h
@@ -0,0 +1,192 @@
+/** @file
+  EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0.  
+  Use to create and manipulate device paths and device nodes.
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __DEVICE_PATH_UTILITIES_PROTOCOL_H__
+#define __DEVICE_PATH_UTILITIES_PROTOCOL_H__
+
+///
+/// Device Path Utilities protocol
+///
+#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \
+  { \
+    0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \
+  }
+
+/**
+  Returns the size of the device path, in bytes.
+
+  @param  DevicePath Points to the start of the EFI device path.
+
+  @return Size  Size of the specified device path, in bytes, including the end-of-path tag.
+  @retval 0     DevicePath is NULL   
+
+**/
+typedef
+UINTN
+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+  );    
+  
+
+/**
+  Create a duplicate of the specified path.
+
+  @param  DevicePath Points to the source EFI device path.
+
+  @retval Pointer    A pointer to the duplicate device path.
+  @retval NULL       insufficient memory or DevicePath is NULL
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+  );      
+
+/**
+  Create a new path by appending the second device path to the first.
+  If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned. 
+  If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned.
+  If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned.
+
+  @param  Src1 Points to the first device path.
+  @param  Src2 Points to the second device path.
+
+  @retval Pointer  A pointer to the newly created device path.
+  @retval NULL     Memory could not be allocated
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_PATH)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+  );     
+  
+/**
+  Creates a new path by appending the device node to the device path.
+  If DeviceNode is NULL then a copy of DevicePath is returned. 
+  If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned.
+  If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned.
+
+  @param  DevicePath Points to the device path.
+  @param  DeviceNode Points to the device node.
+
+  @retval Pointer    A pointer to the allocated device node.
+  @retval NULL       There was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_NODE)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+  );
+
+/**
+  Creates a new path by appending the specified device path instance to the specified device path.
+
+  @param  DevicePath         Points to the device path. If NULL, then ignored.
+  @param  DevicePathInstance Points to the device path instance.
+
+  @retval Pointer            A pointer to the newly created device path
+  @retval NULL               Memory could not be allocated or DevicePathInstance is NULL.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+  );  
+
+/**
+  Creates a copy of the current device path instance and returns a pointer to the next device path
+  instance.
+
+  @param  DevicePathInstance     On input, this holds the pointer to the current device path
+                                 instance. On output, this holds the pointer to the next
+                                 device path instance or NULL if there are no more device
+                                 path instances in the device path.  
+  @param  DevicePathInstanceSize On output, this holds the size of the device path instance,
+                                 in bytes or zero, if DevicePathInstance is NULL.
+                                 If NULL, then the instance size is not output.
+
+  @retval Pointer                A pointer to the copy of the current device path instance.
+  @retval NULL                   DevicePathInstace was NULL on entry or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)(
+  IN  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathInstance,
+  OUT UINTN                         *DevicePathInstanceSize
+  );  
+
+/**
+  Creates a device node
+
+  @param  NodeType    NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+                      the new device node.
+  @param  NodeSubType NodeSubType is the device node sub-type
+                      EFI_DEVICE_PATH.SubType) for the new device node.
+  @param  NodeLength  NodeLength is the length of the device node
+                      (EFI_DEVICE_PATH.Length) for the new device node.
+
+  @retval Pointer     A pointer to the newly created device node.
+  @retval NULL        NodeLength is less than
+                      the size of the header or there was insufficient memory.
+
+**/
+typedef
+EFI_DEVICE_PATH_PROTOCOL*
+(EFIAPI *EFI_DEVICE_PATH_UTILS_CREATE_NODE)(
+  IN UINT8                          NodeType,
+  IN UINT8                          NodeSubType,
+  IN UINT16                         NodeLength
+);   
+
+/**
+  Returns whether a device path is multi-instance.
+
+  @param  DevicePath Points to the device path. If NULL, then ignored.
+
+  @retval TRUE       The device path has more than one instance
+  @retval FALSE      The device path is empty or contains only a single instance.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)(
+  IN CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath
+  );                                                                                                       
+  
+///
+/// This protocol is used to creates and manipulates device paths and device nodes.
+/// 
+typedef struct {
+  EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;
+  EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH      DuplicateDevicePath;
+  EFI_DEVICE_PATH_UTILS_APPEND_PATH          AppendDevicePath;
+  EFI_DEVICE_PATH_UTILS_APPEND_NODE          AppendDeviceNode;
+  EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE      AppendDevicePathInstance;
+  EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE    GetNextDevicePathInstance;
+  EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE    IsDevicePathMultiInstance;
+  EFI_DEVICE_PATH_UTILS_CREATE_NODE          CreateDeviceNode;
+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;
+
+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; 
+
+#endif
diff --git a/sys/contrib/edk2/Include/Protocol/SimpleTextInEx.h b/sys/contrib/edk2/Include/Protocol/SimpleTextInEx.h
new file mode 100644
index 0000000000..5524c720a7
--- /dev/null
+++ b/sys/contrib/edk2/Include/Protocol/SimpleTextInEx.h
@@ -0,0 +1,325 @@
+/** @file
+  Simple Text Input Ex protocol from the UEFI 2.0 specification.
+
+  This protocol defines an extension to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+  which exposes much more state and modifier information from the input device,
+  also allows one to register a notification for a particular keystroke.
+
+  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __SIMPLE_TEXT_IN_EX_H__
+#define __SIMPLE_TEXT_IN_EX_H__
+
+#include <Protocol/SimpleTextIn.h>
+
+#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+  {0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } }
+
+
+typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
+
+/**
+  The Reset() function resets the input device hardware. As part
+  of initialization process, the firmware/device will make a quick
+  but reasonable attempt to verify that the device is functioning.
+  If the ExtendedVerification flag is TRUE the firmware may take
+  an extended amount of time to verify the device is operating on
+  reset. Otherwise the reset operation is to occur as quickly as
+  possible. The hardware verification process is not defined by
+  this specification and is left up to the platform firmware or
+  driver to implement.
+
+  @param This                 A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param ExtendedVerification Indicates that the driver may
+                              perform a more exhaustive
+                              verification operation of the
+                              device during reset.
+
+
+  @retval EFI_SUCCESS       The device was reset.
+
+  @retval EFI_DEVICE_ERROR  The device is not functioning
+                            correctly and could not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_RESET_EX)(
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  IN BOOLEAN                           ExtendedVerification
+);
+
+
+///
+/// EFI_KEY_TOGGLE_STATE. The toggle states are defined.
+/// They are: EFI_TOGGLE_STATE_VALID, EFI_SCROLL_LOCK_ACTIVE
+/// EFI_NUM_LOCK_ACTIVE, EFI_CAPS_LOCK_ACTIVE
+///
+typedef UINT8 EFI_KEY_TOGGLE_STATE;
+
+typedef struct _EFI_KEY_STATE {
+  ///
+  /// Reflects the currently pressed shift
+  /// modifiers for the input device. The
+  /// returned value is valid only if the high
+  /// order bit has been set.
+  ///
+  UINT32                KeyShiftState;
+  ///
+  /// Reflects the current internal state of
+  /// various toggled attributes. The returned
+  /// value is valid only if the high order
+  /// bit has been set.
+  ///
+  EFI_KEY_TOGGLE_STATE  KeyToggleState;
+} EFI_KEY_STATE;
+
+typedef struct {
+  ///
+  /// The EFI scan code and Unicode value returned from the input device.
+  ///
+  EFI_INPUT_KEY   Key;
+  ///
+  /// The current state of various toggled attributes as well as input modifier values.
+  ///
+  EFI_KEY_STATE   KeyState;
+} EFI_KEY_DATA;
+
+//
+// Any Shift or Toggle State that is valid should have
+// high order bit set.
+//
+// Shift state
+//
+#define EFI_SHIFT_STATE_VALID     0x80000000
+#define EFI_RIGHT_SHIFT_PRESSED   0x00000001
+#define EFI_LEFT_SHIFT_PRESSED    0x00000002
+#define EFI_RIGHT_CONTROL_PRESSED 0x00000004
+#define EFI_LEFT_CONTROL_PRESSED  0x00000008
+#define EFI_RIGHT_ALT_PRESSED     0x00000010
+#define EFI_LEFT_ALT_PRESSED      0x00000020
+#define EFI_RIGHT_LOGO_PRESSED    0x00000040
+#define EFI_LEFT_LOGO_PRESSED     0x00000080
+#define EFI_MENU_KEY_PRESSED      0x00000100
+#define EFI_SYS_REQ_PRESSED       0x00000200
+
+//
+// Toggle state
+//
+#define EFI_TOGGLE_STATE_VALID    0x80
+#define EFI_KEY_STATE_EXPOSED     0x40
+#define EFI_SCROLL_LOCK_ACTIVE    0x01
+#define EFI_NUM_LOCK_ACTIVE       0x02
+#define EFI_CAPS_LOCK_ACTIVE      0x04
+
+//
+// EFI Scan codes
+//
+#define SCAN_F11                  0x0015
+#define SCAN_F12                  0x0016
+#define SCAN_PAUSE                0x0048
+#define SCAN_F13                  0x0068
+#define SCAN_F14                  0x0069
+#define SCAN_F15                  0x006A
+#define SCAN_F16                  0x006B
+#define SCAN_F17                  0x006C
+#define SCAN_F18                  0x006D
+#define SCAN_F19                  0x006E
+#define SCAN_F20                  0x006F
+#define SCAN_F21                  0x0070
+#define SCAN_F22                  0x0071
+#define SCAN_F23                  0x0072
+#define SCAN_F24                  0x0073
+#define SCAN_MUTE                 0x007F
+#define SCAN_VOLUME_UP            0x0080
+#define SCAN_VOLUME_DOWN          0x0081
+#define SCAN_BRIGHTNESS_UP        0x0100
+#define SCAN_BRIGHTNESS_DOWN      0x0101
+#define SCAN_SUSPEND              0x0102
+#define SCAN_HIBERNATE            0x0103
+#define SCAN_TOGGLE_DISPLAY       0x0104
+#define SCAN_RECOVERY             0x0105
+#define SCAN_EJECT                0x0106
+
+/**
+  The function reads the next keystroke from the input device. If
+  there is no pending keystroke the function returns
+  EFI_NOT_READY. If there is a pending keystroke, then
+  KeyData.Key.ScanCode is the EFI scan code defined in Error!
+  Reference source not found. The KeyData.Key.UnicodeChar is the
+  actual printable character or is zero if the key does not
+  represent a printable character (control key, function key,
+  etc.). The KeyData.KeyState is shift state for the character
+  reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode .
+  When interpreting the data from this function, it should be
+  noted that if a class of printable characters that are
+  normally adjusted by shift modifiers (e.g. Shift Key + "f"
+  key) would be presented solely as a KeyData.Key.UnicodeChar
+  without the associated shift state. So in the previous example
+  of a Shift Key + "f" key being pressed, the only pertinent
+  data returned would be KeyData.Key.UnicodeChar with the value
+  of "F". This of course would not typically be the case for
+  non-printable characters such as the pressing of the Right
+  Shift Key + F10 key since the corresponding returned data
+  would be reflected both in the KeyData.KeyState.KeyShiftState
+  and KeyData.Key.ScanCode values. UEFI drivers which implement
+  the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return
+  KeyData.Key and KeyData.KeyState values. These drivers must
+  always return the most current state of
+  KeyData.KeyState.KeyShiftState and
+  KeyData.KeyState.KeyToggleState. It should also be noted that
+  certain input devices may not be able to produce shift or toggle
+  state information, and in those cases the high order bit in the
+  respective Toggle and Shift state fields should not be active.
+
+
+  @param This     A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param KeyData  A pointer to a buffer that is filled in with
+                  the keystroke state data for the key that was
+                  pressed.
+
+
+  @retval EFI_SUCCESS     The keystroke information was
+                          returned.
+
+  @retval EFI_NOT_READY   There was no keystroke data available.
+                          EFI_DEVICE_ERROR The keystroke
+                          information was not returned due to
+                          hardware errors.
+
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INPUT_READ_KEY_EX)(
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  OUT EFI_KEY_DATA                      *KeyData
+);
+
+/**
+  The SetState() function allows the input device hardware to
+  have state settings adjusted.
+
+  @param This           A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to
+                        set the state for the input device.
+
+
+  @retval EFI_SUCCESS       The device state was set appropriately.
+
+  @retval EFI_DEVICE_ERROR  The device is not functioning
+                            correctly and could not have the
+                            setting adjusted.
+
+  @retval EFI_UNSUPPORTED   The device does not support the
+                            ability to have its state set.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_STATE)(
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  IN EFI_KEY_TOGGLE_STATE              *KeyToggleState
+);
+
+///
+/// The function will be called when the key sequence is typed specified by KeyData.
+///
+typedef
+EFI_STATUS
+(EFIAPI *EFI_KEY_NOTIFY_FUNCTION)(
+  IN EFI_KEY_DATA *KeyData
+);
+
+/**
+  The RegisterKeystrokeNotify() function registers a function
+  which will be called when a specified keystroke will occur.
+
+  @param This                     A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param KeyData                  A pointer to a buffer that is filled in with
+                                  the keystroke information for the key that was
+                                  pressed.
+
+  @param KeyNotificationFunction  Points to the function to be
+                                  called when the key sequence
+                                  is typed specified by KeyData.
+
+
+  @param NotifyHandle             Points to the unique handle assigned to
+                                  the registered notification.
+
+  @retval EFI_SUCCESS           The device state was set
+                                appropriately.
+
+  @retval EFI_OUT_OF_RESOURCES  Unable to allocate necessary
+                                data structures.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY)(
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+  IN  EFI_KEY_DATA                      *KeyData,
+  IN  EFI_KEY_NOTIFY_FUNCTION           KeyNotificationFunction,
+  OUT VOID                              **NotifyHandle
+);
+
+/**
+  The UnregisterKeystrokeNotify() function removes the
+  notification which was previously registered.
+
+  @param This               A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+  @param NotificationHandle The handle of the notification
+                            function being unregistered.
+
+  @retval EFI_SUCCESS The device state was set appropriately.
+
+  @retval EFI_INVALID_PARAMETER The NotificationHandle is
+                                invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY)(
+  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
+  IN VOID                               *NotificationHandle
+);
+
+
+///
+/// The EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL is used on the ConsoleIn
+/// device. It is an extension to the Simple Text Input protocol
+/// which allows a variety of extended shift state information to be
+/// returned.
+///
+struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL{
+  EFI_INPUT_RESET_EX              Reset;
+  EFI_INPUT_READ_KEY_EX           ReadKeyStrokeEx;
+  ///
+  /// Event to use with WaitForEvent() to wait for a key to be available.
+  ///
+  EFI_EVENT                       WaitForKeyEx;
+  EFI_SET_STATE                   SetState;
+  EFI_REGISTER_KEYSTROKE_NOTIFY   RegisterKeyNotify;
+  EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
+};
+
+
+extern EFI_GUID gEfiSimpleTextInputExProtocolGuid;
+
+#endif
+
diff --git a/sys/contrib/edk2/Include/Uefi.h b/sys/contrib/edk2/Include/Uefi.h
new file mode 100644
index 0000000000..4b21013177
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi.h
@@ -0,0 +1,27 @@
+/** @file
+
+  Root include file for Mde Package UEFI, UEFI_APPLICATION type modules.
+
+  This is the include file for any module of type UEFI and UEFI_APPLICATION. Uefi modules only use 
+  types defined via this include file and can be ported easily to any 
+  environment. 
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.                                          
+    
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PI_UEFI_H__
+#define __PI_UEFI_H__
+
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+
+#endif
+
diff --git a/sys/contrib/edk2/Include/Uefi/UefiBaseType.h b/sys/contrib/edk2/Include/Uefi/UefiBaseType.h
new file mode 100644
index 0000000000..32b39c9fed
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi/UefiBaseType.h
@@ -0,0 +1,299 @@
+/** @file
+  Defines data types and constants introduced in UEFI.
+
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.                                          
+    
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_BASETYPE_H__
+#define __UEFI_BASETYPE_H__
+
+#include <Base.h>
+
+//
+// Basic data type definitions introduced in UEFI.
+//
+
+///
+/// 128-bit buffer containing a unique identifier value.
+///
+typedef GUID                      EFI_GUID;
+///
+/// Function return status for EFI API.
+///
+typedef RETURN_STATUS             EFI_STATUS;
+///
+/// A collection of related interfaces.
+///
+typedef VOID                      *EFI_HANDLE;
+///
+/// Handle to an event structure.
+///
+typedef VOID                      *EFI_EVENT;
+///
+/// Task priority level.
+///
+typedef UINTN                     EFI_TPL;
+///
+/// Logical block address.
+///
+typedef UINT64                    EFI_LBA;
+
+///
+/// 64-bit physical memory address.
+///
+typedef UINT64                    EFI_PHYSICAL_ADDRESS;
+
+///
+/// 64-bit virtual memory address.
+///
+typedef UINT64                    EFI_VIRTUAL_ADDRESS;
+
+///
+/// EFI Time Abstraction:
+///  Year:       1900 - 9999
+///  Month:      1 - 12
+///  Day:        1 - 31
+///  Hour:       0 - 23
+///  Minute:     0 - 59
+///  Second:     0 - 59
+///  Nanosecond: 0 - 999,999,999
+///  TimeZone:   -1440 to 1440 or 2047
+///
+typedef struct {
+  UINT16  Year;
+  UINT8   Month;
+  UINT8   Day;
+  UINT8   Hour;
+  UINT8   Minute;
+  UINT8   Second;
+  UINT8   Pad1;
+  UINT32  Nanosecond;
+  INT16   TimeZone;
+  UINT8   Daylight;
+  UINT8   Pad2;
+} EFI_TIME;
+
+
+///
+/// 4-byte buffer. An IPv4 internet protocol address.
+///
+typedef IPv4_ADDRESS EFI_IPv4_ADDRESS;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef IPv6_ADDRESS EFI_IPv6_ADDRESS;
+
+///
+/// 32-byte buffer containing a network Media Access Control address.
+///
+typedef struct {
+  UINT8 Addr[32];
+} EFI_MAC_ADDRESS;
+
+///
+/// 16-byte buffer aligned on a 4-byte boundary.
+/// An IPv4 or IPv6 internet protocol address.
+///
+typedef union {
+  UINT32            Addr[4];
+  EFI_IPv4_ADDRESS  v4;
+  EFI_IPv6_ADDRESS  v6;
+} EFI_IP_ADDRESS;
+
+
+///
+/// Enumeration of EFI_STATUS.
+///@{ 
+#define EFI_SUCCESS               RETURN_SUCCESS              
+#define EFI_LOAD_ERROR            RETURN_LOAD_ERROR           
+#define EFI_INVALID_PARAMETER     RETURN_INVALID_PARAMETER    
+#define EFI_UNSUPPORTED           RETURN_UNSUPPORTED          
+#define EFI_BAD_BUFFER_SIZE       RETURN_BAD_BUFFER_SIZE      
+#define EFI_BUFFER_TOO_SMALL      RETURN_BUFFER_TOO_SMALL     
+#define EFI_NOT_READY             RETURN_NOT_READY            
+#define EFI_DEVICE_ERROR          RETURN_DEVICE_ERROR         
+#define EFI_WRITE_PROTECTED       RETURN_WRITE_PROTECTED      
+#define EFI_OUT_OF_RESOURCES      RETURN_OUT_OF_RESOURCES     
+#define EFI_VOLUME_CORRUPTED      RETURN_VOLUME_CORRUPTED     
+#define EFI_VOLUME_FULL           RETURN_VOLUME_FULL          
+#define EFI_NO_MEDIA              RETURN_NO_MEDIA             
+#define EFI_MEDIA_CHANGED         RETURN_MEDIA_CHANGED        
+#define EFI_NOT_FOUND             RETURN_NOT_FOUND            
+#define EFI_ACCESS_DENIED         RETURN_ACCESS_DENIED        
+#define EFI_NO_RESPONSE           RETURN_NO_RESPONSE          
+#define EFI_NO_MAPPING            RETURN_NO_MAPPING           
+#define EFI_TIMEOUT               RETURN_TIMEOUT              
+#define EFI_NOT_STARTED           RETURN_NOT_STARTED          
+#define EFI_ALREADY_STARTED       RETURN_ALREADY_STARTED      
+#define EFI_ABORTED               RETURN_ABORTED              
+#define EFI_ICMP_ERROR            RETURN_ICMP_ERROR           
+#define EFI_TFTP_ERROR            RETURN_TFTP_ERROR           
+#define EFI_PROTOCOL_ERROR        RETURN_PROTOCOL_ERROR       
+#define EFI_INCOMPATIBLE_VERSION  RETURN_INCOMPATIBLE_VERSION 
+#define EFI_SECURITY_VIOLATION    RETURN_SECURITY_VIOLATION   
+#define EFI_CRC_ERROR             RETURN_CRC_ERROR   
+#define EFI_END_OF_MEDIA          RETURN_END_OF_MEDIA
+#define EFI_END_OF_FILE           RETURN_END_OF_FILE
+#define EFI_INVALID_LANGUAGE      RETURN_INVALID_LANGUAGE
+#define EFI_COMPROMISED_DATA      RETURN_COMPROMISED_DATA
+#define EFI_HTTP_ERROR            RETURN_HTTP_ERROR
+
+#define EFI_WARN_UNKNOWN_GLYPH    RETURN_WARN_UNKNOWN_GLYPH   
+#define EFI_WARN_DELETE_FAILURE   RETURN_WARN_DELETE_FAILURE  
+#define EFI_WARN_WRITE_FAILURE    RETURN_WARN_WRITE_FAILURE   
+#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
+#define EFI_WARN_STALE_DATA       RETURN_WARN_STALE_DATA
+#define EFI_WARN_FILE_SYSTEM      RETURN_WARN_FILE_SYSTEM
+///@}
+
+///
+/// Define macro to encode the status code.
+/// 
+#define EFIERR(_a)                ENCODE_ERROR(_a)
+
+#define EFI_ERROR(A)              RETURN_ERROR(A)
+
+///
+/// ICMP error definitions
+///@{
+#define EFI_NETWORK_UNREACHABLE   EFIERR(100)
+#define EFI_HOST_UNREACHABLE      EFIERR(101) 
+#define EFI_PROTOCOL_UNREACHABLE  EFIERR(102)
+#define EFI_PORT_UNREACHABLE      EFIERR(103)
+///@}
+
+///
+/// Tcp connection status definitions
+///@{
+#define EFI_CONNECTION_FIN        EFIERR(104)
+#define EFI_CONNECTION_RESET      EFIERR(105)
+#define EFI_CONNECTION_REFUSED    EFIERR(106)
+///@}
+
+//
+// The EFI memory allocation functions work in units of EFI_PAGEs that are
+// 4KB. This should in no way be confused with the page size of the processor.
+// An EFI_PAGE is just the quanta of memory in EFI.
+//
+#define EFI_PAGE_SIZE             SIZE_4KB
+#define EFI_PAGE_MASK             0xFFF
+#define EFI_PAGE_SHIFT            12
+
+/**
+  Macro that converts a size, in bytes, to a number of EFI_PAGESs.
+
+  @param  Size      A size in bytes.  This parameter is assumed to be type UINTN.  
+                    Passing in a parameter that is larger than UINTN may produce 
+                    unexpected results.
+
+  @return  The number of EFI_PAGESs associated with the number of bytes specified
+           by Size.
+
+**/
+#define EFI_SIZE_TO_PAGES(Size)  (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0))
+
+/**
+  Macro that converts a number of EFI_PAGEs to a size in bytes.
+
+  @param  Pages     The number of EFI_PAGES.  This parameter is assumed to be 
+                    type UINTN.  Passing in a parameter that is larger than 
+                    UINTN may produce unexpected results.
+
+  @return  The number of bytes associated with the number of EFI_PAGEs specified 
+           by Pages.
+  
+**/
+#define EFI_PAGES_TO_SIZE(Pages)  ((Pages) << EFI_PAGE_SHIFT)
+
+///
+/// PE32+ Machine type for IA32 UEFI images.
+///
+#define EFI_IMAGE_MACHINE_IA32            0x014C
+
+///
+/// PE32+ Machine type for IA64 UEFI images.
+///
+#define EFI_IMAGE_MACHINE_IA64            0x0200
+
+///
+/// PE32+ Machine type for EBC UEFI images.
+///
+#define EFI_IMAGE_MACHINE_EBC             0x0EBC
+
+///
+/// PE32+ Machine type for X64 UEFI images.
+///
+#define EFI_IMAGE_MACHINE_X64             0x8664
+
+///
+/// PE32+ Machine type for ARM mixed ARM and Thumb/Thumb2 images.
+///
+#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED  0x01C2
+
+///
+/// PE32+ Machine type for AARCH64 A64 images.
+///
+#define EFI_IMAGE_MACHINE_AARCH64  0xAA64
+
+
+#if   defined (MDE_CPU_IA32)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64) 
+
+#elif defined (MDE_CPU_IPF)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_IA64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) 
+
+#elif defined (MDE_CPU_X64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32) 
+
+#elif defined (MDE_CPU_ARM)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED) 
+
+#elif defined (MDE_CPU_AARCH64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+  (((Machine) == EFI_IMAGE_MACHINE_AARCH64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
+#elif defined (MDE_CPU_EBC)
+
+///
+/// This is just to make sure you can cross compile with the EBC compiler.
+/// It does not make sense to have a PE loader coded in EBC. 
+///
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) 
+
+#else
+#error Unknown Processor Type
+#endif
+
+#endif
diff --git a/sys/contrib/edk2/Include/Uefi/UefiGpt.h b/sys/contrib/edk2/Include/Uefi/UefiGpt.h
new file mode 100644
index 0000000000..aa3c9bec0b
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi/UefiGpt.h
@@ -0,0 +1,141 @@
+/** @file
+  EFI Guid Partition Table Format Definition.
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.                                          
+    
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_GPT_H__
+#define __UEFI_GPT_H__
+
+///
+/// The primary GUID Partition Table Header must be
+/// located in LBA 1 (i.e., the second logical block).
+///
+#define PRIMARY_PART_HEADER_LBA 1
+///
+/// EFI Partition Table Signature: "EFI PART".
+/// 
+#define EFI_PTAB_HEADER_ID      SIGNATURE_64 ('E','F','I',' ','P','A','R','T')
+
+#pragma pack(1)
+
+///
+/// GPT Partition Table Header.
+///
+typedef struct {
+  ///
+  /// The table header for the GPT partition Table.
+  /// This header contains EFI_PTAB_HEADER_ID.
+  ///
+  EFI_TABLE_HEADER  Header;
+  ///
+  /// The LBA that contains this data structure.
+  ///
+  EFI_LBA           MyLBA;
+  ///
+  /// LBA address of the alternate GUID Partition Table Header.
+  ///
+  EFI_LBA           AlternateLBA;
+  ///
+  /// The first usable logical block that may be used
+  /// by a partition described by a GUID Partition Entry.
+  ///
+  EFI_LBA           FirstUsableLBA;
+  ///
+  /// The last usable logical block that may be used
+  /// by a partition described by a GUID Partition Entry.
+  ///
+  EFI_LBA           LastUsableLBA;
+  ///
+  /// GUID that can be used to uniquely identify the disk.
+  ///
+  EFI_GUID          DiskGUID;
+  ///
+  /// The starting LBA of the GUID Partition Entry array.
+  ///
+  EFI_LBA           PartitionEntryLBA;
+  ///
+  /// The number of Partition Entries in the GUID Partition Entry array.
+  ///
+  UINT32            NumberOfPartitionEntries;
+  ///
+  /// The size, in bytes, of each the GUID Partition
+  /// Entry structures in the GUID Partition Entry
+  /// array. This field shall be set to a value of 128 x 2^n where n is
+  /// an integer greater than or equal to zero (e.g., 128, 256, 512, etc.).
+  ///
+  UINT32            SizeOfPartitionEntry;
+  ///
+  /// The CRC32 of the GUID Partition Entry array.
+  /// Starts at PartitionEntryLBA and is
+  /// computed over a byte length of
+  /// NumberOfPartitionEntries * SizeOfPartitionEntry.
+  ///
+  UINT32            PartitionEntryArrayCRC32;
+} EFI_PARTITION_TABLE_HEADER;
+
+///
+/// GPT Partition Entry.
+///
+typedef struct {
+  ///
+  /// Unique ID that defines the purpose and type of this Partition. A value of
+  /// zero defines that this partition entry is not being used.
+  ///
+  EFI_GUID  PartitionTypeGUID;
+  ///
+  /// GUID that is unique for every partition entry. Every partition ever
+  /// created will have a unique GUID.
+  /// This GUID must be assigned when the GUID Partition Entry is created.
+  ///
+  EFI_GUID  UniquePartitionGUID;
+  ///
+  /// Starting LBA of the partition defined by this entry
+  ///
+  EFI_LBA   StartingLBA;
+  ///
+  /// Ending LBA of the partition defined by this entry.
+  ///
+  EFI_LBA   EndingLBA;
+  ///
+  /// Attribute bits, all bits reserved by UEFI
+  /// Bit 0:      If this bit is set, the partition is required for the platform to function. The owner/creator of the
+  ///             partition indicates that deletion or modification of the contents can result in loss of platform
+  ///             features or failure for the platform to boot or operate. The system cannot function normally if
+  ///             this partition is removed, and it should be considered part of the hardware of the system.
+  ///             Actions such as running diagnostics, system recovery, or even OS install or boot, could
+  ///             potentially stop working if this partition is removed. Unless OS software or firmware
+  ///             recognizes this partition, it should never be removed or modified as the UEFI firmware or
+  ///             platform hardware may become non-functional.
+  /// Bit 1:      If this bit is set, then firmware must not produce an EFI_BLOCK_IO_PROTOCOL device for
+  ///             this partition. By not producing an EFI_BLOCK_IO_PROTOCOL partition, file system
+  ///             mappings will not be created for this partition in UEFI.
+  /// Bit 2:      This bit is set aside to let systems with traditional PC-AT BIOS firmware implementations
+  ///             inform certain limited, special-purpose software running on these systems that a GPT 
+  ///             partition may be bootable. The UEFI boot manager must ignore this bit when selecting
+  ///             a UEFI-compliant application, e.g., an OS loader.
+  /// Bits 3-47:  Undefined and must be zero. Reserved for expansion by future versions of the UEFI
+  ///             specification.
+  /// Bits 48-63: Reserved for GUID specific use. The use of these bits will vary depending on the
+  ///             PartitionTypeGUID. Only the owner of the PartitionTypeGUID is allowed
+  ///             to modify these bits. They must be preserved if Bits 0-47 are modified..
+  ///
+  UINT64    Attributes;
+  ///
+  /// Null-terminated name of the partition.
+  ///
+  CHAR16    PartitionName[36];
+} EFI_PARTITION_ENTRY;
+
+#pragma pack()
+#endif
+
+
diff --git a/sys/contrib/edk2/Include/Uefi/UefiInternalFormRepresentation.h b/sys/contrib/edk2/Include/Uefi/UefiInternalFormRepresentation.h
new file mode 100644
index 0000000000..389c12c1f0
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi/UefiInternalFormRepresentation.h
@@ -0,0 +1,2135 @@
+/** @file
+  This file defines the encoding for the VFR (Visual Form Representation) language.
+  IFR is primarily consumed by the EFI presentation engine, and produced by EFI
+  internal application and drivers as well as all add-in card option-ROM drivers
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that 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.             
+
+  @par Revision Reference:
+  These definitions are from UEFI 2.1 and 2.2.
+
+**/
+
+#ifndef __UEFI_INTERNAL_FORMREPRESENTATION_H__
+#define __UEFI_INTERNAL_FORMREPRESENTATION_H__
+
+#include <Guid/HiiFormMapMethodGuid.h>
+
+///
+/// The following types are currently defined:
+///
+typedef VOID*   EFI_HII_HANDLE;
+typedef CHAR16* EFI_STRING;
+typedef UINT16  EFI_IMAGE_ID;
+typedef UINT16  EFI_QUESTION_ID;
+typedef UINT16  EFI_STRING_ID;
+typedef UINT16  EFI_FORM_ID;
+typedef UINT16  EFI_VARSTORE_ID;
+typedef UINT16  EFI_ANIMATION_ID;
+
+typedef UINT16  EFI_DEFAULT_ID;
+
+typedef UINT32  EFI_HII_FONT_STYLE;
+
+
+
+#pragma pack(1)
+
+//
+// Definitions for Package Lists and Package Headers
+// Section 27.3.1
+//
+
+///
+/// The header found at the start of each package list.
+///
+typedef struct {
+  EFI_GUID               PackageListGuid;
+  UINT32                 PackageLength;
+} EFI_HII_PACKAGE_LIST_HEADER;
+
+///
+/// The header found at the start of each package.
+///
+typedef struct {
+  UINT32  Length:24;
+  UINT32  Type:8;
+  // UINT8  Data[...];
+} EFI_HII_PACKAGE_HEADER;
+
+//
+// Value of HII package type
+// 
+#define EFI_HII_PACKAGE_TYPE_ALL             0x00
+#define EFI_HII_PACKAGE_TYPE_GUID            0x01
+#define EFI_HII_PACKAGE_FORMS                0x02
+#define EFI_HII_PACKAGE_STRINGS              0x04
+#define EFI_HII_PACKAGE_FONTS                0x05
+#define EFI_HII_PACKAGE_IMAGES               0x06
+#define EFI_HII_PACKAGE_SIMPLE_FONTS         0x07
+#define EFI_HII_PACKAGE_DEVICE_PATH          0x08
+#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT      0x09
+#define EFI_HII_PACKAGE_ANIMATIONS           0x0A
+#define EFI_HII_PACKAGE_END                  0xDF
+#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN    0xE0
+#define EFI_HII_PACKAGE_TYPE_SYSTEM_END      0xFF
+
+//
+// Definitions for Simplified Font Package
+//
+
+///
+/// Contents of EFI_NARROW_GLYPH.Attributes.
+///@{
+#define EFI_GLYPH_NON_SPACING                0x01
+#define EFI_GLYPH_WIDE                       0x02
+#define EFI_GLYPH_HEIGHT                     19
+#define EFI_GLYPH_WIDTH                      8
+///@}
+
+///
+/// The EFI_NARROW_GLYPH has a preferred dimension (w x h) of 8 x 19 pixels.
+///
+typedef struct {
+  ///
+  /// The Unicode representation of the glyph. The term weight is the 
+  /// technical term for a character code.
+  ///
+  CHAR16                 UnicodeWeight;
+  ///
+  /// The data element containing the glyph definitions.
+  ///
+  UINT8                  Attributes;
+  ///
+  /// The column major glyph representation of the character. Bits 
+  /// with values of one indicate that the corresponding pixel is to be
+  /// on when normally displayed; those with zero are off.
+  ///
+  UINT8                  GlyphCol1[EFI_GLYPH_HEIGHT];
+} EFI_NARROW_GLYPH;
+
+///
+/// The EFI_WIDE_GLYPH has a preferred dimension (w x h) of 16 x 19 pixels, which is large enough 
+/// to accommodate logographic characters.
+///
+typedef struct {
+  ///
+  /// The Unicode representation of the glyph. The term weight is the 
+  /// technical term for a character code.
+  ///
+  CHAR16                 UnicodeWeight;
+  ///
+  /// The data element containing the glyph definitions.
+  ///
+  UINT8                  Attributes;
+  ///
+  /// The column major glyph representation of the character. Bits 
+  /// with values of one indicate that the corresponding pixel is to be 
+  /// on when normally displayed; those with zero are off.
+  ///
+  UINT8                  GlyphCol1[EFI_GLYPH_HEIGHT];
+  ///
+  /// The column major glyph representation of the character. Bits 
+  /// with values of one indicate that the corresponding pixel is to be 
+  /// on when normally displayed; those with zero are off.
+  ///
+  UINT8                  GlyphCol2[EFI_GLYPH_HEIGHT];
+  ///
+  /// Ensures that sizeof (EFI_WIDE_GLYPH) is twice the 
+  /// sizeof (EFI_NARROW_GLYPH). The contents of Pad must 
+  /// be zero.
+  ///
+  UINT8                  Pad[3];
+} EFI_WIDE_GLYPH;
+
+///
+/// A simplified font package consists of a font header
+/// followed by a series of glyph structures.
+///
+typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER Header;
+  UINT16                 NumberOfNarrowGlyphs;
+  UINT16                 NumberOfWideGlyphs;
+  // EFI_NARROW_GLYPH       NarrowGlyphs[];
+  // EFI_WIDE_GLYPH         WideGlyphs[];
+} EFI_HII_SIMPLE_FONT_PACKAGE_HDR;
+
+//
+// Definitions for Font Package
+// Section 27.3.3
+//
+
+//
+// Value for font style
+//
+#define EFI_HII_FONT_STYLE_NORMAL            0x00000000
+#define EFI_HII_FONT_STYLE_BOLD              0x00000001
+#define EFI_HII_FONT_STYLE_ITALIC            0x00000002
+#define EFI_HII_FONT_STYLE_EMBOSS            0x00010000
+#define EFI_HII_FONT_STYLE_OUTLINE           0x00020000
+#define EFI_HII_FONT_STYLE_SHADOW            0x00040000
+#define EFI_HII_FONT_STYLE_UNDERLINE         0x00080000
+#define EFI_HII_FONT_STYLE_DBL_UNDER         0x00100000
+
+typedef struct _EFI_HII_GLYPH_INFO {
+  UINT16                 Width;
+  UINT16                 Height;
+  INT16                  OffsetX;
+  INT16                  OffsetY;
+  INT16                  AdvanceX;
+} EFI_HII_GLYPH_INFO;
+
+///
+/// The fixed header consists of a standard record header,
+/// then the character values in this section, the flags
+/// (including the encoding method) and the offsets of the glyph
+/// information, the glyph bitmaps and the character map.
+///
+typedef struct _EFI_HII_FONT_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER Header;
+  UINT32                 HdrSize;
+  UINT32                 GlyphBlockOffset;
+  EFI_HII_GLYPH_INFO     Cell;
+  EFI_HII_FONT_STYLE     FontStyle;
+  CHAR16                 FontFamily[1];
+} EFI_HII_FONT_PACKAGE_HDR;
+
+//
+// Value of different glyph info block types
+//
+#define EFI_HII_GIBT_END                  0x00
+#define EFI_HII_GIBT_GLYPH                0x10
+#define EFI_HII_GIBT_GLYPHS               0x11
+#define EFI_HII_GIBT_GLYPH_DEFAULT        0x12
+#define EFI_HII_GIBT_GLYPHS_DEFAULT       0x13
+#define EFI_HII_GIBT_GLYPH_VARIABILITY    0x14
+#define EFI_HII_GIBT_DUPLICATE            0x20
+#define EFI_HII_GIBT_SKIP2                0x21
+#define EFI_HII_GIBT_SKIP1                0x22
+#define EFI_HII_GIBT_DEFAULTS             0x23
+#define EFI_HII_GIBT_EXT1                 0x30
+#define EFI_HII_GIBT_EXT2                 0x31
+#define EFI_HII_GIBT_EXT4                 0x32
+
+typedef struct _EFI_HII_GLYPH_BLOCK {
+  UINT8                  BlockType;
+} EFI_HII_GLYPH_BLOCK;
+
+//
+// Definition of different glyph info block types
+//
+
+typedef struct _EFI_HII_GIBT_DEFAULTS_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+} EFI_HII_GIBT_DEFAULTS_BLOCK;
+
+typedef struct _EFI_HII_GIBT_DUPLICATE_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  CHAR16                 CharValue;
+} EFI_HII_GIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_GLYPH_GIBT_END_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+} EFI_GLYPH_GIBT_END_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT1_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BlockType2;
+  UINT8                  Length;
+} EFI_HII_GIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT2_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BlockType2;
+  UINT16                 Length;
+} EFI_HII_GIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_GIBT_EXT4_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BlockType2;
+  UINT32                 Length;
+} EFI_HII_GIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPH_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPH_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPHS_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+  UINT16                 Count;  
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPHS_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK;
+
+typedef struct _EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT16                 Count;
+  UINT8                  BitmapData[1];
+} EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK;
+
+typedef struct _EFI_HII_GIBT_VARIABILITY_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  EFI_HII_GLYPH_INFO     Cell;
+  UINT8                  GlyphPackInBits;
+  UINT8                  BitmapData [1];
+} EFI_HII_GIBT_VARIABILITY_BLOCK;
+
+typedef struct _EFI_HII_GIBT_SKIP1_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT8                  SkipCount;
+} EFI_HII_GIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_GIBT_SKIP2_BLOCK {
+  EFI_HII_GLYPH_BLOCK    Header;
+  UINT16                 SkipCount;
+} EFI_HII_GIBT_SKIP2_BLOCK;
+
+//
+// Definitions for Device Path Package
+// Section 27.3.4
+//
+
+///
+/// The device path package is used to carry a device path
+/// associated with the package list.
+///
+typedef struct _EFI_HII_DEVICE_PATH_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER   Header;
+  // EFI_DEVICE_PATH_PROTOCOL DevicePath[];
+} EFI_HII_DEVICE_PATH_PACKAGE_HDR;
+
+//
+// Definitions for GUID Package
+// Section 27.3.5
+//
+
+///
+/// The GUID package is used to carry data where the format is defined by a GUID.
+///
+typedef struct _EFI_HII_GUID_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER  Header;
+  EFI_GUID                Guid;
+  // Data per GUID definition may follow
+} EFI_HII_GUID_PACKAGE_HDR;
+
+//
+// Definitions for String Package
+// Section 27.3.6
+//
+
+#define UEFI_CONFIG_LANG   "x-UEFI"
+#define UEFI_CONFIG_LANG_2 "x-i-UEFI"
+
+///
+/// The fixed header consists of a standard record header and then the string identifiers
+/// contained in this section and the offsets of the string and language information.
+///
+typedef struct _EFI_HII_STRING_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER  Header;
+  UINT32                  HdrSize;
+  UINT32                  StringInfoOffset;
+  CHAR16                  LanguageWindow[16];
+  EFI_STRING_ID           LanguageName;
+  CHAR8                   Language[1];
+} EFI_HII_STRING_PACKAGE_HDR;
+
+typedef struct {
+  UINT8                   BlockType;
+} EFI_HII_STRING_BLOCK;
+
+//
+// Value of different string information block types
+//
+#define EFI_HII_SIBT_END                     0x00
+#define EFI_HII_SIBT_STRING_SCSU             0x10
+#define EFI_HII_SIBT_STRING_SCSU_FONT        0x11
+#define EFI_HII_SIBT_STRINGS_SCSU            0x12
+#define EFI_HII_SIBT_STRINGS_SCSU_FONT       0x13
+#define EFI_HII_SIBT_STRING_UCS2             0x14
+#define EFI_HII_SIBT_STRING_UCS2_FONT        0x15
+#define EFI_HII_SIBT_STRINGS_UCS2            0x16
+#define EFI_HII_SIBT_STRINGS_UCS2_FONT       0x17
+#define EFI_HII_SIBT_DUPLICATE               0x20
+#define EFI_HII_SIBT_SKIP2                   0x21
+#define EFI_HII_SIBT_SKIP1                   0x22
+#define EFI_HII_SIBT_EXT1                    0x30
+#define EFI_HII_SIBT_EXT2                    0x31
+#define EFI_HII_SIBT_EXT4                    0x32
+#define EFI_HII_SIBT_FONT                    0x40
+
+//
+// Definition of different string information block types
+//
+
+typedef struct _EFI_HII_SIBT_DUPLICATE_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  EFI_STRING_ID           StringId;
+} EFI_HII_SIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_HII_SIBT_END_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+} EFI_HII_SIBT_END_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT1_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   BlockType2;
+  UINT8                   Length;
+} EFI_HII_SIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   BlockType2;
+  UINT16                  Length;
+} EFI_HII_SIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_EXT4_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   BlockType2;
+  UINT32                  Length;
+} EFI_HII_SIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_SIBT_FONT_BLOCK {
+  EFI_HII_SIBT_EXT2_BLOCK Header;
+  UINT8                   FontId;
+  UINT16                  FontSize;
+  EFI_HII_FONT_STYLE      FontStyle;
+  CHAR16                  FontName[1];
+} EFI_HII_SIBT_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_SKIP1_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   SkipCount;
+} EFI_HII_SIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_SIBT_SKIP2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT16                  SkipCount;
+} EFI_HII_SIBT_SKIP2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_SCSU_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRING_SCSU_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_SCSU_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT16                  StringCount;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRINGS_SCSU_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  UINT16                  StringCount;
+  UINT8                   StringText[1];
+} EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_UCS2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRING_UCS2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_UCS2_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT16                  StringCount;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRINGS_UCS2_BLOCK;
+
+typedef struct _EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK {
+  EFI_HII_STRING_BLOCK    Header;
+  UINT8                   FontIdentifier;
+  UINT16                  StringCount;
+  CHAR16                  StringText[1];
+} EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK;
+
+//
+// Definitions for Image Package
+// Section 27.3.7
+//
+
+typedef struct _EFI_HII_IMAGE_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER  Header;
+  UINT32                  ImageInfoOffset;
+  UINT32                  PaletteInfoOffset;
+} EFI_HII_IMAGE_PACKAGE_HDR;
+
+typedef struct _EFI_HII_IMAGE_BLOCK {
+  UINT8                   BlockType;
+} EFI_HII_IMAGE_BLOCK;
+
+//
+// Value of different image information block types
+//
+#define EFI_HII_IIBT_END               0x00
+#define EFI_HII_IIBT_IMAGE_1BIT        0x10
+#define EFI_HII_IIBT_IMAGE_1BIT_TRANS  0x11
+#define EFI_HII_IIBT_IMAGE_4BIT        0x12
+#define EFI_HII_IIBT_IMAGE_4BIT_TRANS  0x13
+#define EFI_HII_IIBT_IMAGE_8BIT        0x14
+#define EFI_HII_IIBT_IMAGE_8BIT_TRANS  0x15
+#define EFI_HII_IIBT_IMAGE_24BIT       0x16
+#define EFI_HII_IIBT_IMAGE_24BIT_TRANS 0x17
+#define EFI_HII_IIBT_IMAGE_JPEG        0x18
+#define EFI_HII_IIBT_IMAGE_PNG         0x19
+#define EFI_HII_IIBT_DUPLICATE         0x20
+#define EFI_HII_IIBT_SKIP2             0x21
+#define EFI_HII_IIBT_SKIP1             0x22
+#define EFI_HII_IIBT_EXT1              0x30
+#define EFI_HII_IIBT_EXT2              0x31
+#define EFI_HII_IIBT_EXT4              0x32
+
+//
+// Definition of different image information block types
+//
+
+typedef struct _EFI_HII_IIBT_END_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+} EFI_HII_IIBT_END_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT1_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        BlockType2;
+  UINT8                        Length;
+} EFI_HII_IIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT2_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        BlockType2;
+  UINT16                       Length;
+} EFI_HII_IIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_IIBT_EXT4_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        BlockType2;
+  UINT32                       Length;
+} EFI_HII_IIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_IMAGE_1BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_1BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_RGB_PIXEL {
+  UINT8                        b;
+  UINT8                        g;
+  UINT8                        r;
+} EFI_HII_RGB_PIXEL;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  EFI_HII_RGB_PIXEL            Bitmap[1];
+} EFI_HII_IIBT_IMAGE_24BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BLOCK {
+  EFI_HII_IMAGE_BLOCK           Header;
+  EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_24BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK           Header;
+  EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_IMAGE_4BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_4BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_BASE {
+  UINT16                       Width;
+  UINT16                       Height;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_IMAGE_8BIT_BASE;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_PALETTE_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_8BIT_BLOCK;
+
+typedef struct _EFI_HII_IIBT_IMAGE_8BIT_TRANS_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        PaletteIndex;
+  EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap;
+} EFI_HII_IIBT_IMAGE_8BIT_TRAN_BLOCK;
+
+typedef struct _EFI_HII_IIBT_DUPLICATE_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  EFI_IMAGE_ID                 ImageId;
+} EFI_HII_IIBT_DUPLICATE_BLOCK;
+
+typedef struct _EFI_HII_IIBT_JPEG_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT32                       Size;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_JPEG_BLOCK;
+
+typedef struct _EFI_HII_IIBT_PNG_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT32                       Size;
+  UINT8                        Data[1];
+} EFI_HII_IIBT_PNG_BLOCK;
+
+typedef struct _EFI_HII_IIBT_SKIP1_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT8                        SkipCount;
+} EFI_HII_IIBT_SKIP1_BLOCK;
+
+typedef struct _EFI_HII_IIBT_SKIP2_BLOCK {
+  EFI_HII_IMAGE_BLOCK          Header;
+  UINT16                       SkipCount;
+} EFI_HII_IIBT_SKIP2_BLOCK;
+
+//
+// Definitions for Palette Information
+//
+
+typedef struct _EFI_HII_IMAGE_PALETTE_INFO_HEADER {
+  UINT16                       PaletteCount;
+} EFI_HII_IMAGE_PALETTE_INFO_HEADER;
+
+typedef struct _EFI_HII_IMAGE_PALETTE_INFO {
+  UINT16                       PaletteSize;
+  EFI_HII_RGB_PIXEL            PaletteValue[1];
+} EFI_HII_IMAGE_PALETTE_INFO;
+
+//
+// Definitions for Forms Package
+// Section 27.3.8
+//
+
+///
+/// The Form package is used to carry form-based encoding data.
+///
+typedef struct _EFI_HII_FORM_PACKAGE_HDR {
+  EFI_HII_PACKAGE_HEADER       Header;
+  // EFI_IFR_OP_HEADER         OpCodeHeader;
+  // More op-codes follow
+} EFI_HII_FORM_PACKAGE_HDR;
+
+typedef struct {
+  UINT8 Hour;
+  UINT8 Minute;
+  UINT8 Second;
+} EFI_HII_TIME;
+
+typedef struct {
+  UINT16 Year;
+  UINT8  Month;
+  UINT8  Day;
+} EFI_HII_DATE;
+
+typedef struct {
+  EFI_QUESTION_ID QuestionId;
+  EFI_FORM_ID     FormId;
+  EFI_GUID        FormSetGuid;
+  EFI_STRING_ID   DevicePath;
+} EFI_HII_REF;
+
+typedef union {
+  UINT8           u8;
+  UINT16          u16;
+  UINT32          u32;
+  UINT64          u64;
+  BOOLEAN         b;
+  EFI_HII_TIME    time;
+  EFI_HII_DATE    date;
+  EFI_STRING_ID   string; ///< EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION
+  EFI_HII_REF     ref;    ///< EFI_IFR_TYPE_REF
+  // UINT8 buffer[];      ///< EFI_IFR_TYPE_BUFFER
+} EFI_IFR_TYPE_VALUE;
+
+//
+// IFR Opcodes
+//
+#define EFI_IFR_FORM_OP                0x01
+#define EFI_IFR_SUBTITLE_OP            0x02
+#define EFI_IFR_TEXT_OP                0x03
+#define EFI_IFR_IMAGE_OP               0x04
+#define EFI_IFR_ONE_OF_OP              0x05
+#define EFI_IFR_CHECKBOX_OP            0x06
+#define EFI_IFR_NUMERIC_OP             0x07
+#define EFI_IFR_PASSWORD_OP            0x08
+#define EFI_IFR_ONE_OF_OPTION_OP       0x09
+#define EFI_IFR_SUPPRESS_IF_OP         0x0A
+#define EFI_IFR_LOCKED_OP              0x0B
+#define EFI_IFR_ACTION_OP              0x0C
+#define EFI_IFR_RESET_BUTTON_OP        0x0D
+#define EFI_IFR_FORM_SET_OP            0x0E
+#define EFI_IFR_REF_OP                 0x0F
+#define EFI_IFR_NO_SUBMIT_IF_OP        0x10
+#define EFI_IFR_INCONSISTENT_IF_OP     0x11
+#define EFI_IFR_EQ_ID_VAL_OP           0x12
+#define EFI_IFR_EQ_ID_ID_OP            0x13
+#define EFI_IFR_EQ_ID_VAL_LIST_OP      0x14
+#define EFI_IFR_AND_OP                 0x15
+#define EFI_IFR_OR_OP                  0x16
+#define EFI_IFR_NOT_OP                 0x17
+#define EFI_IFR_RULE_OP                0x18
+#define EFI_IFR_GRAY_OUT_IF_OP         0x19
+#define EFI_IFR_DATE_OP                0x1A
+#define EFI_IFR_TIME_OP                0x1B
+#define EFI_IFR_STRING_OP              0x1C
+#define EFI_IFR_REFRESH_OP             0x1D
+#define EFI_IFR_DISABLE_IF_OP          0x1E
+#define EFI_IFR_ANIMATION_OP           0x1F
+#define EFI_IFR_TO_LOWER_OP            0x20
+#define EFI_IFR_TO_UPPER_OP            0x21
+#define EFI_IFR_MAP_OP                 0x22
+#define EFI_IFR_ORDERED_LIST_OP        0x23
+#define EFI_IFR_VARSTORE_OP            0x24
+#define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25
+#define EFI_IFR_VARSTORE_EFI_OP        0x26
+#define EFI_IFR_VARSTORE_DEVICE_OP     0x27
+#define EFI_IFR_VERSION_OP             0x28
+#define EFI_IFR_END_OP                 0x29
+#define EFI_IFR_MATCH_OP               0x2A
+#define EFI_IFR_GET_OP                 0x2B
+#define EFI_IFR_SET_OP                 0x2C
+#define EFI_IFR_READ_OP                0x2D
+#define EFI_IFR_WRITE_OP               0x2E
+#define EFI_IFR_EQUAL_OP               0x2F
+#define EFI_IFR_NOT_EQUAL_OP           0x30
+#define EFI_IFR_GREATER_THAN_OP        0x31
+#define EFI_IFR_GREATER_EQUAL_OP       0x32
+#define EFI_IFR_LESS_THAN_OP           0x33
+#define EFI_IFR_LESS_EQUAL_OP          0x34
+#define EFI_IFR_BITWISE_AND_OP         0x35
+#define EFI_IFR_BITWISE_OR_OP          0x36
+#define EFI_IFR_BITWISE_NOT_OP         0x37
+#define EFI_IFR_SHIFT_LEFT_OP          0x38
+#define EFI_IFR_SHIFT_RIGHT_OP         0x39
+#define EFI_IFR_ADD_OP                 0x3A
+#define EFI_IFR_SUBTRACT_OP            0x3B
+#define EFI_IFR_MULTIPLY_OP            0x3C
+#define EFI_IFR_DIVIDE_OP              0x3D
+#define EFI_IFR_MODULO_OP              0x3E
+#define EFI_IFR_RULE_REF_OP            0x3F
+#define EFI_IFR_QUESTION_REF1_OP       0x40
+#define EFI_IFR_QUESTION_REF2_OP       0x41
+#define EFI_IFR_UINT8_OP               0x42
+#define EFI_IFR_UINT16_OP              0x43
+#define EFI_IFR_UINT32_OP              0x44
+#define EFI_IFR_UINT64_OP              0x45
+#define EFI_IFR_TRUE_OP                0x46
+#define EFI_IFR_FALSE_OP               0x47
+#define EFI_IFR_TO_UINT_OP             0x48
+#define EFI_IFR_TO_STRING_OP           0x49
+#define EFI_IFR_TO_BOOLEAN_OP          0x4A
+#define EFI_IFR_MID_OP                 0x4B
+#define EFI_IFR_FIND_OP                0x4C
+#define EFI_IFR_TOKEN_OP               0x4D
+#define EFI_IFR_STRING_REF1_OP         0x4E
+#define EFI_IFR_STRING_REF2_OP         0x4F
+#define EFI_IFR_CONDITIONAL_OP         0x50
+#define EFI_IFR_QUESTION_REF3_OP       0x51
+#define EFI_IFR_ZERO_OP                0x52
+#define EFI_IFR_ONE_OP                 0x53
+#define EFI_IFR_ONES_OP                0x54
+#define EFI_IFR_UNDEFINED_OP           0x55
+#define EFI_IFR_LENGTH_OP              0x56
+#define EFI_IFR_DUP_OP                 0x57
+#define EFI_IFR_THIS_OP                0x58
+#define EFI_IFR_SPAN_OP                0x59
+#define EFI_IFR_VALUE_OP               0x5A
+#define EFI_IFR_DEFAULT_OP             0x5B
+#define EFI_IFR_DEFAULTSTORE_OP        0x5C
+#define EFI_IFR_FORM_MAP_OP            0x5D
+#define EFI_IFR_CATENATE_OP            0x5E
+#define EFI_IFR_GUID_OP                0x5F
+#define EFI_IFR_SECURITY_OP            0x60
+#define EFI_IFR_MODAL_TAG_OP           0x61
+#define EFI_IFR_REFRESH_ID_OP          0x62
+#define EFI_IFR_WARNING_IF_OP          0x63
+#define EFI_IFR_MATCH2_OP              0x64
+
+//
+// Definitions of IFR Standard Headers
+// Section 27.3.8.2
+//
+
+typedef struct _EFI_IFR_OP_HEADER {
+  UINT8                    OpCode;
+  UINT8                    Length:7;
+  UINT8                    Scope:1;
+} EFI_IFR_OP_HEADER;
+
+typedef struct _EFI_IFR_STATEMENT_HEADER {
+  EFI_STRING_ID            Prompt;
+  EFI_STRING_ID            Help;
+} EFI_IFR_STATEMENT_HEADER;
+
+typedef struct _EFI_IFR_QUESTION_HEADER {
+  EFI_IFR_STATEMENT_HEADER Header;
+  EFI_QUESTION_ID          QuestionId;
+  EFI_VARSTORE_ID          VarStoreId;
+  union {
+    EFI_STRING_ID          VarName;
+    UINT16                 VarOffset;
+  }                        VarStoreInfo;
+  UINT8                    Flags;
+} EFI_IFR_QUESTION_HEADER;
+
+//
+// Flag values of EFI_IFR_QUESTION_HEADER
+//
+#define EFI_IFR_FLAG_READ_ONLY          0x01
+#define EFI_IFR_FLAG_CALLBACK           0x04
+#define EFI_IFR_FLAG_RESET_REQUIRED     0x10
+#define EFI_IFR_FLAG_RECONNECT_REQUIRED 0x40
+#define EFI_IFR_FLAG_OPTIONS_ONLY       0x80
+
+//
+// Definition for Opcode Reference
+// Section 27.3.8.3
+//
+typedef struct _EFI_IFR_DEFAULTSTORE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DefaultName;
+  UINT16                   DefaultId;
+} EFI_IFR_DEFAULTSTORE;
+
+//
+// Default Identifier of default store 
+//
+#define EFI_HII_DEFAULT_CLASS_STANDARD       0x0000
+#define EFI_HII_DEFAULT_CLASS_MANUFACTURING  0x0001
+#define EFI_HII_DEFAULT_CLASS_SAFE           0x0002
+#define EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN 0x4000
+#define EFI_HII_DEFAULT_CLASS_PLATFORM_END   0x7fff
+#define EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN 0x8000
+#define EFI_HII_DEFAULT_CLASS_HARDWARE_END   0xbfff
+#define EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN 0xc000
+#define EFI_HII_DEFAULT_CLASS_FIRMWARE_END   0xffff
+
+typedef struct _EFI_IFR_VARSTORE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 Guid;
+  EFI_VARSTORE_ID          VarStoreId;
+  UINT16                   Size;
+  UINT8                    Name[1];
+} EFI_IFR_VARSTORE;
+
+typedef struct _EFI_IFR_VARSTORE_EFI {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_VARSTORE_ID          VarStoreId;
+  EFI_GUID                 Guid;
+  UINT32                   Attributes;
+  UINT16                   Size;
+  UINT8                    Name[1];
+} EFI_IFR_VARSTORE_EFI;
+
+typedef struct _EFI_IFR_VARSTORE_NAME_VALUE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_VARSTORE_ID          VarStoreId;
+  EFI_GUID                 Guid;
+} EFI_IFR_VARSTORE_NAME_VALUE;
+
+typedef struct _EFI_IFR_FORM_SET {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 Guid;
+  EFI_STRING_ID            FormSetTitle;
+  EFI_STRING_ID            Help;
+  UINT8                    Flags;
+  // EFI_GUID              ClassGuid[];
+} EFI_IFR_FORM_SET;
+
+typedef struct _EFI_IFR_END {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_END;
+
+typedef struct _EFI_IFR_FORM {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   FormId;
+  EFI_STRING_ID            FormTitle;
+} EFI_IFR_FORM;
+
+typedef struct _EFI_IFR_IMAGE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IMAGE_ID             Id;
+} EFI_IFR_IMAGE;
+
+typedef struct _EFI_IFR_MODAL_TAG {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MODAL_TAG;
+
+typedef struct _EFI_IFR_LOCKED {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LOCKED;
+
+typedef struct _EFI_IFR_RULE {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    RuleId;
+} EFI_IFR_RULE;
+
+typedef struct _EFI_IFR_DEFAULT {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   DefaultId;
+  UINT8                    Type;
+  EFI_IFR_TYPE_VALUE       Value;
+} EFI_IFR_DEFAULT;
+
+typedef struct _EFI_IFR_DEFAULT_2 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   DefaultId;
+  UINT8                    Type;
+} EFI_IFR_DEFAULT_2;
+
+typedef struct _EFI_IFR_VALUE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_VALUE;
+
+typedef struct _EFI_IFR_SUBTITLE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_STATEMENT_HEADER Statement;
+  UINT8                    Flags;
+} EFI_IFR_SUBTITLE;
+
+#define EFI_IFR_FLAGS_HORIZONTAL       0x01
+
+typedef struct _EFI_IFR_CHECKBOX {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+} EFI_IFR_CHECKBOX;
+
+#define EFI_IFR_CHECKBOX_DEFAULT       0x01
+#define EFI_IFR_CHECKBOX_DEFAULT_MFG   0x02
+
+typedef struct _EFI_IFR_TEXT {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_STATEMENT_HEADER Statement;
+  EFI_STRING_ID            TextTwo;
+} EFI_IFR_TEXT;
+
+typedef struct _EFI_IFR_REF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+} EFI_IFR_REF;
+
+typedef struct _EFI_IFR_REF2 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+  EFI_QUESTION_ID          QuestionId;
+} EFI_IFR_REF2;
+
+typedef struct _EFI_IFR_REF3 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+  EFI_QUESTION_ID          QuestionId;
+  EFI_GUID                 FormSetId;
+} EFI_IFR_REF3;
+
+typedef struct _EFI_IFR_REF4 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_FORM_ID              FormId;
+  EFI_QUESTION_ID          QuestionId;
+  EFI_GUID                 FormSetId;
+  EFI_STRING_ID            DevicePath;
+} EFI_IFR_REF4;
+
+typedef struct _EFI_IFR_REF5 {
+  EFI_IFR_OP_HEADER Header;
+  EFI_IFR_QUESTION_HEADER Question;
+} EFI_IFR_REF5;
+
+typedef struct _EFI_IFR_RESET_BUTTON {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_STATEMENT_HEADER Statement;
+  EFI_DEFAULT_ID           DefaultId;
+} EFI_IFR_RESET_BUTTON;
+
+typedef struct _EFI_IFR_ACTION {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  EFI_STRING_ID            QuestionConfig;
+} EFI_IFR_ACTION;
+
+typedef struct _EFI_IFR_ACTION_1 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+} EFI_IFR_ACTION_1;
+
+typedef struct _EFI_IFR_DATE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+} EFI_IFR_DATE;
+
+//
+// Flags that describe the behavior of the question.
+//
+#define EFI_QF_DATE_YEAR_SUPPRESS      0x01
+#define EFI_QF_DATE_MONTH_SUPPRESS     0x02
+#define EFI_QF_DATE_DAY_SUPPRESS       0x04
+
+#define EFI_QF_DATE_STORAGE            0x30
+#define     QF_DATE_STORAGE_NORMAL     0x00
+#define     QF_DATE_STORAGE_TIME       0x10
+#define     QF_DATE_STORAGE_WAKEUP     0x20
+
+typedef union {
+  struct {
+    UINT8 MinValue;
+    UINT8 MaxValue;
+    UINT8 Step;
+  } u8;
+  struct {
+    UINT16 MinValue;
+    UINT16 MaxValue;
+    UINT16 Step;
+  } u16;
+  struct {
+    UINT32 MinValue;
+    UINT32 MaxValue;
+    UINT32 Step;
+  } u32;
+  struct {
+    UINT64 MinValue;
+    UINT64 MaxValue;
+    UINT64 Step;
+  } u64;
+} MINMAXSTEP_DATA;
+
+typedef struct _EFI_IFR_NUMERIC {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+  MINMAXSTEP_DATA          data;
+} EFI_IFR_NUMERIC;
+
+//
+// Flags related to the numeric question
+//
+#define EFI_IFR_NUMERIC_SIZE           0x03
+#define   EFI_IFR_NUMERIC_SIZE_1       0x00
+#define   EFI_IFR_NUMERIC_SIZE_2       0x01
+#define   EFI_IFR_NUMERIC_SIZE_4       0x02
+#define   EFI_IFR_NUMERIC_SIZE_8       0x03
+
+#define EFI_IFR_DISPLAY                0x30
+#define   EFI_IFR_DISPLAY_INT_DEC      0x00
+#define   EFI_IFR_DISPLAY_UINT_DEC     0x10
+#define   EFI_IFR_DISPLAY_UINT_HEX     0x20
+
+typedef struct _EFI_IFR_ONE_OF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+  MINMAXSTEP_DATA          data;
+} EFI_IFR_ONE_OF;
+
+typedef struct _EFI_IFR_STRING {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    MinSize;
+  UINT8                    MaxSize;
+  UINT8                    Flags;
+} EFI_IFR_STRING;
+
+#define EFI_IFR_STRING_MULTI_LINE      0x01
+
+typedef struct _EFI_IFR_PASSWORD {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT16                   MinSize;
+  UINT16                   MaxSize;
+} EFI_IFR_PASSWORD;
+
+typedef struct _EFI_IFR_ORDERED_LIST {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    MaxContainers;
+  UINT8                    Flags;
+} EFI_IFR_ORDERED_LIST;
+
+#define EFI_IFR_UNIQUE_SET             0x01
+#define EFI_IFR_NO_EMPTY_SET           0x02
+
+typedef struct _EFI_IFR_TIME {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_IFR_QUESTION_HEADER  Question;
+  UINT8                    Flags;
+} EFI_IFR_TIME;
+
+//
+// A bit-mask that determines which unique settings are active for this opcode.
+//
+#define QF_TIME_HOUR_SUPPRESS          0x01
+#define QF_TIME_MINUTE_SUPPRESS        0x02
+#define QF_TIME_SECOND_SUPPRESS        0x04
+
+#define QF_TIME_STORAGE                0x30
+#define   QF_TIME_STORAGE_NORMAL       0x00
+#define   QF_TIME_STORAGE_TIME         0x10
+#define   QF_TIME_STORAGE_WAKEUP       0x20
+
+typedef struct _EFI_IFR_DISABLE_IF {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_DISABLE_IF;
+
+typedef struct _EFI_IFR_SUPPRESS_IF {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SUPPRESS_IF;
+
+typedef struct _EFI_IFR_GRAY_OUT_IF {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_GRAY_OUT_IF;
+
+typedef struct _EFI_IFR_INCONSISTENT_IF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Error;
+} EFI_IFR_INCONSISTENT_IF;
+
+typedef struct _EFI_IFR_NO_SUBMIT_IF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Error;
+} EFI_IFR_NO_SUBMIT_IF;
+
+typedef struct _EFI_IFR_WARNING_IF {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Warning;
+  UINT8                    TimeOut;
+} EFI_IFR_WARNING_IF;
+
+typedef struct _EFI_IFR_REFRESH {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    RefreshInterval;
+} EFI_IFR_REFRESH;
+
+typedef struct _EFI_IFR_VARSTORE_DEVICE {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DevicePath;
+} EFI_IFR_VARSTORE_DEVICE;
+
+typedef struct _EFI_IFR_ONE_OF_OPTION {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            Option;
+  UINT8                    Flags;
+  UINT8                    Type;
+  EFI_IFR_TYPE_VALUE       Value;
+} EFI_IFR_ONE_OF_OPTION;
+
+//
+// Types of the option's value.
+//
+#define EFI_IFR_TYPE_NUM_SIZE_8        0x00
+#define EFI_IFR_TYPE_NUM_SIZE_16       0x01
+#define EFI_IFR_TYPE_NUM_SIZE_32       0x02
+#define EFI_IFR_TYPE_NUM_SIZE_64       0x03
+#define EFI_IFR_TYPE_BOOLEAN           0x04
+#define EFI_IFR_TYPE_TIME              0x05
+#define EFI_IFR_TYPE_DATE              0x06
+#define EFI_IFR_TYPE_STRING            0x07
+#define EFI_IFR_TYPE_OTHER             0x08
+#define EFI_IFR_TYPE_UNDEFINED         0x09
+#define EFI_IFR_TYPE_ACTION            0x0A
+#define EFI_IFR_TYPE_BUFFER            0x0B
+#define EFI_IFR_TYPE_REF               0x0C
+
+#define EFI_IFR_OPTION_DEFAULT         0x10
+#define EFI_IFR_OPTION_DEFAULT_MFG     0x20
+
+typedef struct _EFI_IFR_GUID {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 Guid;
+  //Optional Data Follows
+} EFI_IFR_GUID;
+
+typedef struct _EFI_IFR_REFRESH_ID {
+  EFI_IFR_OP_HEADER Header;
+  EFI_GUID          RefreshEventGroupId;
+} EFI_IFR_REFRESH_ID;
+
+typedef struct _EFI_IFR_DUP {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_DUP;
+
+typedef struct _EFI_IFR_EQ_ID_ID {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId1;
+  EFI_QUESTION_ID          QuestionId2;
+} EFI_IFR_EQ_ID_ID;
+
+typedef struct _EFI_IFR_EQ_ID_VAL {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId;
+  UINT16                   Value;
+} EFI_IFR_EQ_ID_VAL;
+
+typedef struct _EFI_IFR_EQ_ID_VAL_LIST {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId;
+  UINT16                   ListLength;
+  UINT16                   ValueList[1];
+} EFI_IFR_EQ_ID_VAL_LIST;
+
+typedef struct _EFI_IFR_UINT8 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8 Value;
+} EFI_IFR_UINT8;
+
+typedef struct _EFI_IFR_UINT16 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT16                   Value;
+} EFI_IFR_UINT16;
+
+typedef struct _EFI_IFR_UINT32 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT32                   Value;
+} EFI_IFR_UINT32;
+
+typedef struct _EFI_IFR_UINT64 {
+  EFI_IFR_OP_HEADER        Header;
+  UINT64 Value;
+} EFI_IFR_UINT64;
+
+typedef struct _EFI_IFR_QUESTION_REF1 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_QUESTION_ID          QuestionId;
+} EFI_IFR_QUESTION_REF1;
+
+typedef struct _EFI_IFR_QUESTION_REF2 {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_QUESTION_REF2;
+
+typedef struct _EFI_IFR_QUESTION_REF3 {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_QUESTION_REF3;
+
+typedef struct _EFI_IFR_QUESTION_REF3_2 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DevicePath;
+} EFI_IFR_QUESTION_REF3_2;
+
+typedef struct _EFI_IFR_QUESTION_REF3_3 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            DevicePath;
+  EFI_GUID                 Guid;
+} EFI_IFR_QUESTION_REF3_3;
+
+typedef struct _EFI_IFR_RULE_REF {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    RuleId;
+} EFI_IFR_RULE_REF;
+
+typedef struct _EFI_IFR_STRING_REF1 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_STRING_ID            StringId;
+} EFI_IFR_STRING_REF1;
+
+typedef struct _EFI_IFR_STRING_REF2 {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_STRING_REF2;
+
+typedef struct _EFI_IFR_THIS {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_THIS;
+
+typedef struct _EFI_IFR_TRUE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TRUE;
+
+typedef struct _EFI_IFR_FALSE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_FALSE;
+
+typedef struct _EFI_IFR_ONE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ONE;
+
+typedef struct _EFI_IFR_ONES {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ONES;
+
+typedef struct _EFI_IFR_ZERO {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ZERO;
+
+typedef struct _EFI_IFR_UNDEFINED {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_UNDEFINED;
+
+typedef struct _EFI_IFR_VERSION {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_VERSION;
+
+typedef struct _EFI_IFR_LENGTH {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LENGTH;
+
+typedef struct _EFI_IFR_NOT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_NOT;
+
+typedef struct _EFI_IFR_BITWISE_NOT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_BITWISE_NOT;
+
+typedef struct _EFI_IFR_TO_BOOLEAN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_BOOLEAN;
+
+///
+/// For EFI_IFR_TO_STRING, when converting from
+/// unsigned integers, these flags control the format:
+/// 0 = unsigned decimal.
+/// 1 = signed decimal.
+/// 2 = hexadecimal (lower-case alpha).
+/// 3 = hexadecimal (upper-case alpha).
+///@{
+#define EFI_IFR_STRING_UNSIGNED_DEC      0
+#define EFI_IFR_STRING_SIGNED_DEC        1
+#define EFI_IFR_STRING_LOWERCASE_HEX     2
+#define EFI_IFR_STRING_UPPERCASE_HEX     3
+///@}
+
+///
+/// When converting from a buffer, these flags control the format:
+/// 0 = ASCII.
+/// 8 = Unicode.
+///@{
+#define EFI_IFR_STRING_ASCII             0
+#define EFI_IFR_STRING_UNICODE           8
+///@}
+
+typedef struct _EFI_IFR_TO_STRING {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    Format;
+} EFI_IFR_TO_STRING;
+
+typedef struct _EFI_IFR_TO_UINT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_UINT;
+
+typedef struct _EFI_IFR_TO_UPPER {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_UPPER;
+
+typedef struct _EFI_IFR_TO_LOWER {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TO_LOWER;
+
+typedef struct _EFI_IFR_ADD {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_ADD;
+
+typedef struct _EFI_IFR_AND {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_AND;
+
+typedef struct _EFI_IFR_BITWISE_AND {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_BITWISE_AND;
+
+typedef struct _EFI_IFR_BITWISE_OR {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_BITWISE_OR;
+
+typedef struct _EFI_IFR_CATENATE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_CATENATE;
+
+typedef struct _EFI_IFR_DIVIDE {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_DIVIDE;
+
+typedef struct _EFI_IFR_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_EQUAL;
+
+typedef struct _EFI_IFR_GREATER_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_GREATER_EQUAL;
+
+typedef struct _EFI_IFR_GREATER_THAN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_GREATER_THAN;
+
+typedef struct _EFI_IFR_LESS_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LESS_EQUAL;
+
+typedef struct _EFI_IFR_LESS_THAN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_LESS_THAN;
+
+typedef struct _EFI_IFR_MATCH {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MATCH;
+
+typedef struct _EFI_IFR_MATCH2 {
+  EFI_IFR_OP_HEADER        Header;
+  EFI_GUID                 SyntaxType;
+} EFI_IFR_MATCH2;
+
+typedef struct _EFI_IFR_MULTIPLY {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MULTIPLY;
+
+typedef struct _EFI_IFR_MODULO {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MODULO;
+
+typedef struct _EFI_IFR_NOT_EQUAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_NOT_EQUAL;
+
+typedef struct _EFI_IFR_OR {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_OR;
+
+typedef struct _EFI_IFR_SHIFT_LEFT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SHIFT_LEFT;
+
+typedef struct _EFI_IFR_SHIFT_RIGHT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SHIFT_RIGHT;
+
+typedef struct _EFI_IFR_SUBTRACT {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_SUBTRACT;
+
+typedef struct _EFI_IFR_CONDITIONAL {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_CONDITIONAL;
+
+//
+// Flags governing the matching criteria of EFI_IFR_FIND
+//
+#define EFI_IFR_FF_CASE_SENSITIVE    0x00
+#define EFI_IFR_FF_CASE_INSENSITIVE  0x01
+
+typedef struct _EFI_IFR_FIND {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    Format;
+} EFI_IFR_FIND;
+
+typedef struct _EFI_IFR_MID {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_MID;
+
+typedef struct _EFI_IFR_TOKEN {
+  EFI_IFR_OP_HEADER        Header;
+} EFI_IFR_TOKEN;
+
+//
+// Flags specifying whether to find the first matching string
+// or the first non-matching string.
+//
+#define EFI_IFR_FLAGS_FIRST_MATCHING     0x00
+#define EFI_IFR_FLAGS_FIRST_NON_MATCHING 0x01
+
+typedef struct _EFI_IFR_SPAN {
+  EFI_IFR_OP_HEADER        Header;
+  UINT8                    Flags;
+} EFI_IFR_SPAN;
+
+typedef struct _EFI_IFR_SECURITY {
+  ///
+  /// Standard opcode header, where Header.Op = EFI_IFR_SECURITY_OP.
+  ///
+  EFI_IFR_OP_HEADER        Header;
+  ///
+  /// Security permission level.
+  ///
+  EFI_GUID                 Permissions;
+} EFI_IFR_SECURITY;
+
+typedef struct _EFI_IFR_FORM_MAP_METHOD {
+  ///
+  /// The string identifier which provides the human-readable name of 
+  /// the configuration method for this standards map form.
+  ///
+  EFI_STRING_ID            MethodTitle;
+  ///
+  /// Identifier which uniquely specifies the configuration methods 
+  /// associated with this standards map form.
+  ///
+  EFI_GUID                 MethodIdentifier;
+} EFI_IFR_FORM_MAP_METHOD;
+
+typedef struct _EFI_IFR_FORM_MAP {
+  ///
+  /// The sequence that defines the type of opcode as well as the length 
+  /// of the opcode being defined. Header.OpCode = EFI_IFR_FORM_MAP_OP. 
+  ///
+  EFI_IFR_OP_HEADER        Header;
+  ///
+  /// The unique identifier for this particular form.
+  ///
+  EFI_FORM_ID              FormId;
+  ///
+  /// One or more configuration method's name and unique identifier.
+  ///
+  // EFI_IFR_FORM_MAP_METHOD  Methods[];
+} EFI_IFR_FORM_MAP;
+
+typedef struct _EFI_IFR_SET {
+  ///
+  /// The sequence that defines the type of opcode as well as the length 
+  /// of the opcode being defined. Header.OpCode = EFI_IFR_SET_OP. 
+  ///
+  EFI_IFR_OP_HEADER  Header;
+  ///
+  /// Specifies the identifier of a previously declared variable store to 
+  /// use when storing the question's value. 
+  ///
+  EFI_VARSTORE_ID    VarStoreId;
+  union {
+    ///
+    /// A 16-bit Buffer Storage offset.
+    ///
+    EFI_STRING_ID    VarName;
+    ///
+    /// A Name Value or EFI Variable name (VarName).
+    ///
+    UINT16           VarOffset;
+  }                  VarStoreInfo;
+  ///
+  /// Specifies the type used for storage. 
+  ///
+  UINT8              VarStoreType;
+} EFI_IFR_SET;
+
+typedef struct _EFI_IFR_GET {
+  ///
+  /// The sequence that defines the type of opcode as well as the length 
+  /// of the opcode being defined. Header.OpCode = EFI_IFR_GET_OP. 
+  ///
+  EFI_IFR_OP_HEADER  Header;
+  ///
+  /// Specifies the identifier of a previously declared variable store to 
+  /// use when retrieving the value. 
+  ///
+  EFI_VARSTORE_ID    VarStoreId;
+  union {
+    ///
+    /// A 16-bit Buffer Storage offset.
+    ///
+    EFI_STRING_ID    VarName;
+    ///
+    /// A Name Value or EFI Variable name (VarName).
+    ///
+    UINT16           VarOffset;
+  }                  VarStoreInfo;
+  ///
+  /// Specifies the type used for storage. 
+  ///
+  UINT8              VarStoreType;
+} EFI_IFR_GET;
+
+typedef struct _EFI_IFR_READ {
+  EFI_IFR_OP_HEADER       Header;
+} EFI_IFR_READ;
+
+typedef struct _EFI_IFR_WRITE {
+  EFI_IFR_OP_HEADER      Header;
+} EFI_IFR_WRITE;
+
+typedef struct _EFI_IFR_MAP {
+  EFI_IFR_OP_HEADER      Header;
+} EFI_IFR_MAP;
+//
+// Definitions for Keyboard Package
+// Releated definitions are in Section of EFI_HII_DATABASE_PROTOCOL
+//
+
+///
+/// Each enumeration values maps a physical key on a keyboard.
+///
+typedef enum {    
+  EfiKeyLCtrl,
+  EfiKeyA0, 
+  EfiKeyLAlt,
+  EfiKeySpaceBar,
+  EfiKeyA2,
+  EfiKeyA3,
+  EfiKeyA4,
+  EfiKeyRCtrl,
+  EfiKeyLeftArrow,
+  EfiKeyDownArrow,
+  EfiKeyRightArrow,
+  EfiKeyZero,
+  EfiKeyPeriod,
+  EfiKeyEnter,
+  EfiKeyLShift,
+  EfiKeyB0,
+  EfiKeyB1,
+  EfiKeyB2,
+  EfiKeyB3,
+  EfiKeyB4,
+  EfiKeyB5,
+  EfiKeyB6,
+  EfiKeyB7,
+  EfiKeyB8,
+  EfiKeyB9,
+  EfiKeyB10,
+  EfiKeyRShift,
+  EfiKeyUpArrow,
+  EfiKeyOne,
+  EfiKeyTwo,
+  EfiKeyThree,
+  EfiKeyCapsLock,
+  EfiKeyC1,
+  EfiKeyC2,
+  EfiKeyC3,
+  EfiKeyC4,
+  EfiKeyC5,
+  EfiKeyC6,
+  EfiKeyC7,
+  EfiKeyC8,
+  EfiKeyC9,
+  EfiKeyC10,
+  EfiKeyC11,
+  EfiKeyC12,
+  EfiKeyFour,
+  EfiKeyFive,
+  EfiKeySix,
+  EfiKeyPlus,
+  EfiKeyTab,
+  EfiKeyD1,
+  EfiKeyD2,
+  EfiKeyD3,
+  EfiKeyD4,
+  EfiKeyD5,
+  EfiKeyD6,
+  EfiKeyD7,
+  EfiKeyD8,
+  EfiKeyD9,
+  EfiKeyD10,
+  EfiKeyD11,
+  EfiKeyD12,
+  EfiKeyD13,
+  EfiKeyDel,
+  EfiKeyEnd,
+  EfiKeyPgDn,
+  EfiKeySeven,
+  EfiKeyEight,
+  EfiKeyNine,
+  EfiKeyE0,
+  EfiKeyE1,
+  EfiKeyE2,
+  EfiKeyE3,
+  EfiKeyE4,
+  EfiKeyE5,
+  EfiKeyE6,
+  EfiKeyE7,
+  EfiKeyE8,
+  EfiKeyE9,
+  EfiKeyE10,
+  EfiKeyE11,
+  EfiKeyE12,
+  EfiKeyBackSpace,
+  EfiKeyIns,
+  EfiKeyHome,
+  EfiKeyPgUp,
+  EfiKeyNLck,
+  EfiKeySlash,
+  EfiKeyAsterisk,
+  EfiKeyMinus,
+  EfiKeyEsc,
+  EfiKeyF1,
+  EfiKeyF2,
+  EfiKeyF3,
+  EfiKeyF4,
+  EfiKeyF5,
+  EfiKeyF6,
+  EfiKeyF7,
+  EfiKeyF8,
+  EfiKeyF9,
+  EfiKeyF10,
+  EfiKeyF11,
+  EfiKeyF12,
+  EfiKeyPrint,
+  EfiKeySLck,
+  EfiKeyPause
+} EFI_KEY;
+
+typedef struct {
+  ///
+  /// Used to describe a physical key on a keyboard.
+  ///
+  EFI_KEY                 Key;
+  ///
+  /// Unicode character code for the Key.
+  ///
+  CHAR16                  Unicode;
+  ///
+  /// Unicode character code for the key with the shift key being held down.
+  ///
+  CHAR16                  ShiftedUnicode;
+  ///
+  /// Unicode character code for the key with the Alt-GR being held down.
+  ///
+  CHAR16                  AltGrUnicode;
+  ///
+  /// Unicode character code for the key with the Alt-GR and shift keys being held down.
+  ///
+  CHAR16                  ShiftedAltGrUnicode;
+  ///
+  /// Modifier keys are defined to allow for special functionality that is not necessarily 
+  /// accomplished by a printable character. Many of these modifier keys are flags to toggle 
+  /// certain state bits on and off inside of a keyboard driver.
+  ///
+  UINT16                  Modifier;
+  UINT16                  AffectedAttribute;
+} EFI_KEY_DESCRIPTOR;
+
+///
+/// A key which is affected by all the standard shift modifiers.  
+/// Most keys would be expected to have this bit active.
+///
+#define EFI_AFFECTED_BY_STANDARD_SHIFT       0x0001
+
+///
+/// This key is affected by the caps lock so that if a keyboard driver
+/// would need to disambiguate between a key which had a "1" defined
+/// versus an "a" character.  Having this bit turned on would tell
+/// the keyboard driver to use the appropriate shifted state or not.
+///
+#define EFI_AFFECTED_BY_CAPS_LOCK            0x0002
+
+///
+/// Similar to the case of CAPS lock, if this bit is active, the key
+/// is affected by the num lock being turned on.
+///
+#define EFI_AFFECTED_BY_NUM_LOCK             0x0004
+
+typedef struct {
+  UINT16                  LayoutLength;
+  EFI_GUID                Guid;
+  UINT32                  LayoutDescriptorStringOffset;
+  UINT8                   DescriptorCount;
+  // EFI_KEY_DESCRIPTOR    Descriptors[];
+} EFI_HII_KEYBOARD_LAYOUT;
+
+typedef struct {
+  EFI_HII_PACKAGE_HEADER  Header;
+  UINT16                  LayoutCount;
+  // EFI_HII_KEYBOARD_LAYOUT Layout[];
+} EFI_HII_KEYBOARD_PACKAGE_HDR;
+
+//
+// Modifier values
+//
+#define EFI_NULL_MODIFIER                0x0000
+#define EFI_LEFT_CONTROL_MODIFIER        0x0001
+#define EFI_RIGHT_CONTROL_MODIFIER       0x0002
+#define EFI_LEFT_ALT_MODIFIER            0x0003
+#define EFI_RIGHT_ALT_MODIFIER           0x0004
+#define EFI_ALT_GR_MODIFIER              0x0005
+#define EFI_INSERT_MODIFIER              0x0006
+#define EFI_DELETE_MODIFIER              0x0007
+#define EFI_PAGE_DOWN_MODIFIER           0x0008
+#define EFI_PAGE_UP_MODIFIER             0x0009
+#define EFI_HOME_MODIFIER                0x000A
+#define EFI_END_MODIFIER                 0x000B
+#define EFI_LEFT_SHIFT_MODIFIER          0x000C
+#define EFI_RIGHT_SHIFT_MODIFIER         0x000D
+#define EFI_CAPS_LOCK_MODIFIER           0x000E
+#define EFI_NUM_LOCK_MODIFIER            0x000F
+#define EFI_LEFT_ARROW_MODIFIER          0x0010
+#define EFI_RIGHT_ARROW_MODIFIER         0x0011
+#define EFI_DOWN_ARROW_MODIFIER          0x0012
+#define EFI_UP_ARROW_MODIFIER            0x0013
+#define EFI_NS_KEY_MODIFIER              0x0014
+#define EFI_NS_KEY_DEPENDENCY_MODIFIER   0x0015
+#define EFI_FUNCTION_KEY_ONE_MODIFIER    0x0016
+#define EFI_FUNCTION_KEY_TWO_MODIFIER    0x0017
+#define EFI_FUNCTION_KEY_THREE_MODIFIER  0x0018
+#define EFI_FUNCTION_KEY_FOUR_MODIFIER   0x0019
+#define EFI_FUNCTION_KEY_FIVE_MODIFIER   0x001A
+#define EFI_FUNCTION_KEY_SIX_MODIFIER    0x001B
+#define EFI_FUNCTION_KEY_SEVEN_MODIFIER  0x001C
+#define EFI_FUNCTION_KEY_EIGHT_MODIFIER  0x001D
+#define EFI_FUNCTION_KEY_NINE_MODIFIER   0x001E
+#define EFI_FUNCTION_KEY_TEN_MODIFIER    0x001F
+#define EFI_FUNCTION_KEY_ELEVEN_MODIFIER 0x0020
+#define EFI_FUNCTION_KEY_TWELVE_MODIFIER 0x0021
+
+//
+// Keys that have multiple control functions based on modifier
+// settings are handled in the keyboard driver implementation.
+// For instance, PRINT_KEY might have a modifier held down and
+// is still a nonprinting character, but might have an alternate
+// control function like SYSREQUEST
+//
+#define EFI_PRINT_MODIFIER               0x0022
+#define EFI_SYS_REQUEST_MODIFIER         0x0023
+#define EFI_SCROLL_LOCK_MODIFIER         0x0024
+#define EFI_PAUSE_MODIFIER               0x0025
+#define EFI_BREAK_MODIFIER               0x0026
+
+#define EFI_LEFT_LOGO_MODIFIER           0x0027
+#define EFI_RIGHT_LOGO_MODIFIER          0x0028
+#define EFI_MENU_MODIFIER                0x0029
+
+///
+/// Animation IFR opcode
+///
+typedef struct _EFI_IFR_ANIMATION {
+  ///
+  /// Standard opcode header, where Header.OpCode is 
+  /// EFI_IFR_ANIMATION_OP.
+  ///
+  EFI_IFR_OP_HEADER        Header;
+  ///
+  /// Animation identifier in the HII database.
+  ///
+  EFI_ANIMATION_ID         Id;
+} EFI_IFR_ANIMATION;
+
+///
+/// HII animation package header.
+///
+typedef struct _EFI_HII_ANIMATION_PACKAGE_HDR {
+  ///
+  /// Standard package header, where Header.Type = EFI_HII_PACKAGE_ANIMATIONS.
+  ///
+  EFI_HII_PACKAGE_HEADER  Header;
+  ///
+  /// Offset, relative to this header, of the animation information. If 
+  /// this is zero, then there are no animation sequences in the package.
+  ///
+  UINT32                  AnimationInfoOffset;
+} EFI_HII_ANIMATION_PACKAGE_HDR;
+
+///
+/// Animation information is encoded as a series of blocks,
+/// with each block prefixed by a single byte header EFI_HII_ANIMATION_BLOCK.
+///
+typedef struct _EFI_HII_ANIMATION_BLOCK {
+  UINT8  BlockType;
+  //UINT8  BlockBody[];
+} EFI_HII_ANIMATION_BLOCK;
+
+///
+/// Animation block types.
+///
+#define EFI_HII_AIBT_END                 0x00
+#define EFI_HII_AIBT_OVERLAY_IMAGES      0x10
+#define EFI_HII_AIBT_CLEAR_IMAGES        0x11
+#define EFI_HII_AIBT_RESTORE_SCRN        0x12
+#define EFI_HII_AIBT_OVERLAY_IMAGES_LOOP 0x18
+#define EFI_HII_AIBT_CLEAR_IMAGES_LOOP   0x19
+#define EFI_HII_AIBT_RESTORE_SCRN_LOOP   0x1A
+#define EFI_HII_AIBT_DUPLICATE           0x20
+#define EFI_HII_AIBT_SKIP2               0x21
+#define EFI_HII_AIBT_SKIP1               0x22
+#define EFI_HII_AIBT_EXT1                0x30
+#define EFI_HII_AIBT_EXT2                0x31
+#define EFI_HII_AIBT_EXT4                0x32
+
+///
+/// Extended block headers used for variable sized animation records
+/// which need an explicit length.
+///
+
+typedef struct _EFI_HII_AIBT_EXT1_BLOCK  {
+  ///
+  /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT1.
+  ///
+  EFI_HII_ANIMATION_BLOCK  Header;
+  ///
+  /// The block type.
+  ///
+  UINT8                    BlockType2;
+  ///
+  /// Size of the animation block, in bytes, including the animation block header.
+  ///
+  UINT8                    Length;
+} EFI_HII_AIBT_EXT1_BLOCK;
+
+typedef struct _EFI_HII_AIBT_EXT2_BLOCK {
+  ///
+  /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT2.
+  ///
+  EFI_HII_ANIMATION_BLOCK  Header;
+  ///
+  /// The block type
+  ///
+  UINT8                    BlockType2;
+  ///
+  /// Size of the animation block, in bytes, including the animation block header.
+  ///
+  UINT16                   Length;
+} EFI_HII_AIBT_EXT2_BLOCK;
+
+typedef struct _EFI_HII_AIBT_EXT4_BLOCK {
+  ///
+  /// Standard animation header, where Header.BlockType = EFI_HII_AIBT_EXT4.
+  ///
+  EFI_HII_ANIMATION_BLOCK  Header;
+  ///
+  /// The block type
+  ///
+  UINT8                    BlockType2;
+  ///
+  /// Size of the animation block, in bytes, including the animation block header.
+  ///
+  UINT32                   Length;
+} EFI_HII_AIBT_EXT4_BLOCK;
+
+typedef struct _EFI_HII_ANIMATION_CELL {
+  ///
+  /// The X offset from the upper left hand corner of the logical 
+  /// window to position the indexed image.
+  ///
+  UINT16                    OffsetX;
+  ///
+  /// The Y offset from the upper left hand corner of the logical 
+  /// window to position the indexed image.
+  ///
+  UINT16                    OffsetY;
+  ///
+  /// The image to display at the specified offset from the upper left 
+  /// hand corner of the logical window.
+  ///
+  EFI_IMAGE_ID              ImageId;
+  ///
+  /// The number of milliseconds to delay after displaying the indexed 
+  /// image and before continuing on to the next linked image.  If value 
+  /// is zero, no delay.
+  ///
+  UINT16                    Delay;
+} EFI_HII_ANIMATION_CELL;
+
+///
+/// An animation block to describe an animation sequence that does not cycle, and
+/// where one image is simply displayed over the previous image.
+///
+typedef struct _EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK {
+  ///
+  /// This is image that is to be reference by the image protocols, if the 
+  /// animation function is not supported or disabled. This image can 
+  /// be one particular image from the animation sequence (if any one 
+  /// of the animation frames has a complete image) or an alternate 
+  /// image that can be displayed alone. If the value is zero, no image 
+  /// is displayed.
+  ///
+  EFI_IMAGE_ID            DftImageId;
+  ///
+  /// The overall width of the set of images (logical window width).
+  ///
+  UINT16                  Width;
+  ///
+  /// The overall height of the set of images (logical window height).
+  ///
+  UINT16                  Height;
+  ///
+  /// The number of EFI_HII_ANIMATION_CELL contained in the 
+  /// animation sequence.
+  ///
+  UINT16                  CellCount;
+  ///
+  /// An array of CellCount animation cells.
+  ///
+  EFI_HII_ANIMATION_CELL  AnimationCell[1];
+} EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that does not cycle,
+/// and where the logical window is cleared to the specified color before 
+/// the next image is displayed.
+///
+typedef struct _EFI_HII_AIBT_CLEAR_IMAGES_BLOCK {
+  ///
+  /// This is image that is to be reference by the image protocols, if the 
+  /// animation function is not supported or disabled. This image can 
+  /// be one particular image from the animation sequence (if any one 
+  /// of the animation frames has a complete image) or an alternate 
+  /// image that can be displayed alone. If the value is zero, no image 
+  /// is displayed.
+  ///
+  EFI_IMAGE_ID       DftImageId;
+  ///
+  /// The overall width of the set of images (logical window width).
+  ///
+  UINT16             Width;
+  ///
+  /// The overall height of the set of images (logical window height).
+  ///
+  UINT16             Height;
+  ///
+  /// The number of EFI_HII_ANIMATION_CELL contained in the 
+  /// animation sequence.
+  ///
+  UINT16             CellCount;
+  ///
+  /// The color to clear the logical window to before displaying the 
+  /// indexed image.
+  ///
+  EFI_HII_RGB_PIXEL  BackgndColor;
+  ///
+  /// An array of CellCount animation cells.
+  ///
+  EFI_HII_ANIMATION_CELL AnimationCell[1];
+} EFI_HII_AIBT_CLEAR_IMAGES_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that does not cycle,
+/// and where the screen is restored to the original state before the next 
+/// image is displayed.
+///
+typedef struct _EFI_HII_AIBT_RESTORE_SCRN_BLOCK {
+  ///
+  /// This is image that is to be reference by the image protocols, if the 
+  /// animation function is not supported or disabled. This image can 
+  /// be one particular image from the animation sequence (if any one 
+  /// of the animation frames has a complete image) or an alternate 
+  /// image that can be displayed alone. If the value is zero, no image 
+  /// is displayed.
+  ///
+  EFI_IMAGE_ID            DftImageId;
+  ///
+  /// The overall width of the set of images (logical window width).
+  ///
+  UINT16                  Width;
+  ///
+  /// The overall height of the set of images (logical window height).
+  ///
+  UINT16                  Height;
+  ///
+  /// The number of EFI_HII_ANIMATION_CELL contained in the 
+  /// animation sequence.
+  ///
+  UINT16                  CellCount;
+  ///
+  /// An array of CellCount animation cells.
+  ///
+  EFI_HII_ANIMATION_CELL  AnimationCell[1];
+} EFI_HII_AIBT_RESTORE_SCRN_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that continuously cycles,
+/// and where one image is simply displayed over the previous image.
+///
+typedef EFI_HII_AIBT_OVERLAY_IMAGES_BLOCK  EFI_HII_AIBT_OVERLAY_IMAGES_LOOP_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that continuously cycles,
+/// and where the logical window is cleared to the specified color before 
+/// the next image is displayed.
+///
+typedef EFI_HII_AIBT_CLEAR_IMAGES_BLOCK    EFI_HII_AIBT_CLEAR_IMAGES_LOOP_BLOCK;
+
+///
+/// An animation block to describe an animation sequence that continuously cycles,
+/// and where the screen is restored to the original state before 
+/// the next image is displayed.
+///
+typedef EFI_HII_AIBT_RESTORE_SCRN_BLOCK    EFI_HII_AIBT_RESTORE_SCRN_LOOP_BLOCK;
+
+///
+/// Assigns a new character value to a previously defined animation sequence.
+///
+typedef struct _EFI_HII_AIBT_DUPLICATE_BLOCK {
+  ///
+  /// The previously defined animation ID with the exact same 
+  /// animation information.
+  ///
+  EFI_ANIMATION_ID  AnimationId;
+} EFI_HII_AIBT_DUPLICATE_BLOCK;
+
+///
+/// Skips animation IDs.
+///
+typedef struct _EFI_HII_AIBT_SKIP1_BLOCK {
+  ///
+  /// The unsigned 8-bit value to add to AnimationIdCurrent.
+  ///
+  UINT8  SkipCount;
+} EFI_HII_AIBT_SKIP1_BLOCK;
+
+///
+/// Skips animation IDs.
+///
+typedef struct _EFI_HII_AIBT_SKIP2_BLOCK {
+  ///
+  /// The unsigned 16-bit value to add to AnimationIdCurrent.
+  ///
+  UINT16  SkipCount;
+} EFI_HII_AIBT_SKIP2_BLOCK;
+
+#pragma pack()
+
+
+
+///
+/// References to string tokens must use this macro to enable scanning for
+/// token usages.
+///
+///
+/// STRING_TOKEN is not defined in UEFI specification. But it is placed 
+/// here for the easy access by C files and VFR source files.
+///
+#define STRING_TOKEN(t) t
+
+///
+/// IMAGE_TOKEN is not defined in UEFI specification. But it is placed
+/// here for the easy access by C files and VFR source files.
+///
+#define IMAGE_TOKEN(t) t
+
+#endif
diff --git a/sys/contrib/edk2/Include/Uefi/UefiMultiPhase.h b/sys/contrib/edk2/Include/Uefi/UefiMultiPhase.h
new file mode 100644
index 0000000000..30352587ad
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi/UefiMultiPhase.h
@@ -0,0 +1,231 @@
+/** @file
+  This includes some definitions introduced in UEFI that will be used in both PEI and DXE phases.
+
+Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_MULTIPHASE_H__
+#define __UEFI_MULTIPHASE_H__
+
+#include <Guid/WinCertificate.h>
+///
+/// Enumeration of memory types introduced in UEFI.
+///
+typedef enum {
+  ///
+  /// Not used.
+  ///
+  EfiReservedMemoryType,
+  ///
+  /// The code portions of a loaded application.
+  /// (Note that UEFI OS loaders are UEFI applications.)
+  ///
+  EfiLoaderCode,
+  ///
+  /// The data portions of a loaded application and the default data allocation
+  /// type used by an application to allocate pool memory.
+  ///
+  EfiLoaderData,
+  ///
+  /// The code portions of a loaded Boot Services Driver.
+  ///
+  EfiBootServicesCode,
+  ///
+  /// The data portions of a loaded Boot Serves Driver, and the default data
+  /// allocation type used by a Boot Services Driver to allocate pool memory.
+  ///
+  EfiBootServicesData,
+  ///
+  /// The code portions of a loaded Runtime Services Driver.
+  ///
+  EfiRuntimeServicesCode,
+  ///
+  /// The data portions of a loaded Runtime Services Driver and the default
+  /// data allocation type used by a Runtime Services Driver to allocate pool memory.
+  ///
+  EfiRuntimeServicesData,
+  ///
+  /// Free (unallocated) memory.
+  ///
+  EfiConventionalMemory,
+  ///
+  /// Memory in which errors have been detected.
+  ///
+  EfiUnusableMemory,
+  ///
+  /// Memory that holds the ACPI tables.
+  ///
+  EfiACPIReclaimMemory,
+  ///
+  /// Address space reserved for use by the firmware.
+  ///
+  EfiACPIMemoryNVS,
+  ///
+  /// Used by system firmware to request that a memory-mapped IO region
+  /// be mapped by the OS to a virtual address so it can be accessed by EFI runtime services.
+  ///
+  EfiMemoryMappedIO,
+  ///
+  /// System memory-mapped IO region that is used to translate memory
+  /// cycles to IO cycles by the processor.
+  ///
+  EfiMemoryMappedIOPortSpace,
+  ///
+  /// Address space reserved by the firmware for code that is part of the processor.
+  ///
+  EfiPalCode,
+  ///
+  /// A memory region that operates as EfiConventionalMemory, 
+  /// however it happens to also support byte-addressable non-volatility.
+  ///
+  EfiPersistentMemory,
+  EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+///
+/// Enumeration of reset types.
+///
+typedef enum {
+  ///
+  /// Used to induce a system-wide reset. This sets all circuitry within the
+  /// system to its initial state.  This type of reset is asynchronous to system
+  /// operation and operates withgout regard to cycle boundaries.  EfiColdReset
+  /// is tantamount to a system power cycle.
+  ///
+  EfiResetCold,
+  ///
+  /// Used to induce a system-wide initialization. The processors are set to their
+  /// initial state, and pending cycles are not corrupted.  If the system does
+  /// not support this reset type, then an EfiResetCold must be performed.
+  ///
+  EfiResetWarm,
+  ///
+  /// Used to induce an entry into a power state equivalent to the ACPI G2/S5 or G3
+  /// state.  If the system does not support this reset type, then when the system
+  /// is rebooted, it should exhibit the EfiResetCold attributes.
+  ///
+  EfiResetShutdown,
+  ///
+  /// Used to induce a system-wide reset. The exact type of the reset is defined by
+  /// the EFI_GUID that follows the Null-terminated Unicode string passed into
+  /// ResetData. If the platform does not recognize the EFI_GUID in ResetData the
+  /// platform must pick a supported reset type to perform. The platform may
+  /// optionally log the parameters from any non-normal reset that occurs.
+  ///
+  EfiResetPlatformSpecific
+} EFI_RESET_TYPE;
+
+///
+/// Data structure that precedes all of the standard EFI table types.
+///
+typedef struct {
+  ///
+  /// A 64-bit signature that identifies the type of table that follows.
+  /// Unique signatures have been generated for the EFI System Table,
+  /// the EFI Boot Services Table, and the EFI Runtime Services Table.
+  ///
+  UINT64  Signature;
+  ///
+  /// The revision of the EFI Specification to which this table
+  /// conforms. The upper 16 bits of this field contain the major
+  /// revision value, and the lower 16 bits contain the minor revision
+  /// value. The minor revision values are limited to the range of 00..99.
+  ///
+  UINT32  Revision;
+  ///
+  /// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
+  ///
+  UINT32  HeaderSize;
+  ///
+  /// The 32-bit CRC for the entire table. This value is computed by
+  /// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
+  ///
+  UINT32  CRC32;
+  ///
+  /// Reserved field that must be set to 0.
+  ///
+  UINT32  Reserved;
+} EFI_TABLE_HEADER;
+
+///
+/// Attributes of variable.
+///
+#define EFI_VARIABLE_NON_VOLATILE                            0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS                      0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS                          0x00000004
+///
+/// This attribute is identified by the mnemonic 'HR'
+/// elsewhere in this specification.
+///
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD                   0x00000008
+///
+/// Attributes of Authenticated Variable
+///
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS              0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS   0x00000020
+#define EFI_VARIABLE_APPEND_WRITE                            0x00000040
+
+
+///
+/// AuthInfo is a WIN_CERTIFICATE using the wCertificateType
+/// WIN_CERTIFICATE_UEFI_GUID and the CertType
+/// EFI_CERT_TYPE_RSA2048_SHA256_GUID. If the attribute specifies
+/// authenticated access, then the Data buffer should begin with an
+/// authentication descriptor prior to the data payload and DataSize
+/// should reflect the the data.and descriptor size. The caller
+/// shall digest the Monotonic Count value and the associated data
+/// for the variable update using the SHA-256 1-way hash algorithm.
+/// The ensuing the 32-byte digest will be signed using the private
+/// key associated w/ the public/private 2048-bit RSA key-pair. The
+/// WIN_CERTIFICATE shall be used to describe the signature of the
+/// Variable data *Data. In addition, the signature will also
+/// include the MonotonicCount value to guard against replay attacks.
+///
+typedef struct {
+  ///
+  /// Included in the signature of
+  /// AuthInfo.Used to ensure freshness/no
+  /// replay. Incremented during each
+  /// "Write" access.
+  ///
+  UINT64                      MonotonicCount;
+  ///
+  /// Provides the authorization for the variable
+  /// access. It is a signature across the
+  /// variable data and the  Monotonic Count
+  /// value. Caller uses Private key that is
+  /// associated with a public key that has been
+  /// provisioned via the key exchange.
+  ///
+  WIN_CERTIFICATE_UEFI_GUID   AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION;
+
+///
+/// When the attribute EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS is
+/// set, then the Data buffer shall begin with an instance of a complete (and serialized)
+/// EFI_VARIABLE_AUTHENTICATION_2 descriptor. The descriptor shall be followed by the new
+/// variable value and DataSize shall reflect the combined size of the descriptor and the new
+/// variable value. The authentication descriptor is not part of the variable data and is not
+/// returned by subsequent calls to GetVariable().
+///
+typedef struct {
+  ///
+  /// For the TimeStamp value, components Pad1, Nanosecond, TimeZone, Daylight and
+  /// Pad2 shall be set to 0. This means that the time shall always be expressed in GMT.
+  ///
+  EFI_TIME                    TimeStamp;
+  ///
+  /// Only a CertType of  EFI_CERT_TYPE_PKCS7_GUID is accepted.
+  ///
+  WIN_CERTIFICATE_UEFI_GUID   AuthInfo;
+ } EFI_VARIABLE_AUTHENTICATION_2;
+
+#endif
diff --git a/sys/contrib/edk2/Include/Uefi/UefiPxe.h b/sys/contrib/edk2/Include/Uefi/UefiPxe.h
new file mode 100644
index 0000000000..aad1d3577d
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi/UefiPxe.h
@@ -0,0 +1,1792 @@
+/** @file
+  This header file contains all of the PXE type definitions,
+  structure prototypes, global variables and constants that
+  are needed for porting PXE to EFI.
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that 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.
+
+  @par Revision Reference:
+  32/64-bit PXE specification:
+  alpha-4, 99-Dec-17.
+
+**/
+
+#ifndef __EFI_PXE_H__
+#define __EFI_PXE_H__
+
+#pragma pack(1)
+
+#define PXE_BUSTYPE(a, b, c, d) \
+    ( \
+      (((PXE_UINT32) (d) & 0xFF) << 24) | (((PXE_UINT32) (c) & 0xFF) << 16) | (((PXE_UINT32) (b) & 0xFF) << 8) | \
+        ((PXE_UINT32) (a) & 0xFF) \
+    )
+
+///
+/// UNDI ROM ID and devive ID signature.
+///
+#define PXE_BUSTYPE_PXE PXE_BUSTYPE ('!', 'P', 'X', 'E')
+
+///
+/// BUS ROM ID signatures.
+///
+#define PXE_BUSTYPE_PCI     PXE_BUSTYPE ('P', 'C', 'I', 'R')
+#define PXE_BUSTYPE_PC_CARD PXE_BUSTYPE ('P', 'C', 'C', 'R')
+#define PXE_BUSTYPE_USB     PXE_BUSTYPE ('U', 'S', 'B', 'R')
+#define PXE_BUSTYPE_1394    PXE_BUSTYPE ('1', '3', '9', '4')
+
+#define PXE_SWAP_UINT16(n)  ((((PXE_UINT16) (n) & 0x00FF) << 8) | (((PXE_UINT16) (n) & 0xFF00) >> 8))
+
+#define PXE_SWAP_UINT32(n) \
+  ((((PXE_UINT32)(n) & 0x000000FF) << 24) | \
+   (((PXE_UINT32)(n) & 0x0000FF00) << 8)  | \
+   (((PXE_UINT32)(n) & 0x00FF0000) >> 8)  | \
+   (((PXE_UINT32)(n) & 0xFF000000) >> 24))
+
+#define PXE_SWAP_UINT64(n) \
+  ((((PXE_UINT64)(n) & 0x00000000000000FFULL) << 56) | \
+   (((PXE_UINT64)(n) & 0x000000000000FF00ULL) << 40) | \
+   (((PXE_UINT64)(n) & 0x0000000000FF0000ULL) << 24) | \
+   (((PXE_UINT64)(n) & 0x00000000FF000000ULL) << 8)  | \
+   (((PXE_UINT64)(n) & 0x000000FF00000000ULL) >> 8)  | \
+   (((PXE_UINT64)(n) & 0x0000FF0000000000ULL) >> 24) | \
+   (((PXE_UINT64)(n) & 0x00FF000000000000ULL) >> 40) | \
+   (((PXE_UINT64)(n) & 0xFF00000000000000ULL) >> 56))
+
+
+#define PXE_CPBSIZE_NOT_USED  0               ///< zero
+#define PXE_DBSIZE_NOT_USED   0               ///< zero
+#define PXE_CPBADDR_NOT_USED  (PXE_UINT64) 0  ///< zero
+#define PXE_DBADDR_NOT_USED   (PXE_UINT64) 0  ///< zero
+#define PXE_CONST             CONST
+
+#define PXE_VOLATILE          volatile
+
+typedef VOID           PXE_VOID;
+typedef UINT8          PXE_UINT8;
+typedef UINT16         PXE_UINT16;
+typedef UINT32         PXE_UINT32;
+typedef UINTN          PXE_UINTN;
+
+///
+/// Typedef unsigned long PXE_UINT64.
+///
+typedef UINT64      PXE_UINT64;
+
+typedef PXE_UINT8 PXE_BOOL;
+#define PXE_FALSE 0            ///< zero
+#define PXE_TRUE  (!PXE_FALSE)
+
+typedef PXE_UINT16      PXE_OPCODE;
+
+///
+/// Return UNDI operational state.
+///
+#define PXE_OPCODE_GET_STATE  0x0000
+
+///
+/// Change UNDI operational state from Stopped to Started.
+///
+#define PXE_OPCODE_START  0x0001
+
+///
+/// Change UNDI operational state from Started to Stopped.
+///
+#define PXE_OPCODE_STOP 0x0002
+
+///
+/// Get UNDI initialization information.
+///
+#define PXE_OPCODE_GET_INIT_INFO  0x0003
+
+///
+/// Get NIC configuration information.
+///
+#define PXE_OPCODE_GET_CONFIG_INFO  0x0004
+
+///
+/// Changed UNDI operational state from Started to Initialized.
+///
+#define PXE_OPCODE_INITIALIZE 0x0005
+
+///
+/// Re-initialize the NIC H/W.
+///
+#define PXE_OPCODE_RESET  0x0006
+
+///
+/// Change the UNDI operational state from Initialized to Started.
+///
+#define PXE_OPCODE_SHUTDOWN 0x0007
+
+///
+/// Read & change state of external interrupt enables.
+///
+#define PXE_OPCODE_INTERRUPT_ENABLES  0x0008
+
+///
+/// Read & change state of packet receive filters.
+///
+#define PXE_OPCODE_RECEIVE_FILTERS  0x0009
+
+///
+/// Read & change station MAC address.
+///
+#define PXE_OPCODE_STATION_ADDRESS  0x000A
+
+///
+/// Read traffic statistics.
+///
+#define PXE_OPCODE_STATISTICS 0x000B
+
+///
+/// Convert multicast IP address to multicast MAC address.
+///
+#define PXE_OPCODE_MCAST_IP_TO_MAC  0x000C
+
+///
+/// Read or change non-volatile storage on the NIC.
+///
+#define PXE_OPCODE_NVDATA 0x000D
+
+///
+/// Get & clear interrupt status.
+///
+#define PXE_OPCODE_GET_STATUS 0x000E
+
+///
+/// Fill media header in packet for transmit.
+///
+#define PXE_OPCODE_FILL_HEADER  0x000F
+
+///
+/// Transmit packet(s).
+///
+#define PXE_OPCODE_TRANSMIT 0x0010
+
+///
+/// Receive packet.
+///
+#define PXE_OPCODE_RECEIVE  0x0011
+
+///
+/// Last valid PXE UNDI OpCode number.
+///
+#define PXE_OPCODE_LAST_VALID 0x0011
+
+typedef PXE_UINT16  PXE_OPFLAGS;
+
+#define PXE_OPFLAGS_NOT_USED  0x0000
+
+//
+// //////////////////////////////////////
+// UNDI Get State
+//
+// No OpFlags
+
+////////////////////////////////////////
+// UNDI Start
+//
+// No OpFlags
+
+////////////////////////////////////////
+// UNDI Stop
+//
+// No OpFlags
+
+////////////////////////////////////////
+// UNDI Get Init Info
+//
+// No Opflags
+
+////////////////////////////////////////
+// UNDI Get Config Info
+//
+// No Opflags
+
+///
+/// UNDI Initialize
+///
+#define PXE_OPFLAGS_INITIALIZE_CABLE_DETECT_MASK    0x0001
+#define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE         0x0000
+#define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE  0x0001
+
+///
+///
+/// UNDI Reset
+///
+#define PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS  0x0001
+#define PXE_OPFLAGS_RESET_DISABLE_FILTERS     0x0002
+
+///
+/// UNDI Shutdown.
+///
+/// No OpFlags.
+
+///
+/// UNDI Interrupt Enables.
+///
+///
+/// Select whether to enable or disable external interrupt signals.
+/// Setting both enable and disable will return PXE_STATCODE_INVALID_OPFLAGS.
+///
+#define PXE_OPFLAGS_INTERRUPT_OPMASK  0xC000
+#define PXE_OPFLAGS_INTERRUPT_ENABLE  0x8000
+#define PXE_OPFLAGS_INTERRUPT_DISABLE 0x4000
+#define PXE_OPFLAGS_INTERRUPT_READ    0x0000
+
+///
+/// Enable receive interrupts.  An external interrupt will be generated
+/// after a complete non-error packet has been received.
+///
+#define PXE_OPFLAGS_INTERRUPT_RECEIVE 0x0001
+
+///
+/// Enable transmit interrupts.  An external interrupt will be generated
+/// after a complete non-error packet has been transmitted.
+///
+#define PXE_OPFLAGS_INTERRUPT_TRANSMIT  0x0002
+
+///
+/// Enable command interrupts.  An external interrupt will be generated
+/// when command execution stops.
+///
+#define PXE_OPFLAGS_INTERRUPT_COMMAND 0x0004
+
+///
+/// Generate software interrupt.  Setting this bit generates an external
+/// interrupt, if it is supported by the hardware.
+///
+#define PXE_OPFLAGS_INTERRUPT_SOFTWARE  0x0008
+
+///
+/// UNDI Receive Filters.
+///
+///
+/// Select whether to enable or disable receive filters.
+/// Setting both enable and disable will return PXE_STATCODE_INVALID_OPCODE.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_OPMASK   0xC000
+#define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE   0x8000
+#define PXE_OPFLAGS_RECEIVE_FILTER_DISABLE  0x4000
+#define PXE_OPFLAGS_RECEIVE_FILTER_READ     0x0000
+
+///
+/// To reset the contents of the multicast MAC address filter list,
+/// set this OpFlag:
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST 0x2000
+
+///
+/// Enable unicast packet receiving.  Packets sent to the current station
+/// MAC address will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST  0x0001
+
+///
+/// Enable broadcast packet receiving.  Packets sent to the broadcast
+/// MAC address will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST  0x0002
+
+///
+/// Enable filtered multicast packet receiving.  Packets sent to any
+/// of the multicast MAC addresses in the multicast MAC address filter
+/// list will be received.  If the filter list is empty, no multicast
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004
+
+///
+/// Enable promiscuous packet receiving.  All packets will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008
+
+///
+/// Enable promiscuous multicast packet receiving.  All multicast
+/// packets will be received.
+///
+#define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010
+
+///
+/// UNDI Station Address.
+///
+#define PXE_OPFLAGS_STATION_ADDRESS_READ   0x0000
+#define PXE_OPFLAGS_STATION_ADDRESS_WRITE  0x0000
+#define PXE_OPFLAGS_STATION_ADDRESS_RESET  0x0001
+
+///
+/// UNDI Statistics.
+///
+#define PXE_OPFLAGS_STATISTICS_READ   0x0000
+#define PXE_OPFLAGS_STATISTICS_RESET  0x0001
+
+///
+/// UNDI MCast IP to MAC.
+///
+///
+/// Identify the type of IP address in the CPB.
+///
+#define PXE_OPFLAGS_MCAST_IP_TO_MAC_OPMASK  0x0003
+#define PXE_OPFLAGS_MCAST_IPV4_TO_MAC       0x0000
+#define PXE_OPFLAGS_MCAST_IPV6_TO_MAC       0x0001
+
+///
+/// UNDI NvData.
+///
+///
+/// Select the type of non-volatile data operation.
+///
+#define PXE_OPFLAGS_NVDATA_OPMASK 0x0001
+#define PXE_OPFLAGS_NVDATA_READ   0x0000
+#define PXE_OPFLAGS_NVDATA_WRITE  0x0001
+
+///
+/// UNDI Get Status.
+///
+///
+/// Return current interrupt status.  This will also clear any interrupts
+/// that are currently set.  This can be used in a polling routine.  The
+/// interrupt flags are still set and cleared even when the interrupts
+/// are disabled.
+///
+#define PXE_OPFLAGS_GET_INTERRUPT_STATUS  0x0001
+
+///
+/// Return list of transmitted buffers for recycling.  Transmit buffers
+/// must not be changed or unallocated until they have recycled.  After
+/// issuing a transmit command, wait for a transmit complete interrupt.
+/// When a transmit complete interrupt is received, read the transmitted
+/// buffers.  Do not plan on getting one buffer per interrupt.  Some
+/// NICs and UNDIs may transmit multiple buffers per interrupt.
+///
+#define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS 0x0002
+
+///
+/// Return current media status.
+///
+#define PXE_OPFLAGS_GET_MEDIA_STATUS    0x0004
+
+///
+/// UNDI Fill Header.
+///
+#define PXE_OPFLAGS_FILL_HEADER_OPMASK      0x0001
+#define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED  0x0001
+#define PXE_OPFLAGS_FILL_HEADER_WHOLE       0x0000
+
+///
+/// UNDI Transmit.
+///
+///
+/// S/W UNDI only.  Return after the packet has been transmitted.  A
+/// transmit complete interrupt will still be generated and the transmit
+/// buffer will have to be recycled.
+///
+#define PXE_OPFLAGS_SWUNDI_TRANSMIT_OPMASK  0x0001
+#define PXE_OPFLAGS_TRANSMIT_BLOCK          0x0001
+#define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK     0x0000
+
+#define PXE_OPFLAGS_TRANSMIT_OPMASK     0x0002
+#define PXE_OPFLAGS_TRANSMIT_FRAGMENTED 0x0002
+#define PXE_OPFLAGS_TRANSMIT_WHOLE      0x0000
+
+///
+/// UNDI Receive.
+///
+/// No OpFlags.
+///
+
+///
+/// PXE STATFLAGS.
+///
+typedef PXE_UINT16  PXE_STATFLAGS;
+
+#define PXE_STATFLAGS_INITIALIZE  0x0000
+
+///
+/// Common StatFlags that can be returned by all commands.
+///
+///
+/// The COMMAND_COMPLETE and COMMAND_FAILED status flags must be
+/// implemented by all UNDIs.  COMMAND_QUEUED is only needed by UNDIs
+/// that support command queuing.
+///
+#define PXE_STATFLAGS_STATUS_MASK       0xC000
+#define PXE_STATFLAGS_COMMAND_COMPLETE  0xC000
+#define PXE_STATFLAGS_COMMAND_FAILED    0x8000
+#define PXE_STATFLAGS_COMMAND_QUEUED    0x4000
+
+///
+/// UNDI Get State.
+///
+#define PXE_STATFLAGS_GET_STATE_MASK        0x0003
+#define PXE_STATFLAGS_GET_STATE_INITIALIZED 0x0002
+#define PXE_STATFLAGS_GET_STATE_STARTED     0x0001
+#define PXE_STATFLAGS_GET_STATE_STOPPED     0x0000
+
+///
+/// UNDI Start.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Get Init Info.
+///
+#define PXE_STATFLAGS_CABLE_DETECT_MASK           0x0001
+#define PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED  0x0000
+#define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED      0x0001
+
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK           0x0002
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED  0x0000
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED      0x0002
+
+///
+/// UNDI Initialize.
+///
+#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA  0x0001
+
+///
+/// UNDI Reset.
+///
+#define PXE_STATFLAGS_RESET_NO_MEDIA  0x0001
+
+///
+/// UNDI Shutdown.
+///
+/// No additional StatFlags.
+
+///
+/// UNDI Interrupt Enables.
+///
+///
+/// If set, receive interrupts are enabled.
+///
+#define PXE_STATFLAGS_INTERRUPT_RECEIVE 0x0001
+
+///
+/// If set, transmit interrupts are enabled.
+///
+#define PXE_STATFLAGS_INTERRUPT_TRANSMIT  0x0002
+
+///
+/// If set, command interrupts are enabled.
+///
+#define PXE_STATFLAGS_INTERRUPT_COMMAND 0x0004
+
+///
+/// UNDI Receive Filters.
+///
+
+///
+/// If set, unicast packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST  0x0001
+
+///
+/// If set, broadcast packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST  0x0002
+
+///
+/// If set, multicast packets that match up with the multicast address
+/// filter list will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004
+
+///
+/// If set, all packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008
+
+///
+/// If set, all multicast packets will be received.
+///
+#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010
+
+///
+/// UNDI Station Address.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Statistics.
+///
+/// No additional StatFlags.
+///
+
+///
+//// UNDI MCast IP to MAC.
+////
+//// No additional StatFlags.
+
+///
+/// UNDI NvData.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Get Status.
+///
+
+///
+/// Use to determine if an interrupt has occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK 0x000F
+#define PXE_STATFLAGS_GET_STATUS_NO_INTERRUPTS  0x0000
+
+///
+/// If set, at least one receive interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_RECEIVE  0x0001
+
+///
+/// If set, at least one transmit interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_TRANSMIT 0x0002
+
+///
+/// If set, at least one command interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_COMMAND  0x0004
+
+///
+/// If set, at least one software interrupt occurred.
+///
+#define PXE_STATFLAGS_GET_STATUS_SOFTWARE 0x0008
+
+///
+/// This flag is set if the transmitted buffer queue is empty.  This flag
+/// will be set if all transmitted buffer addresses get written into the DB.
+///
+#define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY  0x0010
+
+///
+/// This flag is set if no transmitted buffer addresses were written
+/// into the DB.  (This could be because DBsize was too small.)
+///
+#define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN  0x0020
+
+///
+/// This flag is set if there is no media detected.
+///
+#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA  0x0040
+
+///
+/// UNDI Fill Header.
+///
+/// No additional StatFlags.
+///
+
+///
+/// UNDI Transmit.
+///
+/// No additional StatFlags.
+
+///
+/// UNDI Receive
+///.
+
+///
+/// No additional StatFlags.
+///
+typedef PXE_UINT16  PXE_STATCODE;
+
+#define PXE_STATCODE_INITIALIZE 0x0000
+
+///
+/// Common StatCodes returned by all UNDI commands, UNDI protocol functions
+/// and BC protocol functions.
+///
+#define PXE_STATCODE_SUCCESS              0x0000
+
+#define PXE_STATCODE_INVALID_CDB          0x0001
+#define PXE_STATCODE_INVALID_CPB          0x0002
+#define PXE_STATCODE_BUSY                 0x0003
+#define PXE_STATCODE_QUEUE_FULL           0x0004
+#define PXE_STATCODE_ALREADY_STARTED      0x0005
+#define PXE_STATCODE_NOT_STARTED          0x0006
+#define PXE_STATCODE_NOT_SHUTDOWN         0x0007
+#define PXE_STATCODE_ALREADY_INITIALIZED  0x0008
+#define PXE_STATCODE_NOT_INITIALIZED      0x0009
+#define PXE_STATCODE_DEVICE_FAILURE       0x000A
+#define PXE_STATCODE_NVDATA_FAILURE       0x000B
+#define PXE_STATCODE_UNSUPPORTED          0x000C
+#define PXE_STATCODE_BUFFER_FULL          0x000D
+#define PXE_STATCODE_INVALID_PARAMETER    0x000E
+#define PXE_STATCODE_INVALID_UNDI         0x000F
+#define PXE_STATCODE_IPV4_NOT_SUPPORTED   0x0010
+#define PXE_STATCODE_IPV6_NOT_SUPPORTED   0x0011
+#define PXE_STATCODE_NOT_ENOUGH_MEMORY    0x0012
+#define PXE_STATCODE_NO_DATA              0x0013
+
+typedef PXE_UINT16  PXE_IFNUM;
+
+///
+/// This interface number must be passed to the S/W UNDI Start command.
+///
+#define PXE_IFNUM_START 0x0000
+
+///
+/// This interface number is returned by the S/W UNDI Get State and
+/// Start commands if information in the CDB, CPB or DB is invalid.
+///
+#define PXE_IFNUM_INVALID 0x0000
+
+typedef PXE_UINT16  PXE_CONTROL;
+
+///
+/// Setting this flag directs the UNDI to queue this command for later
+/// execution if the UNDI is busy and it supports command queuing.
+/// If queuing is not supported, a PXE_STATCODE_INVALID_CONTROL error
+/// is returned.  If the queue is full, a PXE_STATCODE_CDB_QUEUE_FULL
+/// error is returned.
+///
+#define PXE_CONTROL_QUEUE_IF_BUSY 0x0002
+
+///
+/// These two bit values are used to determine if there are more UNDI
+/// CDB structures following this one.  If the link bit is set, there
+/// must be a CDB structure following this one.  Execution will start
+/// on the next CDB structure as soon as this one completes successfully.
+/// If an error is generated by this command, execution will stop.
+///
+#define PXE_CONTROL_LINK              0x0001
+#define PXE_CONTROL_LAST_CDB_IN_LIST  0x0000
+
+typedef PXE_UINT8   PXE_FRAME_TYPE;
+
+#define PXE_FRAME_TYPE_NONE                     0x00
+#define PXE_FRAME_TYPE_UNICAST                  0x01
+#define PXE_FRAME_TYPE_BROADCAST                0x02
+#define PXE_FRAME_TYPE_FILTERED_MULTICAST       0x03
+#define PXE_FRAME_TYPE_PROMISCUOUS              0x04
+#define PXE_FRAME_TYPE_PROMISCUOUS_MULTICAST    0x05
+
+#define PXE_FRAME_TYPE_MULTICAST                PXE_FRAME_TYPE_FILTERED_MULTICAST
+
+typedef PXE_UINT32  PXE_IPV4;
+
+typedef PXE_UINT32  PXE_IPV6[4];
+#define PXE_MAC_LENGTH  32
+
+typedef PXE_UINT8   PXE_MAC_ADDR[PXE_MAC_LENGTH];
+
+typedef PXE_UINT8   PXE_IFTYPE;
+typedef UINT16      PXE_MEDIA_PROTOCOL;
+
+///
+/// This information is from the ARP section of RFC 1700.
+///
+///     1 Ethernet (10Mb)                                    [JBP]
+///     2 Experimental Ethernet (3Mb)                        [JBP]
+///     3 Amateur Radio AX.25                                [PXK]
+///     4 Proteon ProNET Token Ring                          [JBP]
+///     5 Chaos                                              [GXP]
+///     6 IEEE 802 Networks                                  [JBP]
+///     7 ARCNET                                             [JBP]
+///     8 Hyperchannel                                       [JBP]
+///     9 Lanstar                                             [TU]
+///    10 Autonet Short Address                             [MXB1]
+///    11 LocalTalk                                         [JKR1]
+///    12 LocalNet (IBM* PCNet or SYTEK* LocalNET)           [JXM]
+///    13 Ultra link                                        [RXD2]
+///    14 SMDS                                              [GXC1]
+///    15 Frame Relay                                        [AGM]
+///    16 Asynchronous Transmission Mode (ATM)              [JXB2]
+///    17 HDLC                                               [JBP]
+///    18 Fibre Channel                            [Yakov Rekhter]
+///    19 Asynchronous Transmission Mode (ATM)      [Mark Laubach]
+///    20 Serial Line                                        [JBP]
+///    21 Asynchronous Transmission Mode (ATM)              [MXB1]
+///
+/// * Other names and brands may be claimed as the property of others.
+///
+#define PXE_IFTYPE_ETHERNET       0x01
+#define PXE_IFTYPE_TOKENRING      0x04
+#define PXE_IFTYPE_FIBRE_CHANNEL  0x12
+
+typedef struct s_pxe_hw_undi {
+  PXE_UINT32  Signature;      ///< PXE_ROMID_SIGNATURE.
+  PXE_UINT8   Len;            ///< sizeof(PXE_HW_UNDI).
+  PXE_UINT8   Fudge;          ///< makes 8-bit cksum equal zero.
+  PXE_UINT8   Rev;            ///< PXE_ROMID_REV.
+  PXE_UINT8   IFcnt;          ///< physical connector count lower byte.
+  PXE_UINT8   MajorVer;       ///< PXE_ROMID_MAJORVER.
+  PXE_UINT8   MinorVer;       ///< PXE_ROMID_MINORVER.
+  PXE_UINT8   IFcntExt;       ///< physical connector count upper byte.
+  PXE_UINT8   reserved;       ///< zero, not used.
+  PXE_UINT32  Implementation; ///< implementation flags.
+  ///< reserved             ///< vendor use.
+  ///< UINT32 Status;       ///< status port.
+  ///< UINT32 Command;      ///< command port.
+  ///< UINT64 CDBaddr;      ///< CDB address port.
+  ///<
+} PXE_HW_UNDI;
+
+///
+/// Status port bit definitions.
+///
+
+///
+/// UNDI operation state.
+///
+#define PXE_HWSTAT_STATE_MASK   0xC0000000
+#define PXE_HWSTAT_BUSY         0xC0000000
+#define PXE_HWSTAT_INITIALIZED  0x80000000
+#define PXE_HWSTAT_STARTED      0x40000000
+#define PXE_HWSTAT_STOPPED      0x00000000
+
+///
+/// If set, last command failed.
+///
+#define PXE_HWSTAT_COMMAND_FAILED 0x20000000
+
+///
+/// If set, identifies enabled receive filters.
+///
+#define PXE_HWSTAT_PROMISCUOUS_MULTICAST_RX_ENABLED 0x00001000
+#define PXE_HWSTAT_PROMISCUOUS_RX_ENABLED           0x00000800
+#define PXE_HWSTAT_BROADCAST_RX_ENABLED             0x00000400
+#define PXE_HWSTAT_MULTICAST_RX_ENABLED             0x00000200
+#define PXE_HWSTAT_UNICAST_RX_ENABLED               0x00000100
+
+///
+/// If set, identifies enabled external interrupts.
+///
+#define PXE_HWSTAT_SOFTWARE_INT_ENABLED     0x00000080
+#define PXE_HWSTAT_TX_COMPLETE_INT_ENABLED  0x00000040
+#define PXE_HWSTAT_PACKET_RX_INT_ENABLED    0x00000020
+#define PXE_HWSTAT_CMD_COMPLETE_INT_ENABLED 0x00000010
+
+///
+/// If set, identifies pending interrupts.
+///
+#define PXE_HWSTAT_SOFTWARE_INT_PENDING     0x00000008
+#define PXE_HWSTAT_TX_COMPLETE_INT_PENDING  0x00000004
+#define PXE_HWSTAT_PACKET_RX_INT_PENDING    0x00000002
+#define PXE_HWSTAT_CMD_COMPLETE_INT_PENDING 0x00000001
+
+///
+/// Command port definitions.
+///
+
+///
+/// If set, CDB identified in CDBaddr port is given to UNDI.
+/// If not set, other bits in this word will be processed.
+///
+#define PXE_HWCMD_ISSUE_COMMAND   0x80000000
+#define PXE_HWCMD_INTS_AND_FILTS  0x00000000
+
+///
+/// Use these to enable/disable receive filters.
+///
+#define PXE_HWCMD_PROMISCUOUS_MULTICAST_RX_ENABLE 0x00001000
+#define PXE_HWCMD_PROMISCUOUS_RX_ENABLE           0x00000800
+#define PXE_HWCMD_BROADCAST_RX_ENABLE             0x00000400
+#define PXE_HWCMD_MULTICAST_RX_ENABLE             0x00000200
+#define PXE_HWCMD_UNICAST_RX_ENABLE               0x00000100
+
+///
+/// Use these to enable/disable external interrupts.
+///
+#define PXE_HWCMD_SOFTWARE_INT_ENABLE     0x00000080
+#define PXE_HWCMD_TX_COMPLETE_INT_ENABLE  0x00000040
+#define PXE_HWCMD_PACKET_RX_INT_ENABLE    0x00000020
+#define PXE_HWCMD_CMD_COMPLETE_INT_ENABLE 0x00000010
+
+///
+/// Use these to clear pending external interrupts.
+///
+#define PXE_HWCMD_CLEAR_SOFTWARE_INT      0x00000008
+#define PXE_HWCMD_CLEAR_TX_COMPLETE_INT   0x00000004
+#define PXE_HWCMD_CLEAR_PACKET_RX_INT     0x00000002
+#define PXE_HWCMD_CLEAR_CMD_COMPLETE_INT  0x00000001
+
+typedef struct s_pxe_sw_undi {
+  PXE_UINT32  Signature;      ///< PXE_ROMID_SIGNATURE.
+  PXE_UINT8   Len;            ///< sizeof(PXE_SW_UNDI).
+  PXE_UINT8   Fudge;          ///< makes 8-bit cksum zero.
+  PXE_UINT8   Rev;            ///< PXE_ROMID_REV.
+  PXE_UINT8   IFcnt;          ///< physical connector count lower byte.
+  PXE_UINT8   MajorVer;       ///< PXE_ROMID_MAJORVER.
+  PXE_UINT8   MinorVer;       ///< PXE_ROMID_MINORVER.
+  PXE_UINT8   IFcntExt;       ///< physical connector count upper byte.
+  PXE_UINT8   reserved1;      ///< zero, not used.
+  PXE_UINT32  Implementation; ///< Implementation flags.
+  PXE_UINT64  EntryPoint;     ///< API entry point.
+  PXE_UINT8   reserved2[3];   ///< zero, not used.
+  PXE_UINT8   BusCnt;         ///< number of bustypes supported.
+  PXE_UINT32  BusType[1];     ///< list of supported bustypes.
+} PXE_SW_UNDI;
+
+typedef union u_pxe_undi {
+  PXE_HW_UNDI hw;
+  PXE_SW_UNDI sw;
+} PXE_UNDI;
+
+///
+/// Signature of !PXE structure.
+///
+#define PXE_ROMID_SIGNATURE PXE_BUSTYPE ('!', 'P', 'X', 'E')
+
+///
+/// !PXE structure format revision
+///.
+#define PXE_ROMID_REV 0x02
+
+///
+/// UNDI command interface revision.  These are the values that get sent
+/// in option 94 (Client Network Interface Identifier) in the DHCP Discover
+/// and PXE Boot Server Request packets.
+///
+#define PXE_ROMID_MAJORVER    0x03
+#define PXE_ROMID_MINORVER    0x01
+
+///
+/// Implementation flags.
+///
+#define PXE_ROMID_IMP_HW_UNDI                             0x80000000
+#define PXE_ROMID_IMP_SW_VIRT_ADDR                        0x40000000
+#define PXE_ROMID_IMP_64BIT_DEVICE                        0x00010000
+#define PXE_ROMID_IMP_FRAG_SUPPORTED                      0x00008000
+#define PXE_ROMID_IMP_CMD_LINK_SUPPORTED                  0x00004000
+#define PXE_ROMID_IMP_CMD_QUEUE_SUPPORTED                 0x00002000
+#define PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED               0x00001000
+#define PXE_ROMID_IMP_NVDATA_SUPPORT_MASK                 0x00000C00
+#define PXE_ROMID_IMP_NVDATA_BULK_WRITABLE                0x00000C00
+#define PXE_ROMID_IMP_NVDATA_SPARSE_WRITABLE              0x00000800
+#define PXE_ROMID_IMP_NVDATA_READ_ONLY                    0x00000400
+#define PXE_ROMID_IMP_NVDATA_NOT_AVAILABLE                0x00000000
+#define PXE_ROMID_IMP_STATISTICS_SUPPORTED                0x00000200
+#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE               0x00000100
+#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED  0x00000080
+#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED            0x00000040
+#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED              0x00000020
+#define PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED     0x00000010
+#define PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED              0x00000008
+#define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED           0x00000004
+#define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED             0x00000002
+#define PXE_ROMID_IMP_CMD_COMPLETE_INT_SUPPORTED          0x00000001
+
+typedef struct s_pxe_cdb {
+  PXE_OPCODE    OpCode;
+  PXE_OPFLAGS   OpFlags;
+  PXE_UINT16    CPBsize;
+  PXE_UINT16    DBsize;
+  PXE_UINT64    CPBaddr;
+  PXE_UINT64    DBaddr;
+  PXE_STATCODE  StatCode;
+  PXE_STATFLAGS StatFlags;
+  PXE_UINT16    IFnum;
+  PXE_CONTROL   Control;
+} PXE_CDB;
+
+typedef union u_pxe_ip_addr {
+  PXE_IPV6  IPv6;
+  PXE_IPV4  IPv4;
+} PXE_IP_ADDR;
+
+typedef union pxe_device {
+  ///
+  /// PCI and PC Card NICs are both identified using bus, device
+  /// and function numbers.  For PC Card, this may require PC
+  /// Card services to be loaded in the BIOS or preboot
+  /// environment.
+  ///
+  struct {
+    ///
+    /// See S/W UNDI ROMID structure definition for PCI and
+    /// PCC BusType definitions.
+    ///
+    PXE_UINT32  BusType;
+
+    ///
+    /// Bus, device & function numbers that locate this device.
+    ///
+    PXE_UINT16  Bus;
+    PXE_UINT8   Device;
+    PXE_UINT8   Function;
+  }
+  PCI, PCC;
+
+} PXE_DEVICE;
+
+///
+/// cpb and db definitions
+///
+#define MAX_PCI_CONFIG_LEN    64  ///< # of dwords.
+#define MAX_EEPROM_LEN        128 ///< # of dwords.
+#define MAX_XMIT_BUFFERS      32  ///< recycling Q length for xmit_done.
+#define MAX_MCAST_ADDRESS_CNT 8
+
+typedef struct s_pxe_cpb_start_30 {
+  ///
+  /// PXE_VOID Delay(UINTN microseconds);
+  ///
+  /// UNDI will never request a delay smaller than 10 microseconds
+  /// and will always request delays in increments of 10 microseconds.
+  /// The Delay() CallBack routine must delay between n and n + 10
+  /// microseconds before returning control to the UNDI.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Delay;
+
+  ///
+  /// PXE_VOID Block(UINT32 enable);
+  ///
+  /// UNDI may need to block multi-threaded/multi-processor access to
+  /// critical code sections when programming or accessing the network
+  /// device.  To this end, a blocking service is needed by the UNDI.
+  /// When UNDI needs a block, it will call Block() passing a non-zero
+  /// value.  When UNDI no longer needs a block, it will call Block()
+  /// with a zero value.  When called, if the Block() is already enabled,
+  /// do not return control to the UNDI until the previous Block() is
+  /// disabled.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Block;
+
+  ///
+  /// PXE_VOID Virt2Phys(UINT64 virtual, UINT64 physical_ptr);
+  ///
+  /// UNDI will pass the virtual address of a buffer and the virtual
+  /// address of a 64-bit physical buffer.  Convert the virtual address
+  /// to a physical address and write the result to the physical address
+  /// buffer.  If virtual and physical addresses are the same, just
+  /// copy the virtual address to the physical address buffer.
+  ///
+  /// This field can be set to zero if virtual and physical addresses
+  /// are equal.
+  ///
+  UINT64  Virt2Phys;
+  ///
+  /// PXE_VOID Mem_IO(UINT8 read_write, UINT8 len, UINT64 port,
+  ///              UINT64 buf_addr);
+  ///
+  /// UNDI will read or write the device io space using this call back
+  /// function. It passes the number of bytes as the len parameter and it
+  /// will be either 1,2,4 or 8.
+  ///
+  /// This field can not be set to zero.
+  ///
+  UINT64  Mem_IO;
+} PXE_CPB_START_30;
+
+typedef struct s_pxe_cpb_start_31 {
+  ///
+  /// PXE_VOID Delay(UINT64 UnqId, UINTN microseconds);
+  ///
+  /// UNDI will never request a delay smaller than 10 microseconds
+  /// and will always request delays in increments of 10 microseconds.
+  /// The Delay() CallBack routine must delay between n and n + 10
+  /// microseconds before returning control to the UNDI.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Delay;
+
+  ///
+  /// PXE_VOID Block(UINT64 unq_id, UINT32 enable);
+  ///
+  /// UNDI may need to block multi-threaded/multi-processor access to
+  /// critical code sections when programming or accessing the network
+  /// device.  To this end, a blocking service is needed by the UNDI.
+  /// When UNDI needs a block, it will call Block() passing a non-zero
+  /// value.  When UNDI no longer needs a block, it will call Block()
+  /// with a zero value.  When called, if the Block() is already enabled,
+  /// do not return control to the UNDI until the previous Block() is
+  /// disabled.
+  ///
+  /// This field cannot be set to zero.
+  ///
+  UINT64  Block;
+
+  ///
+  /// PXE_VOID Virt2Phys(UINT64 UnqId, UINT64 virtual, UINT64 physical_ptr);
+  ///
+  /// UNDI will pass the virtual address of a buffer and the virtual
+  /// address of a 64-bit physical buffer.  Convert the virtual address
+  /// to a physical address and write the result to the physical address
+  /// buffer.  If virtual and physical addresses are the same, just
+  /// copy the virtual address to the physical address buffer.
+  ///
+  /// This field can be set to zero if virtual and physical addresses
+  /// are equal.
+  ///
+  UINT64  Virt2Phys;
+  ///
+  /// PXE_VOID Mem_IO(UINT64 UnqId, UINT8 read_write, UINT8 len, UINT64 port,
+  ///              UINT64 buf_addr);
+  ///
+  /// UNDI will read or write the device io space using this call back
+  /// function. It passes the number of bytes as the len parameter and it
+  /// will be either 1,2,4 or 8.
+  ///
+  /// This field can not be set to zero.
+  ///
+  UINT64  Mem_IO;
+  ///
+  /// PXE_VOID Map_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
+  ///                 UINT32 Direction, UINT64 mapped_addr);
+  ///
+  /// UNDI will pass the virtual address of a buffer, direction of the data
+  /// flow from/to the mapped buffer (the constants are defined below)
+  /// and a place holder (pointer) for the mapped address.
+  /// This call will Map the given address to a physical DMA address and write
+  /// the result to the mapped_addr pointer.  If there is no need to
+  /// map the given address to a lower address (i.e. the given address is
+  /// associated with a physical address that is already compatible to be
+  /// used with the DMA, it converts the given virtual address to it's
+  /// physical address and write that in the mapped address pointer.
+  ///
+  /// This field can be set to zero if there is no mapping service available.
+  ///
+  UINT64  Map_Mem;
+
+  ///
+  /// PXE_VOID UnMap_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
+  ///            UINT32 Direction, UINT64 mapped_addr);
+  ///
+  /// UNDI will pass the virtual and mapped addresses of a buffer.
+  /// This call will un map the given address.
+  ///
+  /// This field can be set to zero if there is no unmapping service available.
+  ///
+  UINT64  UnMap_Mem;
+
+  ///
+  /// PXE_VOID Sync_Mem(UINT64 unq_id, UINT64 virtual,
+  ///            UINT32 size, UINT32 Direction, UINT64 mapped_addr);
+  ///
+  /// UNDI will pass the virtual and mapped addresses of a buffer.
+  /// This call will synchronize the contents of both the virtual and mapped.
+  /// buffers for the given Direction.
+  ///
+  /// This field can be set to zero if there is no service available.
+  ///
+  UINT64  Sync_Mem;
+
+  ///
+  /// protocol driver can provide anything for this Unique_ID, UNDI remembers
+  /// that as just a 64bit value associated to the interface specified by
+  /// the ifnum and gives it back as a parameter to all the call-back routines
+  /// when calling for that interface!
+  ///
+  UINT64  Unique_ID;
+} PXE_CPB_START_31;
+
+#define TO_AND_FROM_DEVICE    0
+#define FROM_DEVICE           1
+#define TO_DEVICE             2
+
+#define PXE_DELAY_MILLISECOND 1000
+#define PXE_DELAY_SECOND      1000000
+#define PXE_IO_READ           0
+#define PXE_IO_WRITE          1
+#define PXE_MEM_READ          2
+#define PXE_MEM_WRITE         4
+
+typedef struct s_pxe_db_get_init_info {
+  ///
+  /// Minimum length of locked memory buffer that must be given to
+  /// the Initialize command. Giving UNDI more memory will generally
+  /// give better performance.
+  ///
+  /// If MemoryRequired is zero, the UNDI does not need and will not
+  /// use system memory to receive and transmit packets.
+  ///
+  PXE_UINT32  MemoryRequired;
+
+  ///
+  /// Maximum frame data length for Tx/Rx excluding the media header.
+  ///
+  PXE_UINT32  FrameDataLen;
+
+  ///
+  /// Supported link speeds are in units of mega bits.  Common ethernet
+  /// values are 10, 100 and 1000.  Unused LinkSpeeds[] entries are zero
+  /// filled.
+  ///
+  PXE_UINT32  LinkSpeeds[4];
+
+  ///
+  /// Number of non-volatile storage items.
+  ///
+  PXE_UINT32  NvCount;
+
+  ///
+  /// Width of non-volatile storage item in bytes.  0, 1, 2 or 4
+  ///
+  PXE_UINT16  NvWidth;
+
+  ///
+  /// Media header length.  This is the typical media header length for
+  /// this UNDI.  This information is needed when allocating receive
+  /// and transmit buffers.
+  ///
+  PXE_UINT16  MediaHeaderLen;
+
+  ///
+  /// Number of bytes in the NIC hardware (MAC) address.
+  ///
+  PXE_UINT16  HWaddrLen;
+
+  ///
+  /// Maximum number of multicast MAC addresses in the multicast
+  /// MAC address filter list.
+  ///
+  PXE_UINT16  MCastFilterCnt;
+
+  ///
+  /// Default number and size of transmit and receive buffers that will
+  /// be allocated by the UNDI.  If MemoryRequired is non-zero, this
+  /// allocation will come out of the memory buffer given to the Initialize
+  /// command.  If MemoryRequired is zero, this allocation will come out of
+  /// memory on the NIC.
+  ///
+  PXE_UINT16  TxBufCnt;
+  PXE_UINT16  TxBufSize;
+  PXE_UINT16  RxBufCnt;
+  PXE_UINT16  RxBufSize;
+
+  ///
+  /// Hardware interface types defined in the Assigned Numbers RFC
+  /// and used in DHCP and ARP packets.
+  /// See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros.
+  ///
+  PXE_UINT8   IFtype;
+
+  ///
+  /// Supported duplex.  See PXE_DUPLEX_xxxxx #defines below.
+  ///
+  PXE_UINT8   SupportedDuplexModes;
+
+  ///
+  /// Supported loopback options.  See PXE_LOOPBACK_xxxxx #defines below.
+  ///
+  PXE_UINT8   SupportedLoopBackModes;
+} PXE_DB_GET_INIT_INFO;
+
+#define PXE_MAX_TXRX_UNIT_ETHER           1500
+
+#define PXE_HWADDR_LEN_ETHER              0x0006
+#define PXE_MAC_HEADER_LEN_ETHER          0x000E
+
+#define PXE_DUPLEX_ENABLE_FULL_SUPPORTED  1
+#define PXE_DUPLEX_FORCE_FULL_SUPPORTED   2
+
+#define PXE_LOOPBACK_INTERNAL_SUPPORTED   1
+#define PXE_LOOPBACK_EXTERNAL_SUPPORTED   2
+
+typedef struct s_pxe_pci_config_info {
+  ///
+  /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union.
+  /// For PCI bus devices, this field is set to PXE_BUSTYPE_PCI.
+  ///
+  UINT32  BusType;
+
+  ///
+  /// This identifies the PCI network device that this UNDI interface.
+  /// is bound to.
+  ///
+  UINT16  Bus;
+  UINT8   Device;
+  UINT8   Function;
+
+  ///
+  /// This is a copy of the PCI configuration space for this
+  /// network device.
+  ///
+  union {
+    UINT8   Byte[256];
+    UINT16  Word[128];
+    UINT32  Dword[64];
+  } Config;
+} PXE_PCI_CONFIG_INFO;
+
+typedef struct s_pxe_pcc_config_info {
+  ///
+  /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union.
+  /// For PCC bus devices, this field is set to PXE_BUSTYPE_PCC.
+  ///
+  PXE_UINT32  BusType;
+
+  ///
+  /// This identifies the PCC network device that this UNDI interface
+  /// is bound to.
+  ///
+  PXE_UINT16  Bus;
+  PXE_UINT8   Device;
+  PXE_UINT8   Function;
+
+  ///
+  /// This is a copy of the PCC configuration space for this
+  /// network device.
+  ///
+  union {
+    PXE_UINT8   Byte[256];
+    PXE_UINT16  Word[128];
+    PXE_UINT32  Dword[64];
+  } Config;
+} PXE_PCC_CONFIG_INFO;
+
+typedef union u_pxe_db_get_config_info {
+  PXE_PCI_CONFIG_INFO   pci;
+  PXE_PCC_CONFIG_INFO   pcc;
+} PXE_DB_GET_CONFIG_INFO;
+
+typedef struct s_pxe_cpb_initialize {
+  ///
+  /// Address of first (lowest) byte of the memory buffer.  This buffer must
+  /// be in contiguous physical memory and cannot be swapped out.  The UNDI
+  /// will be using this for transmit and receive buffering.
+  ///
+  PXE_UINT64  MemoryAddr;
+
+  ///
+  /// MemoryLength must be greater than or equal to MemoryRequired
+  /// returned by the Get Init Info command.
+  ///
+  PXE_UINT32  MemoryLength;
+
+  ///
+  /// Desired link speed in Mbit/sec.  Common ethernet values are 10, 100
+  /// and 1000.  Setting a value of zero will auto-detect and/or use the
+  /// default link speed (operation depends on UNDI/NIC functionality).
+  ///
+  PXE_UINT32  LinkSpeed;
+
+  ///
+  /// Suggested number and size of receive and transmit buffers to
+  /// allocate.  If MemoryAddr and MemoryLength are non-zero, this
+  /// allocation comes out of the supplied memory buffer.  If MemoryAddr
+  /// and MemoryLength are zero, this allocation comes out of memory
+  /// on the NIC.
+  ///
+  /// If these fields are set to zero, the UNDI will allocate buffer
+  /// counts and sizes as it sees fit.
+  ///
+  PXE_UINT16  TxBufCnt;
+  PXE_UINT16  TxBufSize;
+  PXE_UINT16  RxBufCnt;
+  PXE_UINT16  RxBufSize;
+
+  ///
+  /// The following configuration parameters are optional and must be zero
+  /// to use the default values.
+  ///
+  PXE_UINT8   DuplexMode;
+
+  PXE_UINT8   LoopBackMode;
+} PXE_CPB_INITIALIZE;
+
+#define PXE_DUPLEX_DEFAULT      0x00
+#define PXE_FORCE_FULL_DUPLEX   0x01
+#define PXE_ENABLE_FULL_DUPLEX  0x02
+#define PXE_FORCE_HALF_DUPLEX   0x04
+#define PXE_DISABLE_FULL_DUPLEX 0x08
+
+#define LOOPBACK_NORMAL         0
+#define LOOPBACK_INTERNAL       1
+#define LOOPBACK_EXTERNAL       2
+
+typedef struct s_pxe_db_initialize {
+  ///
+  /// Actual amount of memory used from the supplied memory buffer.  This
+  /// may be less that the amount of memory suppllied and may be zero if
+  /// the UNDI and network device do not use external memory buffers.
+  ///
+  /// Memory used by the UNDI and network device is allocated from the
+  /// lowest memory buffer address.
+  ///
+  PXE_UINT32  MemoryUsed;
+
+  ///
+  /// Actual number and size of receive and transmit buffers that were
+  /// allocated.
+  ///
+  PXE_UINT16  TxBufCnt;
+  PXE_UINT16  TxBufSize;
+  PXE_UINT16  RxBufCnt;
+  PXE_UINT16  RxBufSize;
+} PXE_DB_INITIALIZE;
+
+typedef struct s_pxe_cpb_receive_filters {
+  ///
+  /// List of multicast MAC addresses.  This list, if present, will
+  /// replace the existing multicast MAC address filter list.
+  ///
+  PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];
+} PXE_CPB_RECEIVE_FILTERS;
+
+typedef struct s_pxe_db_receive_filters {
+  ///
+  /// Filtered multicast MAC address list.
+  ///
+  PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];
+} PXE_DB_RECEIVE_FILTERS;
+
+typedef struct s_pxe_cpb_station_address {
+  ///
+  /// If supplied and supported, the current station MAC address
+  /// will be changed.
+  ///
+  PXE_MAC_ADDR  StationAddr;
+} PXE_CPB_STATION_ADDRESS;
+
+typedef struct s_pxe_dpb_station_address {
+  ///
+  /// Current station MAC address.
+  ///
+  PXE_MAC_ADDR  StationAddr;
+
+  ///
+  /// Station broadcast MAC address.
+  ///
+  PXE_MAC_ADDR  BroadcastAddr;
+
+  ///
+  /// Permanent station MAC address.
+  ///
+  PXE_MAC_ADDR  PermanentAddr;
+} PXE_DB_STATION_ADDRESS;
+
+typedef struct s_pxe_db_statistics {
+  ///
+  /// Bit field identifying what statistic data is collected by the
+  /// UNDI/NIC.
+  /// If bit 0x00 is set, Data[0x00] is collected.
+  /// If bit 0x01 is set, Data[0x01] is collected.
+  /// If bit 0x20 is set, Data[0x20] is collected.
+  /// If bit 0x21 is set, Data[0x21] is collected.
+  /// Etc.
+  ///
+  PXE_UINT64  Supported;
+
+  ///
+  /// Statistic data.
+  ///
+  PXE_UINT64  Data[64];
+} PXE_DB_STATISTICS;
+
+///
+/// Total number of frames received.  Includes frames with errors and
+/// dropped frames.
+///
+#define PXE_STATISTICS_RX_TOTAL_FRAMES  0x00
+
+///
+/// Number of valid frames received and copied into receive buffers.
+///
+#define PXE_STATISTICS_RX_GOOD_FRAMES 0x01
+
+///
+/// Number of frames below the minimum length for the media.
+/// This would be <64 for ethernet.
+///
+#define PXE_STATISTICS_RX_UNDERSIZE_FRAMES  0x02
+
+///
+/// Number of frames longer than the maxminum length for the
+/// media.  This would be >1500 for ethernet.
+///
+#define PXE_STATISTICS_RX_OVERSIZE_FRAMES 0x03
+
+///
+/// Valid frames that were dropped because receive buffers were full.
+///
+#define PXE_STATISTICS_RX_DROPPED_FRAMES  0x04
+
+///
+/// Number of valid unicast frames received and not dropped.
+///
+#define PXE_STATISTICS_RX_UNICAST_FRAMES  0x05
+
+///
+/// Number of valid broadcast frames received and not dropped.
+///
+#define PXE_STATISTICS_RX_BROADCAST_FRAMES  0x06
+
+///
+/// Number of valid mutlicast frames received and not dropped.
+///
+#define PXE_STATISTICS_RX_MULTICAST_FRAMES  0x07
+
+///
+/// Number of frames w/ CRC or alignment errors.
+///
+#define PXE_STATISTICS_RX_CRC_ERROR_FRAMES  0x08
+
+///
+/// Total number of bytes received.  Includes frames with errors
+/// and dropped frames.
+///
+#define PXE_STATISTICS_RX_TOTAL_BYTES 0x09
+
+///
+/// Transmit statistics.
+///
+#define PXE_STATISTICS_TX_TOTAL_FRAMES      0x0A
+#define PXE_STATISTICS_TX_GOOD_FRAMES       0x0B
+#define PXE_STATISTICS_TX_UNDERSIZE_FRAMES  0x0C
+#define PXE_STATISTICS_TX_OVERSIZE_FRAMES   0x0D
+#define PXE_STATISTICS_TX_DROPPED_FRAMES    0x0E
+#define PXE_STATISTICS_TX_UNICAST_FRAMES    0x0F
+#define PXE_STATISTICS_TX_BROADCAST_FRAMES  0x10
+#define PXE_STATISTICS_TX_MULTICAST_FRAMES  0x11
+#define PXE_STATISTICS_TX_CRC_ERROR_FRAMES  0x12
+#define PXE_STATISTICS_TX_TOTAL_BYTES       0x13
+
+///
+/// Number of collisions detection on this subnet.
+///
+#define PXE_STATISTICS_COLLISIONS 0x14
+
+///
+/// Number of frames destined for unsupported protocol.
+///
+#define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15
+
+///
+/// Number of valid frames received that were duplicated.
+///
+#define PXE_STATISTICS_RX_DUPLICATED_FRAMES 0x16
+
+///
+/// Number of encrypted frames received that failed to decrypt.
+///
+#define PXE_STATISTICS_RX_DECRYPT_ERROR_FRAMES 0x17
+
+///
+/// Number of frames that failed to transmit after exceeding the retry limit.
+///
+#define PXE_STATISTICS_TX_ERROR_FRAMES 0x18
+
+///
+/// Number of frames transmitted successfully after more than one attempt.
+///
+#define PXE_STATISTICS_TX_RETRY_FRAMES 0x19
+
+typedef struct s_pxe_cpb_mcast_ip_to_mac {
+  ///
+  /// Multicast IP address to be converted to multicast MAC address.
+  ///
+  PXE_IP_ADDR IP;
+} PXE_CPB_MCAST_IP_TO_MAC;
+
+typedef struct s_pxe_db_mcast_ip_to_mac {
+  ///
+  /// Multicast MAC address.
+  ///
+  PXE_MAC_ADDR  MAC;
+} PXE_DB_MCAST_IP_TO_MAC;
+
+typedef struct s_pxe_cpb_nvdata_sparse {
+  ///
+  /// NvData item list.  Only items in this list will be updated.
+  ///
+  struct {
+    ///
+    ///  Non-volatile storage address to be changed.
+    ///
+    PXE_UINT32  Addr;
+
+    ///
+    /// Data item to write into above storage address.
+    ///
+    union {
+      PXE_UINT8   Byte;
+      PXE_UINT16  Word;
+      PXE_UINT32  Dword;
+    } Data;
+  } Item[MAX_EEPROM_LEN];
+} PXE_CPB_NVDATA_SPARSE;
+
+///
+/// When using bulk update, the size of the CPB structure must be
+/// the same size as the non-volatile NIC storage.
+///
+typedef union u_pxe_cpb_nvdata_bulk {
+  ///
+  /// Array of byte-wide data items.
+  ///
+  PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];
+
+  ///
+  /// Array of word-wide data items.
+  ///
+  PXE_UINT16  Word[MAX_EEPROM_LEN << 1];
+
+  ///
+  /// Array of dword-wide data items.
+  ///
+  PXE_UINT32  Dword[MAX_EEPROM_LEN];
+} PXE_CPB_NVDATA_BULK;
+
+typedef struct s_pxe_db_nvdata {
+  ///
+  /// Arrays of data items from non-volatile storage.
+  ///
+  union {
+    ///
+    /// Array of byte-wide data items.
+    ///
+    PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];
+
+    ///
+    /// Array of word-wide data items.
+    ///
+    PXE_UINT16  Word[MAX_EEPROM_LEN << 1];
+
+    ///
+    /// Array of dword-wide data items.
+    ///
+    PXE_UINT32  Dword[MAX_EEPROM_LEN];
+  } Data;
+} PXE_DB_NVDATA;
+
+typedef struct s_pxe_db_get_status {
+  ///
+  /// Length of next receive frame (header + data).  If this is zero,
+  /// there is no next receive frame available.
+  ///
+  PXE_UINT32  RxFrameLen;
+
+  ///
+  /// Reserved, set to zero.
+  ///
+  PXE_UINT32  reserved;
+
+  ///
+  ///  Addresses of transmitted buffers that need to be recycled.
+  ///
+  PXE_UINT64  TxBuffer[MAX_XMIT_BUFFERS];
+} PXE_DB_GET_STATUS;
+
+typedef struct s_pxe_cpb_fill_header {
+  ///
+  /// Source and destination MAC addresses.  These will be copied into
+  /// the media header without doing byte swapping.
+  ///
+  PXE_MAC_ADDR  SrcAddr;
+  PXE_MAC_ADDR  DestAddr;
+
+  ///
+  /// Address of first byte of media header.  The first byte of packet data
+  /// follows the last byte of the media header.
+  ///
+  PXE_UINT64        MediaHeader;
+
+  ///
+  /// Length of packet data in bytes (not including the media header).
+  ///
+  PXE_UINT32        PacketLen;
+
+  ///
+  /// Protocol type.  This will be copied into the media header without
+  /// doing byte swapping.  Protocol type numbers can be obtained from
+  /// the Assigned Numbers RFC 1700.
+  ///
+  PXE_UINT16        Protocol;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16        MediaHeaderLen;
+} PXE_CPB_FILL_HEADER;
+
+#define PXE_PROTOCOL_ETHERNET_IP  0x0800
+#define PXE_PROTOCOL_ETHERNET_ARP 0x0806
+#define MAX_XMIT_FRAGMENTS        16
+
+typedef struct s_pxe_cpb_fill_header_fragmented {
+  ///
+  /// Source and destination MAC addresses.  These will be copied into
+  /// the media header without doing byte swapping.
+  ///
+  PXE_MAC_ADDR        SrcAddr;
+  PXE_MAC_ADDR        DestAddr;
+
+  ///
+  /// Length of packet data in bytes (not including the media header).
+  ///
+  PXE_UINT32          PacketLen;
+
+  ///
+  /// Protocol type.  This will be copied into the media header without
+  /// doing byte swapping.  Protocol type numbers can be obtained from
+  /// the Assigned Numbers RFC 1700.
+  ///
+  PXE_MEDIA_PROTOCOL  Protocol;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16          MediaHeaderLen;
+
+  ///
+  /// Number of packet fragment descriptors.
+  ///
+  PXE_UINT16          FragCnt;
+
+  ///
+  /// Reserved, must be set to zero.
+  ///
+  PXE_UINT16          reserved;
+
+  ///
+  /// Array of packet fragment descriptors.  The first byte of the media
+  /// header is the first byte of the first fragment.
+  ///
+  struct {
+    ///
+    /// Address of this packet fragment.
+    ///
+    PXE_UINT64  FragAddr;
+
+    ///
+    /// Length of this packet fragment.
+    ///
+    PXE_UINT32  FragLen;
+
+    ///
+    /// Reserved, must be set to zero.
+    ///
+    PXE_UINT32  reserved;
+  } FragDesc[MAX_XMIT_FRAGMENTS];
+}
+PXE_CPB_FILL_HEADER_FRAGMENTED;
+
+typedef struct s_pxe_cpb_transmit {
+  ///
+  /// Address of first byte of frame buffer.  This is also the first byte
+  /// of the media header.
+  ///
+  PXE_UINT64  FrameAddr;
+
+  ///
+  /// Length of the data portion of the frame buffer in bytes.  Do not
+  /// include the length of the media header.
+  ///
+  PXE_UINT32  DataLen;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16  MediaheaderLen;
+
+  ///
+  /// Reserved, must be zero.
+  ///
+  PXE_UINT16  reserved;
+} PXE_CPB_TRANSMIT;
+
+typedef struct s_pxe_cpb_transmit_fragments {
+  ///
+  /// Length of packet data in bytes (not including the media header).
+  ///
+  PXE_UINT32  FrameLen;
+
+  ///
+  /// Length of the media header in bytes.
+  ///
+  PXE_UINT16  MediaheaderLen;
+
+  ///
+  /// Number of packet fragment descriptors.
+  ///
+  PXE_UINT16  FragCnt;
+
+  ///
+  /// Array of frame fragment descriptors.  The first byte of the first
+  /// fragment is also the first byte of the media header.
+  ///
+  struct {
+    ///
+    /// Address of this frame fragment.
+    ///
+    PXE_UINT64  FragAddr;
+
+    ///
+    /// Length of this frame fragment.
+    ///
+    PXE_UINT32  FragLen;
+
+    ///
+    /// Reserved, must be set to zero.
+    ///
+    PXE_UINT32  reserved;
+  } FragDesc[MAX_XMIT_FRAGMENTS];
+}
+PXE_CPB_TRANSMIT_FRAGMENTS;
+
+typedef struct s_pxe_cpb_receive {
+  ///
+  /// Address of first byte of receive buffer.  This is also the first byte
+  /// of the frame header.
+  ///
+  PXE_UINT64  BufferAddr;
+
+  ///
+  /// Length of receive buffer.  This must be large enough to hold the
+  /// received frame (media header + data).  If the length of smaller than
+  /// the received frame, data will be lost.
+  ///
+  PXE_UINT32  BufferLen;
+
+  ///
+  /// Reserved, must be set to zero.
+  ///
+  PXE_UINT32  reserved;
+} PXE_CPB_RECEIVE;
+
+typedef struct s_pxe_db_receive {
+  ///
+  /// Source and destination MAC addresses from media header.
+  ///
+  PXE_MAC_ADDR        SrcAddr;
+  PXE_MAC_ADDR        DestAddr;
+
+  ///
+  /// Length of received frame.  May be larger than receive buffer size.
+  /// The receive buffer will not be overwritten.  This is how to tell
+  /// if data was lost because the receive buffer was too small.
+  ///
+  PXE_UINT32          FrameLen;
+
+  ///
+  /// Protocol type from media header.
+  ///
+  PXE_MEDIA_PROTOCOL  Protocol;
+
+  ///
+  /// Length of media header in received frame.
+  ///
+  PXE_UINT16          MediaHeaderLen;
+
+  ///
+  /// Type of receive frame.
+  ///
+  PXE_FRAME_TYPE      Type;
+
+  ///
+  /// Reserved, must be zero.
+  ///
+  PXE_UINT8           reserved[7];
+
+} PXE_DB_RECEIVE;
+
+#pragma pack()
+
+#endif
diff --git a/sys/contrib/edk2/Include/Uefi/UefiSpec.h b/sys/contrib/edk2/Include/Uefi/UefiSpec.h
new file mode 100644
index 0000000000..bea32b7f5e
--- /dev/null
+++ b/sys/contrib/edk2/Include/Uefi/UefiSpec.h
@@ -0,0 +1,2194 @@
+/** @file
+  Include file that supports UEFI.
+
+  This include file must contain things defined in the UEFI 2.6 specification.
+  If a code construct is defined in the UEFI 2.6 specification it must be included
+  by this include file.
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under 
+the terms and conditions of the BSD License that accompanies this distribution.  
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.                                          
+    
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __UEFI_SPEC_H__
+#define __UEFI_SPEC_H__
+
+#include <Uefi/UefiMultiPhase.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextInEx.h>
+#include <Protocol/SimpleTextOut.h>
+
+///
+/// Enumeration of EFI memory allocation types.
+///
+typedef enum {
+  ///
+  /// Allocate any available range of pages that satisfies the request.
+  ///
+  AllocateAnyPages,
+  ///
+  /// Allocate any available range of pages whose uppermost address is less than 
+  /// or equal to a specified maximum address.
+  ///
+  AllocateMaxAddress,
+  ///
+  /// Allocate pages at a specified address.
+  ///
+  AllocateAddress,
+  ///
+  /// Maximum enumeration value that may be used for bounds checking.
+  ///
+  MaxAllocateType
+} EFI_ALLOCATE_TYPE;
+
+//
+// Bit definitions for EFI_TIME.Daylight
+//
+#define EFI_TIME_ADJUST_DAYLIGHT  0x01
+#define EFI_TIME_IN_DAYLIGHT      0x02
+
+///
+/// Value definition for EFI_TIME.TimeZone.
+///
+#define EFI_UNSPECIFIED_TIMEZONE  0x07FF
+
+//
+// Memory cacheability attributes
+//
+#define EFI_MEMORY_UC               0x0000000000000001ULL
+#define EFI_MEMORY_WC               0x0000000000000002ULL
+#define EFI_MEMORY_WT               0x0000000000000004ULL
+#define EFI_MEMORY_WB               0x0000000000000008ULL
+#define EFI_MEMORY_UCE              0x0000000000000010ULL
+//
+// Physical memory protection attributes
+//
+// Note: UEFI spec 2.5 and following: use EFI_MEMORY_RO as write-protected physical memory
+// protection attribute. Also, EFI_MEMORY_WP means cacheability attribute.
+//
+#define EFI_MEMORY_WP               0x0000000000001000ULL
+#define EFI_MEMORY_RP               0x0000000000002000ULL
+#define EFI_MEMORY_XP               0x0000000000004000ULL
+#define EFI_MEMORY_RO               0x0000000000020000ULL
+//
+// Physical memory persistence attribute. 
+// The memory region supports byte-addressable non-volatility.
+//
+#define EFI_MEMORY_NV               0x0000000000008000ULL
+//
+// The memory region provides higher reliability relative to other memory in the system.
+// If all memory has the same reliability, then this bit is not used.
+//
+#define EFI_MEMORY_MORE_RELIABLE    0x0000000000010000ULL
+//
+// Runtime memory attribute
+//
+#define EFI_MEMORY_RUNTIME          0x8000000000000000ULL
+
+///
+/// Memory descriptor version number.
+///
+#define EFI_MEMORY_DESCRIPTOR_VERSION 1
+
+///
+/// Definition of an EFI memory descriptor.
+///
+typedef struct {
+  ///
+  /// Type of the memory region.  See EFI_MEMORY_TYPE.
+  ///
+  UINT32                Type;
+  ///
+  /// Physical address of the first byte of the memory region.  Must aligned 
+  /// on a 4 KB boundary.
+  ///
+  EFI_PHYSICAL_ADDRESS  PhysicalStart;
+  ///
+  /// Virtual address of the first byte of the memory region.  Must aligned 
+  /// on a 4 KB boundary.
+  ///
+  EFI_VIRTUAL_ADDRESS   VirtualStart;
+  ///
+  /// Number of 4KB pages in the memory region.
+  ///
+  UINT64                NumberOfPages;
+  ///
+  /// Attributes of the memory region that describe the bit mask of capabilities
+  /// for that memory region, and not necessarily the current settings for that 
+  /// memory region.
+  ///
+  UINT64                Attribute;
+} EFI_MEMORY_DESCRIPTOR;
+
+/**
+  Allocates memory pages from the system.
+
+  @param[in]       Type         The type of allocation to perform.
+  @param[in]       MemoryType   The type of memory to allocate.
+                                MemoryType values in the range 0x70000000..0x7FFFFFFF
+                                are reserved for OEM use. MemoryType values in the range
+                                0x80000000..0xFFFFFFFF are reserved for use by UEFI OS loaders
+                                that are provided by operating system vendors.
+  @param[in]       Pages        The number of contiguous 4 KB pages to allocate.
+  @param[in, out]  Memory       The pointer to a physical address. On input, the way in which the address is
+                                used depends on the value of Type.
+
+  @retval EFI_SUCCESS           The requested pages were allocated.
+  @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or
+                                AllocateMaxAddress or AllocateAddress.
+                                2) MemoryType is in the range
+                                EfiMaxMemoryType..0x6FFFFFFF.
+                                3) Memory is NULL.
+                                4) MemoryType is EfiPersistentMemory.
+  @retval EFI_OUT_OF_RESOURCES  The pages could not be allocated.
+  @retval EFI_NOT_FOUND         The requested pages could not be found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_PAGES)(
+  IN     EFI_ALLOCATE_TYPE            Type,
+  IN     EFI_MEMORY_TYPE              MemoryType,
+  IN     UINTN                        Pages,
+  IN OUT EFI_PHYSICAL_ADDRESS         *Memory
+  );
+
+/**
+  Frees memory pages.
+
+  @param[in]  Memory      The base physical address of the pages to be freed.
+  @param[in]  Pages       The number of contiguous 4 KB pages to free.
+
+  @retval EFI_SUCCESS           The requested pages were freed.
+  @retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.
+  @retval EFI_NOT_FOUND         The requested memory pages were not allocated with
+                                AllocatePages().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_PAGES)(
+  IN  EFI_PHYSICAL_ADDRESS         Memory,
+  IN  UINTN                        Pages
+  );
+
+/**
+  Returns the current memory map.
+
+  @param[in, out]  MemoryMapSize         A pointer to the size, in bytes, of the MemoryMap buffer.
+                                         On input, this is the size of the buffer allocated by the caller.
+                                         On output, it is the size of the buffer returned by the firmware if
+                                         the buffer was large enough, or the size of the buffer needed to contain
+                                         the map if the buffer was too small.
+  @param[in, out]  MemoryMap             A pointer to the buffer in which firmware places the current memory
+                                         map.
+  @param[out]      MapKey                A pointer to the location in which firmware returns the key for the
+                                         current memory map.
+  @param[out]      DescriptorSize        A pointer to the location in which firmware returns the size, in bytes, of
+                                         an individual EFI_MEMORY_DESCRIPTOR.
+  @param[out]      DescriptorVersion     A pointer to the location in which firmware returns the version number
+                                         associated with the EFI_MEMORY_DESCRIPTOR.
+
+  @retval EFI_SUCCESS           The memory map was returned in the MemoryMap buffer.
+  @retval EFI_BUFFER_TOO_SMALL  The MemoryMap buffer was too small. The current buffer size
+                                needed to hold the memory map is returned in MemoryMapSize.
+  @retval EFI_INVALID_PARAMETER 1) MemoryMapSize is NULL.
+                                2) The MemoryMap buffer is not too small and MemoryMap is
+                                   NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_MEMORY_MAP)(
+  IN OUT UINTN                       *MemoryMapSize,
+  IN OUT EFI_MEMORY_DESCRIPTOR       *MemoryMap,
+  OUT    UINTN                       *MapKey,
+  OUT    UINTN                       *DescriptorSize,
+  OUT    UINT32                      *DescriptorVersion
+  );
+
+/**
+  Allocates pool memory.
+
+  @param[in]   PoolType         The type of pool to allocate.
+                                MemoryType values in the range 0x70000000..0x7FFFFFFF
+                                are reserved for OEM use. MemoryType values in the range
+                                0x80000000..0xFFFFFFFF are reserved for use by UEFI OS loaders
+                                that are provided by operating system vendors.
+  @param[in]   Size             The number of bytes to allocate from the pool.
+  @param[out]  Buffer           A pointer to a pointer to the allocated buffer if the call succeeds;
+                                undefined otherwise.
+
+  @retval EFI_SUCCESS           The requested number of bytes was allocated.
+  @retval EFI_OUT_OF_RESOURCES  The pool requested could not be allocated.
+  @retval EFI_INVALID_PARAMETER Buffer is NULL.
+                                PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF.
+                                PoolType is EfiPersistentMemory.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ALLOCATE_POOL)(
+  IN  EFI_MEMORY_TYPE              PoolType,
+  IN  UINTN                        Size,
+  OUT VOID                         **Buffer
+  );
+
+/**
+  Returns pool memory to the system.
+
+  @param[in]  Buffer            The pointer to the buffer to free.
+
+  @retval EFI_SUCCESS           The memory was returned to the system.
+  @retval EFI_INVALID_PARAMETER Buffer was invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FREE_POOL)(
+  IN  VOID                         *Buffer
+  );
+
+/**
+  Changes the runtime addressing mode of EFI firmware from physical to virtual.
+
+  @param[in]  MemoryMapSize     The size in bytes of VirtualMap.
+  @param[in]  DescriptorSize    The size in bytes of an entry in the VirtualMap.
+  @param[in]  DescriptorVersion The version of the structure entries in VirtualMap.
+  @param[in]  VirtualMap        An array of memory descriptors which contain new virtual
+                                address mapping information for all runtime ranges.
+
+  @retval EFI_SUCCESS           The virtual address map has been applied.
+  @retval EFI_UNSUPPORTED       EFI firmware is not at runtime, or the EFI firmware is already in
+                                virtual address mapped mode.
+  @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid.
+  @retval EFI_NO_MAPPING        A virtual address was not supplied for a range in the memory
+                                map that requires a mapping.
+  @retval EFI_NOT_FOUND         A virtual address was supplied for an address that is not found
+                                in the memory map.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)(
+  IN  UINTN                        MemoryMapSize,
+  IN  UINTN                        DescriptorSize,
+  IN  UINT32                       DescriptorVersion,
+  IN  EFI_MEMORY_DESCRIPTOR        *VirtualMap
+  );
+
+/**
+  Connects one or more drivers to a controller.
+
+  @param[in]  ControllerHandle      The handle of the controller to which driver(s) are to be connected.
+  @param[in]  DriverImageHandle     A pointer to an ordered list handles that support the
+                                    EFI_DRIVER_BINDING_PROTOCOL.
+  @param[in]  RemainingDevicePath   A pointer to the device path that specifies a child of the
+                                    controller specified by ControllerHandle.
+  @param[in]  Recursive             If TRUE, then ConnectController() is called recursively
+                                    until the entire tree of controllers below the controller specified
+                                    by ControllerHandle have been created. If FALSE, then
+                                    the tree of controllers is only expanded one level.
+
+  @retval EFI_SUCCESS           1) One or more drivers were connected to ControllerHandle.
+                                2) No drivers were connected to ControllerHandle, but
+                                RemainingDevicePath is not NULL, and it is an End Device
+                                Path Node.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+  @retval EFI_NOT_FOUND         1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
+                                present in the system.
+                                2) No drivers were connected to ControllerHandle.
+  @retval EFI_SECURITY_VIOLATION 
+                                The user has no permission to start UEFI device drivers on the device path 
+                                associated with the ControllerHandle or specified by the RemainingDevicePath.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONNECT_CONTROLLER)(
+  IN  EFI_HANDLE                    ControllerHandle,
+  IN  EFI_HANDLE                    *DriverImageHandle,   OPTIONAL
+  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath, OPTIONAL
+  IN  BOOLEAN                       Recursive
+  );
+
+/**
+  Disconnects one or more drivers from a controller.
+
+  @param[in]  ControllerHandle      The handle of the controller from which driver(s) are to be disconnected.
+  @param[in]  DriverImageHandle     The driver to disconnect from ControllerHandle.
+                                    If DriverImageHandle is NULL, then all the drivers currently managing
+                                    ControllerHandle are disconnected from ControllerHandle.
+  @param[in]  ChildHandle           The handle of the child to destroy.
+                                    If ChildHandle is NULL, then all the children of ControllerHandle are
+                                    destroyed before the drivers are disconnected from ControllerHandle.
+
+  @retval EFI_SUCCESS           1) One or more drivers were disconnected from the controller.
+                                2) On entry, no drivers are managing ControllerHandle.
+                                3) DriverImageHandle is not NULL, and on entry
+                                   DriverImageHandle is not managing ControllerHandle.
+  @retval EFI_INVALID_PARAMETER 1) ControllerHandle is NULL.
+                                2) DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
+                                3) ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
+                                4) DriverImageHandle does not support the EFI_DRIVER_BINDING_PROTOCOL.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to disconnect any drivers from
+                                ControllerHandle.
+  @retval EFI_DEVICE_ERROR      The controller could not be disconnected because of a device error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DISCONNECT_CONTROLLER)(
+  IN  EFI_HANDLE                     ControllerHandle,
+  IN  EFI_HANDLE                     DriverImageHandle, OPTIONAL
+  IN  EFI_HANDLE                     ChildHandle        OPTIONAL
+  );
+
+
+
+//
+// ConvertPointer DebugDisposition type.
+//
+#define EFI_OPTIONAL_PTR     0x00000001
+
+/**
+  Determines the new virtual address that is to be used on subsequent memory accesses.
+
+  @param[in]       DebugDisposition  Supplies type information for the pointer being converted.
+  @param[in, out]  Address           A pointer to a pointer that is to be fixed to be the value needed
+                                     for the new virtual address mappings being applied.
+
+  @retval EFI_SUCCESS           The pointer pointed to by Address was modified.
+  @retval EFI_INVALID_PARAMETER 1) Address is NULL.
+                                2) *Address is NULL and DebugDisposition does
+                                not have the EFI_OPTIONAL_PTR bit set.
+  @retval EFI_NOT_FOUND         The pointer pointed to by Address was not found to be part
+                                of the current memory map. This is normally fatal.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CONVERT_POINTER)(
+  IN     UINTN                      DebugDisposition,
+  IN OUT VOID                       **Address
+  );
+
+
+//
+// These types can be ORed together as needed - for example,
+// EVT_TIMER might be Ored with EVT_NOTIFY_WAIT or
+// EVT_NOTIFY_SIGNAL.
+//
+#define EVT_TIMER                         0x80000000
+#define EVT_RUNTIME                       0x40000000
+#define EVT_NOTIFY_WAIT                   0x00000100
+#define EVT_NOTIFY_SIGNAL                 0x00000200
+
+#define EVT_SIGNAL_EXIT_BOOT_SERVICES     0x00000201
+#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202
+
+//
+// The event's NotifyContext pointer points to a runtime memory
+// address.
+// The event is deprecated in UEFI2.0 and later specifications.
+//
+#define EVT_RUNTIME_CONTEXT               0x20000000
+
+
+/**
+  Invoke a notification event
+
+  @param[in]  Event                 Event whose notification function is being invoked.
+  @param[in]  Context               The pointer to the notification function's context,
+                                    which is implementation-dependent.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_EVENT_NOTIFY)(
+  IN  EFI_EVENT                Event,
+  IN  VOID                     *Context
+  );
+
+/**
+  Creates an event.
+
+  @param[in]   Type             The type of event to create and its mode and attributes.
+  @param[in]   NotifyTpl        The task priority level of event notifications, if needed.
+  @param[in]   NotifyFunction   The pointer to the event's notification function, if any.
+  @param[in]   NotifyContext    The pointer to the notification function's context; corresponds to parameter
+                                Context in the notification function.
+  @param[out]  Event            The pointer to the newly created event if the call succeeds; undefined
+                                otherwise.
+
+  @retval EFI_SUCCESS           The event structure was created.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The event could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CREATE_EVENT)(
+  IN  UINT32                       Type,
+  IN  EFI_TPL                      NotifyTpl,
+  IN  EFI_EVENT_NOTIFY             NotifyFunction,
+  IN  VOID                         *NotifyContext,
+  OUT EFI_EVENT                    *Event
+  );
+
+/**
+  Creates an event in a group.
+
+  @param[in]   Type             The type of event to create and its mode and attributes.
+  @param[in]   NotifyTpl        The task priority level of event notifications,if needed.
+  @param[in]   NotifyFunction   The pointer to the event's notification function, if any.
+  @param[in]   NotifyContext    The pointer to the notification function's context; corresponds to parameter
+                                Context in the notification function.
+  @param[in]   EventGroup       The pointer to the unique identifier of the group to which this event belongs.
+                                If this is NULL, then the function behaves as if the parameters were passed
+                                to CreateEvent.
+  @param[out]  Event            The pointer to the newly created event if the call succeeds; undefined
+                                otherwise.
+
+  @retval EFI_SUCCESS           The event structure was created.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_OUT_OF_RESOURCES  The event could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CREATE_EVENT_EX)(
+  IN       UINT32                 Type,
+  IN       EFI_TPL                NotifyTpl,
+  IN       EFI_EVENT_NOTIFY       NotifyFunction OPTIONAL,
+  IN CONST VOID                   *NotifyContext OPTIONAL,
+  IN CONST EFI_GUID               *EventGroup    OPTIONAL,
+  OUT      EFI_EVENT              *Event
+  );
+
+///
+/// Timer delay types
+///
+typedef enum {
+  ///
+  /// An event's timer settings is to be cancelled and not trigger time is to be set/
+  ///
+  TimerCancel,
+  ///
+  /// An event is to be signaled periodically at a specified interval from the current time.
+  ///
+  TimerPeriodic,
+  ///
+  /// An event is to be signaled once at a specified interval from the current time.
+  ///
+  TimerRelative
+} EFI_TIMER_DELAY;
+
+/**
+  Sets the type of timer and the trigger time for a timer event.
+
+  @param[in]  Event             The timer event that is to be signaled at the specified time.
+  @param[in]  Type              The type of time that is specified in TriggerTime.
+  @param[in]  TriggerTime       The number of 100ns units until the timer expires.
+                                A TriggerTime of 0 is legal.
+                                If Type is TimerRelative and TriggerTime is 0, then the timer
+                                event will be signaled on the next timer tick.
+                                If Type is TimerPeriodic and TriggerTime is 0, then the timer
+                                event will be signaled on every timer tick.
+
+  @retval EFI_SUCCESS           The event has been set to be signaled at the requested time.
+  @retval EFI_INVALID_PARAMETER Event or Type is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIMER)(
+  IN  EFI_EVENT                Event,
+  IN  EFI_TIMER_DELAY          Type,
+  IN  UINT64                   TriggerTime
+  );
+
+/**
+  Signals an event.
+
+  @param[in]  Event             The event to signal.
+
+  @retval EFI_SUCCESS           The event has been signaled.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SIGNAL_EVENT)(
+  IN  EFI_EVENT                Event
+  );
+
+/**
+  Stops execution until an event is signaled.
+
+  @param[in]   NumberOfEvents   The number of events in the Event array.
+  @param[in]   Event            An array of EFI_EVENT.
+  @param[out]  Index            The pointer to the index of the event which satisfied the wait condition.
+
+  @retval EFI_SUCCESS           The event indicated by Index was signaled.
+  @retval EFI_INVALID_PARAMETER 1) NumberOfEvents is 0.
+                                2) The event indicated by Index is of type
+                                   EVT_NOTIFY_SIGNAL.
+  @retval EFI_UNSUPPORTED       The current TPL is not TPL_APPLICATION.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_WAIT_FOR_EVENT)(
+  IN  UINTN                    NumberOfEvents,
+  IN  EFI_EVENT                *Event,
+  OUT UINTN                    *Index
+  );
+
+/**
+  Closes an event.
+
+  @param[in]  Event             The event to close.
+
+  @retval EFI_SUCCESS           The event has been closed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_EVENT)(
+  IN EFI_EVENT                Event
+  );
+
+/**
+  Checks whether an event is in the signaled state.
+
+  @param[in]  Event             The event to check.
+
+  @retval EFI_SUCCESS           The event is in the signaled state.
+  @retval EFI_NOT_READY         The event is not in the signaled state.
+  @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CHECK_EVENT)(
+  IN EFI_EVENT                Event
+  );
+
+
+//
+// Task priority level
+//
+#define TPL_APPLICATION       4
+#define TPL_CALLBACK          8
+#define TPL_NOTIFY            16
+#define TPL_HIGH_LEVEL        31
+
+
+/**
+  Raises a task's priority level and returns its previous level.
+
+  @param[in]  NewTpl          The new task priority level.
+
+  @return Previous task priority level
+
+**/
+typedef
+EFI_TPL
+(EFIAPI *EFI_RAISE_TPL)(
+  IN EFI_TPL      NewTpl
+  );
+
+/**
+  Restores a task's priority level to its previous value.
+
+  @param[in]  OldTpl          The previous task priority level to restore.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_RESTORE_TPL)(
+  IN EFI_TPL      OldTpl
+  );
+
+/**
+  Returns the value of a variable.
+
+  @param[in]       VariableName  A Null-terminated string that is the name of the vendor's
+                                 variable.
+  @param[in]       VendorGuid    A unique identifier for the vendor.
+  @param[out]      Attributes    If not NULL, a pointer to the memory location to return the
+                                 attributes bitmask for the variable.
+  @param[in, out]  DataSize      On input, the size in bytes of the return Data buffer.
+                                 On output the size of data returned in Data.
+  @param[out]      Data          The buffer to return the contents of the variable. May be NULL
+                                 with a zero DataSize in order to determine the size buffer needed.
+
+  @retval EFI_SUCCESS            The function completed successfully.
+  @retval EFI_NOT_FOUND          The variable was not found.
+  @retval EFI_BUFFER_TOO_SMALL   The DataSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER  VariableName is NULL.
+  @retval EFI_INVALID_PARAMETER  VendorGuid is NULL.
+  @retval EFI_INVALID_PARAMETER  DataSize is NULL.
+  @retval EFI_INVALID_PARAMETER  The DataSize is not too small and Data is NULL.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_VARIABLE)(
+  IN     CHAR16                      *VariableName,
+  IN     EFI_GUID                    *VendorGuid,
+  OUT    UINT32                      *Attributes,    OPTIONAL
+  IN OUT UINTN                       *DataSize,
+  OUT    VOID                        *Data           OPTIONAL
+  );
+
+/**
+  Enumerates the current variable names.
+
+  @param[in, out]  VariableNameSize The size of the VariableName buffer.
+  @param[in, out]  VariableName     On input, supplies the last VariableName that was returned
+                                    by GetNextVariableName(). On output, returns the Nullterminated
+                                    string of the current variable.
+  @param[in, out]  VendorGuid       On input, supplies the last VendorGuid that was returned by
+                                    GetNextVariableName(). On output, returns the
+                                    VendorGuid of the current variable.
+
+  @retval EFI_SUCCESS           The function completed successfully.
+  @retval EFI_NOT_FOUND         The next variable was not found.
+  @retval EFI_BUFFER_TOO_SMALL  The VariableNameSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER VariableNameSize is NULL.
+  @retval EFI_INVALID_PARAMETER VariableName is NULL.
+  @retval EFI_INVALID_PARAMETER VendorGuid is NULL.
+  @retval EFI_DEVICE_ERROR      The variable could not be retrieved due to a hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(
+  IN OUT UINTN                    *VariableNameSize,
+  IN OUT CHAR16                   *VariableName,
+  IN OUT EFI_GUID                 *VendorGuid
+  );
+
+/**
+  Sets the value of a variable.
+
+  @param[in]  VariableName       A Null-terminated string that is the name of the vendor's variable.
+                                 Each VariableName is unique for each VendorGuid. VariableName must
+                                 contain 1 or more characters. If VariableName is an empty string,
+                                 then EFI_INVALID_PARAMETER is returned.
+  @param[in]  VendorGuid         A unique identifier for the vendor.
+  @param[in]  Attributes         Attributes bitmask to set for the variable.
+  @param[in]  DataSize           The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, 
+                                 EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or 
+                                 EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero 
+                                 causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is 
+                                 set, then a SetVariable() call with a DataSize of zero will not cause any change to 
+                                 the variable value (the timestamp associated with the variable may be updated however 
+                                 even if no new data value is provided,see the description of the 
+                                 EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not 
+                                 be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). 
+  @param[in]  Data               The contents for the variable.
+
+  @retval EFI_SUCCESS            The firmware has successfully stored the variable and its data as
+                                 defined by the Attributes.
+  @retval EFI_INVALID_PARAMETER  An invalid combination of attribute bits, name, and GUID was supplied, or the
+                                 DataSize exceeds the maximum allowed.
+  @retval EFI_INVALID_PARAMETER  VariableName is an empty string.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be retrieved due to a hardware error.
+  @retval EFI_WRITE_PROTECTED    The variable in question is read-only.
+  @retval EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
+  @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 
+                                 or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo 
+                                 does NOT pass the validation check carried out by the firmware.
+  
+  @retval EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_VARIABLE)(
+  IN  CHAR16                       *VariableName,
+  IN  EFI_GUID                     *VendorGuid,
+  IN  UINT32                       Attributes,
+  IN  UINTN                        DataSize,
+  IN  VOID                         *Data
+  );
+
+
+///
+/// This provides the capabilities of the
+/// real time clock device as exposed through the EFI interfaces.
+///
+typedef struct {
+  ///
+  /// Provides the reporting resolution of the real-time clock device in
+  /// counts per second. For a normal PC-AT CMOS RTC device, this
+  /// value would be 1 Hz, or 1, to indicate that the device only reports
+  /// the time to the resolution of 1 second.
+  ///
+  UINT32    Resolution;
+  ///
+  /// Provides the timekeeping accuracy of the real-time clock in an
+  /// error rate of 1E-6 parts per million. For a clock with an accuracy
+  /// of 50 parts per million, the value in this field would be
+  /// 50,000,000.
+  ///
+  UINT32    Accuracy;
+  ///
+  /// A TRUE indicates that a time set operation clears the device's
+  /// time below the Resolution reporting level. A FALSE
+  /// indicates that the state below the Resolution level of the
+  /// device is not cleared when the time is set. Normal PC-AT CMOS
+  /// RTC devices set this value to FALSE.
+  ///
+  BOOLEAN   SetsToZero;
+} EFI_TIME_CAPABILITIES;
+
+/**
+  Returns the current time and date information, and the time-keeping capabilities
+  of the hardware platform.
+
+  @param[out]  Time             A pointer to storage to receive a snapshot of the current time.
+  @param[out]  Capabilities     An optional pointer to a buffer to receive the real time clock
+                                device's capabilities.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_TIME)(
+  OUT  EFI_TIME                    *Time,
+  OUT  EFI_TIME_CAPABILITIES       *Capabilities OPTIONAL
+  );
+
+/**
+  Sets the current local time and date information.
+
+  @param[in]  Time              A pointer to the current time.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_TIME)(
+  IN  EFI_TIME                     *Time
+  );
+
+/**
+  Returns the current wakeup alarm clock setting.
+
+  @param[out]  Enabled          Indicates if the alarm is currently enabled or disabled.
+  @param[out]  Pending          Indicates if the alarm signal is pending and requires acknowledgement.
+  @param[out]  Time             The current alarm setting.
+
+  @retval EFI_SUCCESS           The alarm settings were returned.
+  @retval EFI_INVALID_PARAMETER Enabled is NULL.
+  @retval EFI_INVALID_PARAMETER Pending is NULL.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_WAKEUP_TIME)(
+  OUT BOOLEAN                     *Enabled,
+  OUT BOOLEAN                     *Pending,
+  OUT EFI_TIME                    *Time
+  );
+
+/**
+  Sets the system wakeup alarm clock time.
+
+  @param[in]  Enable            Enable or disable the wakeup alarm.
+  @param[in]  Time              If Enable is TRUE, the time to set the wakeup alarm for.
+                                If Enable is FALSE, then this parameter is optional, and may be NULL.
+
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+                                Enable is FALSE, then the wakeup alarm was disabled.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WAKEUP_TIME)(
+  IN  BOOLEAN                      Enable,
+  IN  EFI_TIME                     *Time   OPTIONAL
+  );
+
+/**
+  Loads an EFI image into memory.
+
+  @param[in]   BootPolicy        If TRUE, indicates that the request originates from the boot
+                                 manager, and that the boot manager is attempting to load
+                                 FilePath as a boot selection. Ignored if SourceBuffer is
+                                 not NULL.
+  @param[in]   ParentImageHandle The caller's image handle.
+  @param[in]   DevicePath        The DeviceHandle specific file path from which the image is
+                                 loaded.
+  @param[in]   SourceBuffer      If not NULL, a pointer to the memory location containing a copy
+                                 of the image to be loaded.
+  @param[in]   SourceSize        The size in bytes of SourceBuffer. Ignored if SourceBuffer is NULL.
+  @param[out]  ImageHandle       The pointer to the returned image handle that is created when the
+                                 image is successfully loaded.
+
+  @retval EFI_SUCCESS            Image was loaded into memory correctly.
+  @retval EFI_NOT_FOUND          Both SourceBuffer and DevicePath are NULL.
+  @retval EFI_INVALID_PARAMETER  One or more parametes are invalid.
+  @retval EFI_UNSUPPORTED        The image type is not supported.
+  @retval EFI_OUT_OF_RESOURCES   Image was not loaded due to insufficient resources.
+  @retval EFI_LOAD_ERROR         Image was not loaded because the image format was corrupt or not
+                                 understood.
+  @retval EFI_DEVICE_ERROR       Image was not loaded because the device returned a read error.
+  @retval EFI_ACCESS_DENIED      Image was not loaded because the platform policy prohibits the 
+                                 image from being loaded. NULL is returned in *ImageHandle.
+  @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a 
+                                 valid EFI_LOADED_IMAGE_PROTOCOL. However, the current 
+                                 platform policy specifies that the image should not be started.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_LOAD)(
+  IN  BOOLEAN                      BootPolicy,
+  IN  EFI_HANDLE                   ParentImageHandle,
+  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
+  IN  VOID                         *SourceBuffer OPTIONAL,
+  IN  UINTN                        SourceSize,
+  OUT EFI_HANDLE                   *ImageHandle
+  );
+
+/**
+  Transfers control to a loaded image's entry point.
+
+  @param[in]   ImageHandle       Handle of image to be started.
+  @param[out]  ExitDataSize      The pointer to the size, in bytes, of ExitData.
+  @param[out]  ExitData          The pointer to a pointer to a data buffer that includes a Null-terminated
+                                 string, optionally followed by additional binary data.
+
+  @retval EFI_INVALID_PARAMETER  ImageHandle is either an invalid image handle or the image
+                                 has already been initialized with StartImage.
+  @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.
+  @return Exit code from image
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_START)(
+  IN  EFI_HANDLE                  ImageHandle,
+  OUT UINTN                       *ExitDataSize,
+  OUT CHAR16                      **ExitData    OPTIONAL
+  );
+
+/**
+  Terminates a loaded EFI image and returns control to boot services.
+
+  @param[in]  ImageHandle       Handle that identifies the image. This parameter is passed to the 
+                                image on entry.
+  @param[in]  ExitStatus        The image's exit code.
+  @param[in]  ExitDataSize      The size, in bytes, of ExitData. Ignored if ExitStatus is EFI_SUCCESS.
+  @param[in]  ExitData          The pointer to a data buffer that includes a Null-terminated string,
+                                optionally followed by additional binary data. The string is a 
+                                description that the caller may use to further indicate the reason 
+                                for the image's exit. ExitData is only valid if ExitStatus 
+                                is something other than EFI_SUCCESS. The ExitData buffer 
+                                must be allocated by calling AllocatePool().
+
+  @retval EFI_SUCCESS           The image specified by ImageHandle was unloaded.
+  @retval EFI_INVALID_PARAMETER The image specified by ImageHandle has been loaded and
+                                started with LoadImage() and StartImage(), but the
+                                image is not the currently executing image.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT)(
+  IN  EFI_HANDLE                   ImageHandle,
+  IN  EFI_STATUS                   ExitStatus,
+  IN  UINTN                        ExitDataSize,
+  IN  CHAR16                       *ExitData     OPTIONAL
+  );
+
+/**
+  Unloads an image.
+
+  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_UNLOAD)(
+  IN  EFI_HANDLE                   ImageHandle
+  );
+
+/**
+  Terminates all boot services.
+
+  @param[in]  ImageHandle       Handle that identifies the exiting image.
+  @param[in]  MapKey            Key to the latest memory map.
+
+  @retval EFI_SUCCESS           Boot services have been terminated.
+  @retval EFI_INVALID_PARAMETER MapKey is incorrect.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_EXIT_BOOT_SERVICES)(
+  IN  EFI_HANDLE                   ImageHandle,
+  IN  UINTN                        MapKey
+  );
+
+/**
+  Induces a fine-grained stall.
+
+  @param[in]  Microseconds      The number of microseconds to stall execution.
+
+  @retval EFI_SUCCESS           Execution was stalled at least the requested number of
+                                Microseconds.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_STALL)(
+  IN  UINTN                    Microseconds
+  );
+
+/**
+  Sets the system's watchdog timer.
+
+  @param[in]  Timeout           The number of seconds to set the watchdog timer to.
+  @param[in]  WatchdogCode      The numeric code to log on a watchdog timer timeout event.
+  @param[in]  DataSize          The size, in bytes, of WatchdogData.
+  @param[in]  WatchdogData      A data buffer that includes a Null-terminated string, optionally
+                                followed by additional binary data.
+
+  @retval EFI_SUCCESS           The timeout has been set.
+  @retval EFI_INVALID_PARAMETER The supplied WatchdogCode is invalid.
+  @retval EFI_UNSUPPORTED       The system does not have a watchdog timer.
+  @retval EFI_DEVICE_ERROR      The watchdog timer could not be programmed due to a hardware
+                                error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_WATCHDOG_TIMER)(
+  IN UINTN                    Timeout,
+  IN UINT64                   WatchdogCode,
+  IN UINTN                    DataSize,
+  IN CHAR16                   *WatchdogData OPTIONAL
+  );
+
+/**
+  Resets the entire platform.
+
+  @param[in]  ResetType         The type of reset to perform.
+  @param[in]  ResetStatus       The status code for the reset.
+  @param[in]  DataSize          The size, in bytes, of ResetData.
+  @param[in]  ResetData         For a ResetType of EfiResetCold, EfiResetWarm, or
+                                EfiResetShutdown the data buffer starts with a Null-terminated
+                                string, optionally followed by additional binary data.
+                                The string is a description that the caller may use to further
+                                indicate the reason for the system reset. ResetData is only
+                                valid if ResetStatus is something other than EFI_SUCCESS
+                                unless the ResetType is EfiResetPlatformSpecific
+                                where a minimum amount of ResetData is always required.
+**/
+typedef
+VOID
+(EFIAPI *EFI_RESET_SYSTEM)(
+  IN EFI_RESET_TYPE           ResetType,
+  IN EFI_STATUS               ResetStatus,
+  IN UINTN                    DataSize,
+  IN VOID                     *ResetData OPTIONAL
+  );
+
+/**
+  Returns a monotonically increasing count for the platform.
+
+  @param[out]  Count            The pointer to returned value.
+
+  @retval EFI_SUCCESS           The next monotonic count was returned.
+  @retval EFI_INVALID_PARAMETER Count is NULL.
+  @retval EFI_DEVICE_ERROR      The device is not functioning properly.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(
+  OUT UINT64                  *Count
+  );
+
+/**
+  Returns the next high 32 bits of the platform's monotonic counter.
+
+  @param[out]  HighCount        The pointer to returned value.
+
+  @retval EFI_SUCCESS           The next high monotonic count was returned.
+  @retval EFI_INVALID_PARAMETER HighCount is NULL.
+  @retval EFI_DEVICE_ERROR      The device is not functioning properly.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)(
+  OUT UINT32                  *HighCount
+  );
+
+/**
+  Computes and returns a 32-bit CRC for a data buffer.
+
+  @param[in]   Data             A pointer to the buffer on which the 32-bit CRC is to be computed.
+  @param[in]   DataSize         The number of bytes in the buffer Data.
+  @param[out]  Crc32            The 32-bit CRC that was computed for the data buffer specified by Data
+                                and DataSize.
+
+  @retval EFI_SUCCESS           The 32-bit CRC was computed for the data buffer and returned in
+                                Crc32.
+  @retval EFI_INVALID_PARAMETER Data is NULL.
+  @retval EFI_INVALID_PARAMETER Crc32 is NULL.
+  @retval EFI_INVALID_PARAMETER DataSize is 0.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CALCULATE_CRC32)(
+  IN  VOID                              *Data,
+  IN  UINTN                             DataSize,
+  OUT UINT32                            *Crc32
+  );
+
+/**
+  Copies the contents of one buffer to another buffer.
+
+  @param[in]  Destination       The pointer to the destination buffer of the memory copy.
+  @param[in]  Source            The pointer to the source buffer of the memory copy.
+  @param[in]  Length            Number of bytes to copy from Source to Destination.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_COPY_MEM)(
+  IN VOID     *Destination,
+  IN VOID     *Source,
+  IN UINTN    Length
+  );
+
+/**
+  The SetMem() function fills a buffer with a specified value.
+
+  @param[in]  Buffer            The pointer to the buffer to fill.
+  @param[in]  Size              Number of bytes in Buffer to fill.
+  @param[in]  Value             Value to fill Buffer with.
+
+**/
+typedef
+VOID
+(EFIAPI *EFI_SET_MEM)(
+  IN VOID     *Buffer,
+  IN UINTN    Size,
+  IN UINT8    Value
+  );
+
+///
+/// Enumeration of EFI Interface Types
+///
+typedef enum {
+  ///
+  /// Indicates that the supplied protocol interface is supplied in native form.
+  ///
+  EFI_NATIVE_INTERFACE
+} EFI_INTERFACE_TYPE;
+
+/**
+  Installs a protocol interface on a device handle. If the handle does not exist, it is created and added
+  to the list of handles in the system. InstallMultipleProtocolInterfaces() performs
+  more error checking than InstallProtocolInterface(), so it is recommended that
+  InstallMultipleProtocolInterfaces() be used in place of
+  InstallProtocolInterface()
+
+  @param[in, out]  Handle         A pointer to the EFI_HANDLE on which the interface is to be installed.
+  @param[in]       Protocol       The numeric ID of the protocol interface.
+  @param[in]       InterfaceType  Indicates whether Interface is supplied in native form.
+  @param[in]       Interface      A pointer to the protocol interface.
+
+  @retval EFI_SUCCESS           The protocol interface was installed.
+  @retval EFI_OUT_OF_RESOURCES  Space for a new handle could not be allocated.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER InterfaceType is not EFI_NATIVE_INTERFACE.
+  @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)(
+  IN OUT EFI_HANDLE               *Handle,
+  IN     EFI_GUID                 *Protocol,
+  IN     EFI_INTERFACE_TYPE       InterfaceType,
+  IN     VOID                     *Interface
+  );
+
+/**
+  Installs one or more protocol interfaces into the boot services environment.
+
+  @param[in, out]  Handle       The pointer to a handle to install the new protocol interfaces on,
+                                or a pointer to NULL if a new handle is to be allocated.
+  @param  ...                   A variable argument list containing pairs of protocol GUIDs and protocol
+                                interfaces.
+
+  @retval EFI_SUCCESS           All the protocol interface was installed.
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.
+  @retval EFI_ALREADY_STARTED   A Device Path Protocol instance was passed in that is already present in
+                                the handle database.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+  IN OUT EFI_HANDLE           *Handle,
+  ...
+  );
+
+/**
+  Reinstalls a protocol interface on a device handle.
+
+  @param[in]  Handle            Handle on which the interface is to be reinstalled.
+  @param[in]  Protocol          The numeric ID of the interface.
+  @param[in]  OldInterface      A pointer to the old interface. NULL can be used if a structure is not
+                                associated with Protocol.
+  @param[in]  NewInterface      A pointer to the new interface.
+
+  @retval EFI_SUCCESS           The protocol interface was reinstalled.
+  @retval EFI_NOT_FOUND         The OldInterface on the handle was not found.
+  @retval EFI_ACCESS_DENIED     The protocol interface could not be reinstalled,
+                                because OldInterface is still being used by a
+                                driver that will not release it.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)(
+  IN EFI_HANDLE               Handle,
+  IN EFI_GUID                 *Protocol,
+  IN VOID                     *OldInterface,
+  IN VOID                     *NewInterface
+  );
+
+/**
+  Removes a protocol interface from a device handle. It is recommended that
+  UninstallMultipleProtocolInterfaces() be used in place of
+  UninstallProtocolInterface().
+
+  @param[in]  Handle            The handle on which the interface was installed.
+  @param[in]  Protocol          The numeric ID of the interface.
+  @param[in]  Interface         A pointer to the interface.
+
+  @retval EFI_SUCCESS           The interface was removed.
+  @retval EFI_NOT_FOUND         The interface was not found.
+  @retval EFI_ACCESS_DENIED     The interface was not removed because the interface
+                                is still being used by a driver.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(
+  IN EFI_HANDLE               Handle,
+  IN EFI_GUID                 *Protocol,
+  IN VOID                     *Interface
+  );
+
+/**
+  Removes one or more protocol interfaces into the boot services environment.
+
+  @param[in]  Handle            The handle to remove the protocol interfaces from.
+  @param  ...                   A variable argument list containing pairs of protocol GUIDs and
+                                protocol interfaces.
+
+  @retval EFI_SUCCESS           All the protocol interfaces were removed.
+  @retval EFI_INVALID_PARAMETER One of the protocol interfaces was not previously installed on Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(
+  IN EFI_HANDLE           Handle,
+  ...
+  );
+
+/**
+  Queries a handle to determine if it supports a specified protocol.
+
+  @param[in]   Handle           The handle being queried.
+  @param[in]   Protocol         The published unique identifier of the protocol.
+  @param[out]  Interface        Supplies the address where a pointer to the corresponding Protocol
+                                Interface is returned.
+
+  @retval EFI_SUCCESS           The interface information for the specified protocol was returned.
+  @retval EFI_UNSUPPORTED       The device does not support the specified protocol.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER Interface is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_HANDLE_PROTOCOL)(
+  IN  EFI_HANDLE               Handle,
+  IN  EFI_GUID                 *Protocol,
+  OUT VOID                     **Interface
+  );
+
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL  0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL        0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL       0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER           0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE           0x00000020
+
+/**
+  Queries a handle to determine if it supports a specified protocol. If the protocol is supported by the
+  handle, it opens the protocol on behalf of the calling agent.
+
+  @param[in]   Handle           The handle for the protocol interface that is being opened.
+  @param[in]   Protocol         The published unique identifier of the protocol.
+  @param[out]  Interface        Supplies the address where a pointer to the corresponding Protocol
+                                Interface is returned.
+  @param[in]   AgentHandle      The handle of the agent that is opening the protocol interface
+                                specified by Protocol and Interface.
+  @param[in]   ControllerHandle If the agent that is opening a protocol is a driver that follows the
+                                UEFI Driver Model, then this parameter is the controller handle
+                                that requires the protocol interface. If the agent does not follow
+                                the UEFI Driver Model, then this parameter is optional and may
+                                be NULL.
+  @param[in]   Attributes       The open mode of the protocol interface specified by Handle
+                                and Protocol.
+
+  @retval EFI_SUCCESS           An item was added to the open list for the protocol interface, and the
+                                protocol interface was returned in Interface.
+  @retval EFI_UNSUPPORTED       Handle does not support Protocol.
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+  @retval EFI_ACCESS_DENIED     Required attributes can't be supported in current environment.
+  @retval EFI_ALREADY_STARTED   Item on the open list already has requierd attributes whose agent
+                                handle is the same as AgentHandle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL)(
+  IN  EFI_HANDLE                Handle,
+  IN  EFI_GUID                  *Protocol,
+  OUT VOID                      **Interface, OPTIONAL
+  IN  EFI_HANDLE                AgentHandle,
+  IN  EFI_HANDLE                ControllerHandle,
+  IN  UINT32                    Attributes
+  );
+
+
+/**
+  Closes a protocol on a handle that was opened using OpenProtocol().
+
+  @param[in]  Handle            The handle for the protocol interface that was previously opened
+                                with OpenProtocol(), and is now being closed.
+  @param[in]  Protocol          The published unique identifier of the protocol.
+  @param[in]  AgentHandle       The handle of the agent that is closing the protocol interface.
+  @param[in]  ControllerHandle  If the agent that opened a protocol is a driver that follows the
+                                UEFI Driver Model, then this parameter is the controller handle
+                                that required the protocol interface.
+
+  @retval EFI_SUCCESS           The protocol instance was closed.
+  @retval EFI_INVALID_PARAMETER 1) Handle is NULL.
+                                2) AgentHandle is NULL.
+                                3) ControllerHandle is not NULL and ControllerHandle is not a valid EFI_HANDLE.
+                                4) Protocol is NULL.
+  @retval EFI_NOT_FOUND         1) Handle does not support the protocol specified by Protocol.
+                                2) The protocol interface specified by Handle and Protocol is not
+                                   currently open by AgentHandle and ControllerHandle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_PROTOCOL)(
+  IN EFI_HANDLE               Handle,
+  IN EFI_GUID                 *Protocol,
+  IN EFI_HANDLE               AgentHandle,
+  IN EFI_HANDLE               ControllerHandle
+  );
+
+///
+/// EFI Oprn Protocol Information Entry
+///
+typedef struct {
+  EFI_HANDLE  AgentHandle;
+  EFI_HANDLE  ControllerHandle;
+  UINT32      Attributes;
+  UINT32      OpenCount;
+} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY;
+
+/**
+  Retrieves the list of agents that currently have a protocol interface opened.
+
+  @param[in]   Handle           The handle for the protocol interface that is being queried.
+  @param[in]   Protocol         The published unique identifier of the protocol.
+  @param[out]  EntryBuffer      A pointer to a buffer of open protocol information in the form of
+                                EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
+  @param[out]  EntryCount       A pointer to the number of entries in EntryBuffer.
+
+  @retval EFI_SUCCESS           The open protocol information was returned in EntryBuffer, and the
+                                number of entries was returned EntryCount.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to allocate EntryBuffer.
+  @retval EFI_NOT_FOUND         Handle does not support the protocol specified by Protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)(
+  IN  EFI_HANDLE                          Handle,
+  IN  EFI_GUID                            *Protocol,
+  OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+  OUT UINTN                               *EntryCount
+  );
+
+/**
+  Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
+  from pool.
+
+  @param[in]   Handle              The handle from which to retrieve the list of protocol interface
+                                   GUIDs.
+  @param[out]  ProtocolBuffer      A pointer to the list of protocol interface GUID pointers that are
+                                   installed on Handle.
+  @param[out]  ProtocolBufferCount A pointer to the number of GUID pointers present in
+                                   ProtocolBuffer.
+
+  @retval EFI_SUCCESS           The list of protocol interface GUIDs installed on Handle was returned in
+                                ProtocolBuffer. The number of protocol interface GUIDs was
+                                returned in ProtocolBufferCount.
+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the results.
+  @retval EFI_INVALID_PARAMETER Handle is NULL.
+  @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
+  @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PROTOCOLS_PER_HANDLE)(
+  IN  EFI_HANDLE      Handle,
+  OUT EFI_GUID        ***ProtocolBuffer,
+  OUT UINTN           *ProtocolBufferCount
+  );
+
+/**
+  Creates an event that is to be signaled whenever an interface is installed for a specified protocol.
+
+  @param[in]   Protocol         The numeric ID of the protocol for which the event is to be registered.
+  @param[in]   Event            Event that is to be signaled whenever a protocol interface is registered
+                                for Protocol.
+  @param[out]  Registration     A pointer to a memory location to receive the registration value.
+
+  @retval EFI_SUCCESS           The notification event has been registered.
+  @retval EFI_OUT_OF_RESOURCES  Space for the notification event could not be allocated.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER Event is NULL.
+  @retval EFI_INVALID_PARAMETER Registration is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(
+  IN  EFI_GUID                 *Protocol,
+  IN  EFI_EVENT                Event,
+  OUT VOID                     **Registration
+  );
+
+///
+/// Enumeration of EFI Locate Search Types
+///
+typedef enum {
+  ///
+  /// Retrieve all the handles in the handle database.
+  ///
+  AllHandles,
+  ///
+  /// Retrieve the next handle fron a RegisterProtocolNotify() event.
+  ///
+  ByRegisterNotify,
+  ///
+  /// Retrieve the set of handles from the handle database that support a 
+  /// specified protocol.
+  ///
+  ByProtocol
+} EFI_LOCATE_SEARCH_TYPE;
+
+/**
+  Returns an array of handles that support a specified protocol.
+
+  @param[in]       SearchType   Specifies which handle(s) are to be returned.
+  @param[in]       Protocol     Specifies the protocol to search by.
+  @param[in]       SearchKey    Specifies the search key.
+  @param[in, out]  BufferSize   On input, the size in bytes of Buffer. On output, the size in bytes of
+                                the array returned in Buffer (if the buffer was large enough) or the
+                                size, in bytes, of the buffer needed to obtain the array (if the buffer was
+                                not large enough).
+  @param[out]      Buffer       The buffer in which the array is returned.
+
+  @retval EFI_SUCCESS           The array of handles was returned.
+  @retval EFI_NOT_FOUND         No handles match the search.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small for the result.
+  @retval EFI_INVALID_PARAMETER SearchType is not a member of EFI_LOCATE_SEARCH_TYPE.
+  @retval EFI_INVALID_PARAMETER SearchType is ByRegisterNotify and SearchKey is NULL.
+  @retval EFI_INVALID_PARAMETER SearchType is ByProtocol and Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER One or more matches are found and BufferSize is NULL.
+  @retval EFI_INVALID_PARAMETER BufferSize is large enough for the result and Buffer is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE)(
+  IN     EFI_LOCATE_SEARCH_TYPE   SearchType,
+  IN     EFI_GUID                 *Protocol,    OPTIONAL
+  IN     VOID                     *SearchKey,   OPTIONAL
+  IN OUT UINTN                    *BufferSize,
+  OUT    EFI_HANDLE               *Buffer
+  );
+
+/**
+  Locates the handle to a device on the device path that supports the specified protocol.
+
+  @param[in]       Protocol     Specifies the protocol to search for.
+  @param[in, out]  DevicePath   On input, a pointer to a pointer to the device path. On output, the device
+                                path pointer is modified to point to the remaining part of the device
+                                path.
+  @param[out]      Device       A pointer to the returned device handle.
+
+  @retval EFI_SUCCESS           The resulting handle was returned.
+  @retval EFI_NOT_FOUND         No handles match the search.
+  @retval EFI_INVALID_PARAMETER Protocol is NULL.
+  @retval EFI_INVALID_PARAMETER DevicePath is NULL.
+  @retval EFI_INVALID_PARAMETER A handle matched the search and Device is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_DEVICE_PATH)(
+  IN     EFI_GUID                         *Protocol,
+  IN OUT EFI_DEVICE_PATH_PROTOCOL         **DevicePath,
+  OUT    EFI_HANDLE                       *Device
+  );
+
+/**
+  Adds, updates, or removes a configuration table entry from the EFI System Table.
+
+  @param[in]  Guid              A pointer to the GUID for the entry to add, update, or remove.
+  @param[in]  Table             A pointer to the configuration table for the entry to add, update, or
+                                remove. May be NULL.
+
+  @retval EFI_SUCCESS           The (Guid, Table) pair was added, updated, or removed.
+  @retval EFI_NOT_FOUND         An attempt was made to delete a nonexistent entry.
+  @retval EFI_INVALID_PARAMETER Guid is NULL.
+  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available to complete the operation.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(
+  IN EFI_GUID                 *Guid,
+  IN VOID                     *Table
+  );
+
+/**
+  Returns an array of handles that support the requested protocol in a buffer allocated from pool.
+
+  @param[in]       SearchType   Specifies which handle(s) are to be returned.
+  @param[in]       Protocol     Provides the protocol to search by.
+                                This parameter is only valid for a SearchType of ByProtocol.
+  @param[in]       SearchKey    Supplies the search key depending on the SearchType.
+  @param[in, out]  NoHandles    The number of handles returned in Buffer.
+  @param[out]      Buffer       A pointer to the buffer to return the requested array of handles that
+                                support Protocol.
+
+  @retval EFI_SUCCESS           The array of handles was returned in Buffer, and the number of
+                                handles in Buffer was returned in NoHandles.
+  @retval EFI_NOT_FOUND         No handles match the search.
+  @retval EFI_OUT_OF_RESOURCES  There is not enough pool memory to store the matching results.
+  @retval EFI_INVALID_PARAMETER NoHandles is NULL.
+  @retval EFI_INVALID_PARAMETER Buffer is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
+  IN     EFI_LOCATE_SEARCH_TYPE       SearchType,
+  IN     EFI_GUID                     *Protocol,      OPTIONAL
+  IN     VOID                         *SearchKey,     OPTIONAL
+  IN OUT UINTN                        *NoHandles,
+  OUT    EFI_HANDLE                   **Buffer
+  );
+
+/**
+  Returns the first protocol instance that matches the given protocol.
+
+  @param[in]  Protocol          Provides the protocol to search for.
+  @param[in]  Registration      Optional registration key returned from
+                                RegisterProtocolNotify().
+  @param[out]  Interface        On return, a pointer to the first interface that matches Protocol and
+                                Registration.
+
+  @retval EFI_SUCCESS           A protocol instance matching Protocol was found and returned in
+                                Interface.
+  @retval EFI_NOT_FOUND         No protocol instances were found that match Protocol and
+                                Registration.
+  @retval EFI_INVALID_PARAMETER Interface is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LOCATE_PROTOCOL)(
+  IN  EFI_GUID  *Protocol,
+  IN  VOID      *Registration, OPTIONAL
+  OUT VOID      **Interface
+  );
+
+///
+/// EFI Capsule Block Descriptor
+///
+typedef struct {
+  ///
+  /// Length in bytes of the data pointed to by DataBlock/ContinuationPointer.
+  ///
+  UINT64                  Length;
+  union {
+    ///
+    /// Physical address of the data block. This member of the union is
+    /// used if Length is not equal to zero.
+    ///
+    EFI_PHYSICAL_ADDRESS  DataBlock;
+    ///
+    /// Physical address of another block of
+    /// EFI_CAPSULE_BLOCK_DESCRIPTOR structures. This
+    /// member of the union is used if Length is equal to zero. If
+    /// ContinuationPointer is zero this entry represents the end of the list.
+    ///
+    EFI_PHYSICAL_ADDRESS  ContinuationPointer;
+  } Union;
+} EFI_CAPSULE_BLOCK_DESCRIPTOR;
+
+///
+/// EFI Capsule Header.
+///
+typedef struct {
+  ///
+  /// A GUID that defines the contents of a capsule.
+  ///
+  EFI_GUID          CapsuleGuid;
+  ///
+  /// The size of the capsule header. This may be larger than the size of
+  /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply
+  /// extended header entries
+  ///
+  UINT32            HeaderSize;
+  ///
+  /// Bit-mapped list describing the capsule attributes. The Flag values
+  /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values
+  /// of 0x10000 - 0xFFFFFFFF are defined by this specification
+  ///
+  UINT32            Flags;
+  ///
+  /// Size in bytes of the capsule.
+  ///
+  UINT32            CapsuleImageSize;
+} EFI_CAPSULE_HEADER;
+
+///
+/// The EFI System Table entry must point to an array of capsules
+/// that contain the same CapsuleGuid value. The array must be
+/// prefixed by a UINT32 that represents the size of the array of capsules.
+///
+typedef struct {
+  ///
+  /// the size of the array of capsules.
+  ///
+  UINT32   CapsuleArrayNumber;
+  ///
+  /// Point to an array of capsules that contain the same CapsuleGuid value.
+  ///
+  VOID*    CapsulePtr[1];
+} EFI_CAPSULE_TABLE;
+
+#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET          0x00010000
+#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE         0x00020000
+#define CAPSULE_FLAGS_INITIATE_RESET                0x00040000
+
+/**
+  Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
+  consumption, the firmware may process the capsule immediately. If the payload should persist
+  across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
+  be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
+  part of the reset process.
+
+  @param[in]  CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
+                                 being passed into update capsule.
+  @param[in]  CapsuleCount       Number of pointers to EFI_CAPSULE_HEADER in
+                                 CaspuleHeaderArray.
+  @param[in]  ScatterGatherList  Physical pointer to a set of
+                                 EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
+                                 location in physical memory of a set of capsules.
+
+  @retval EFI_SUCCESS           Valid capsule was passed. If
+                                CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
+                                capsule has been successfully processed by the firmware.
+  @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were
+                                set in the capsule header.
+  @retval EFI_INVALID_PARAMETER CapsuleCount is 0.
+  @retval EFI_DEVICE_ERROR      The capsule update was started, but failed due to a device error.
+  @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform.
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has been previously called this error indicates the capsule 
+                                is compatible with this platform but is not capable of being submitted or processed 
+                                in runtime. The caller may resubmit the capsule prior to ExitBootServices().
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has not been previously called then this error indicates 
+                                the capsule is compatible with this platform but there are insufficient resources to process.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UPDATE_CAPSULE)(
+  IN EFI_CAPSULE_HEADER     **CapsuleHeaderArray,
+  IN UINTN                  CapsuleCount,
+  IN EFI_PHYSICAL_ADDRESS   ScatterGatherList   OPTIONAL
+  );
+
+/**
+  Returns if the capsule can be supported via UpdateCapsule().
+
+  @param[in]   CapsuleHeaderArray  Virtual pointer to an array of virtual pointers to the capsules
+                                   being passed into update capsule.
+  @param[in]   CapsuleCount        Number of pointers to EFI_CAPSULE_HEADER in
+                                   CaspuleHeaderArray.
+  @param[out]  MaxiumCapsuleSize   On output the maximum size that UpdateCapsule() can
+                                   support as an argument to UpdateCapsule() via
+                                   CapsuleHeaderArray and ScatterGatherList.
+  @param[out]  ResetType           Returns the type of reset required for the capsule update.
+
+  @retval EFI_SUCCESS           Valid answer returned.
+  @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform, and
+                                MaximumCapsuleSize and ResetType are undefined.
+  @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL.
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has been previously called this error indicates the capsule 
+                                is compatible with this platform but is not capable of being submitted or processed 
+                                in runtime. The caller may resubmit the capsule prior to ExitBootServices().
+  @retval EFI_OUT_OF_RESOURCES  When ExitBootServices() has not been previously called then this error indicates 
+                                the capsule is compatible with this platform but there are insufficient resources to process.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)(
+  IN  EFI_CAPSULE_HEADER     **CapsuleHeaderArray,
+  IN  UINTN                  CapsuleCount,
+  OUT UINT64                 *MaximumCapsuleSize,
+  OUT EFI_RESET_TYPE         *ResetType
+  );
+
+/**
+  Returns information about the EFI variables.
+
+  @param[in]   Attributes                   Attributes bitmask to specify the type of variables on
+                                            which to return information.
+  @param[out]  MaximumVariableStorageSize   On output the maximum size of the storage space
+                                            available for the EFI variables associated with the
+                                            attributes specified.
+  @param[out]  RemainingVariableStorageSize Returns the remaining size of the storage space
+                                            available for the EFI variables associated with the
+                                            attributes specified.
+  @param[out]  MaximumVariableSize          Returns the maximum size of the individual EFI
+                                            variables associated with the attributes specified.
+
+  @retval EFI_SUCCESS                  Valid answer returned.
+  @retval EFI_INVALID_PARAMETER        An invalid combination of attribute bits was supplied
+  @retval EFI_UNSUPPORTED              The attribute is not supported on this platform, and the
+                                       MaximumVariableStorageSize,
+                                       RemainingVariableStorageSize, MaximumVariableSize
+                                       are undefined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_QUERY_VARIABLE_INFO)(
+  IN  UINT32            Attributes,
+  OUT UINT64            *MaximumVariableStorageSize,
+  OUT UINT64            *RemainingVariableStorageSize,
+  OUT UINT64            *MaximumVariableSize
+  );
+
+//
+// Firmware should stop at a firmware user interface on next boot
+//
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                    0x0000000000000001
+#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION             0x0000000000000002
+#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
+#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008
+#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010
+#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY          0x0000000000000040
+
+//
+// EFI Runtime Services Table
+//
+#define EFI_SYSTEM_TABLE_SIGNATURE      SIGNATURE_64 ('I','B','I',' ','S','Y','S','T')
+#define EFI_2_60_SYSTEM_TABLE_REVISION  ((2 << 16) | (60))
+#define EFI_2_50_SYSTEM_TABLE_REVISION  ((2 << 16) | (50))
+#define EFI_2_40_SYSTEM_TABLE_REVISION  ((2 << 16) | (40))
+#define EFI_2_31_SYSTEM_TABLE_REVISION  ((2 << 16) | (31))
+#define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
+#define EFI_2_20_SYSTEM_TABLE_REVISION  ((2 << 16) | (20))
+#define EFI_2_10_SYSTEM_TABLE_REVISION  ((2 << 16) | (10))
+#define EFI_2_00_SYSTEM_TABLE_REVISION  ((2 << 16) | (00))
+#define EFI_1_10_SYSTEM_TABLE_REVISION  ((1 << 16) | (10))
+#define EFI_1_02_SYSTEM_TABLE_REVISION  ((1 << 16) | (02))
+#define EFI_SYSTEM_TABLE_REVISION       EFI_2_60_SYSTEM_TABLE_REVISION
+#define EFI_SPECIFICATION_VERSION       EFI_SYSTEM_TABLE_REVISION
+
+#define EFI_RUNTIME_SERVICES_SIGNATURE  SIGNATURE_64 ('R','U','N','T','S','E','R','V')
+#define EFI_RUNTIME_SERVICES_REVISION   EFI_SPECIFICATION_VERSION
+
+///
+/// EFI Runtime Services Table.
+///
+typedef struct {
+  ///
+  /// The table header for the EFI Runtime Services Table.
+  ///
+  EFI_TABLE_HEADER                Hdr;
+
+  //
+  // Time Services
+  //
+  EFI_GET_TIME                    GetTime;
+  EFI_SET_TIME                    SetTime;
+  EFI_GET_WAKEUP_TIME             GetWakeupTime;
+  EFI_SET_WAKEUP_TIME             SetWakeupTime;
+
+  //
+  // Virtual Memory Services
+  //
+  EFI_SET_VIRTUAL_ADDRESS_MAP     SetVirtualAddressMap;
+  EFI_CONVERT_POINTER             ConvertPointer;
+
+  //
+  // Variable Services
+  //
+  EFI_GET_VARIABLE                GetVariable;
+  EFI_GET_NEXT_VARIABLE_NAME      GetNextVariableName;
+  EFI_SET_VARIABLE                SetVariable;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_GET_NEXT_HIGH_MONO_COUNT    GetNextHighMonotonicCount;
+  EFI_RESET_SYSTEM                ResetSystem;
+
+  //
+  // UEFI 2.0 Capsule Services
+  //
+  EFI_UPDATE_CAPSULE              UpdateCapsule;
+  EFI_QUERY_CAPSULE_CAPABILITIES  QueryCapsuleCapabilities;
+
+  //
+  // Miscellaneous UEFI 2.0 Service
+  //
+  EFI_QUERY_VARIABLE_INFO         QueryVariableInfo;
+} EFI_RUNTIME_SERVICES;
+
+
+#define EFI_BOOT_SERVICES_SIGNATURE   SIGNATURE_64 ('B','O','O','T','S','E','R','V')
+#define EFI_BOOT_SERVICES_REVISION    EFI_SPECIFICATION_VERSION
+
+///
+/// EFI Boot Services Table.
+///
+typedef struct {
+  ///
+  /// The table header for the EFI Boot Services Table.
+  ///
+  EFI_TABLE_HEADER                Hdr;
+
+  //
+  // Task Priority Services
+  //
+  EFI_RAISE_TPL                   RaiseTPL;
+  EFI_RESTORE_TPL                 RestoreTPL;
+
+  //
+  // Memory Services
+  //
+  EFI_ALLOCATE_PAGES              AllocatePages;
+  EFI_FREE_PAGES                  FreePages;
+  EFI_GET_MEMORY_MAP              GetMemoryMap;
+  EFI_ALLOCATE_POOL               AllocatePool;
+  EFI_FREE_POOL                   FreePool;
+
+  //
+  // Event & Timer Services
+  //
+  EFI_CREATE_EVENT                  CreateEvent;
+  EFI_SET_TIMER                     SetTimer;
+  EFI_WAIT_FOR_EVENT                WaitForEvent;
+  EFI_SIGNAL_EVENT                  SignalEvent;
+  EFI_CLOSE_EVENT                   CloseEvent;
+  EFI_CHECK_EVENT                   CheckEvent;
+
+  //
+  // Protocol Handler Services
+  //
+  EFI_INSTALL_PROTOCOL_INTERFACE    InstallProtocolInterface;
+  EFI_REINSTALL_PROTOCOL_INTERFACE  ReinstallProtocolInterface;
+  EFI_UNINSTALL_PROTOCOL_INTERFACE  UninstallProtocolInterface;
+  EFI_HANDLE_PROTOCOL               HandleProtocol;
+  VOID                              *Reserved;
+  EFI_REGISTER_PROTOCOL_NOTIFY      RegisterProtocolNotify;
+  EFI_LOCATE_HANDLE                 LocateHandle;
+  EFI_LOCATE_DEVICE_PATH            LocateDevicePath;
+  EFI_INSTALL_CONFIGURATION_TABLE   InstallConfigurationTable;
+
+  //
+  // Image Services
+  //
+  EFI_IMAGE_LOAD                    LoadImage;
+  EFI_IMAGE_START                   StartImage;
+  EFI_EXIT                          Exit;
+  EFI_IMAGE_UNLOAD                  UnloadImage;
+  EFI_EXIT_BOOT_SERVICES            ExitBootServices;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_GET_NEXT_MONOTONIC_COUNT      GetNextMonotonicCount;
+  EFI_STALL                         Stall;
+  EFI_SET_WATCHDOG_TIMER            SetWatchdogTimer;
+
+  //
+  // DriverSupport Services
+  //
+  EFI_CONNECT_CONTROLLER            ConnectController;
+  EFI_DISCONNECT_CONTROLLER         DisconnectController;
+
+  //
+  // Open and Close Protocol Services
+  //
+  EFI_OPEN_PROTOCOL                 OpenProtocol;
+  EFI_CLOSE_PROTOCOL                CloseProtocol;
+  EFI_OPEN_PROTOCOL_INFORMATION     OpenProtocolInformation;
+
+  //
+  // Library Services
+  //
+  EFI_PROTOCOLS_PER_HANDLE          ProtocolsPerHandle;
+  EFI_LOCATE_HANDLE_BUFFER          LocateHandleBuffer;
+  EFI_LOCATE_PROTOCOL               LocateProtocol;
+  EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES    InstallMultipleProtocolInterfaces;
+  EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES  UninstallMultipleProtocolInterfaces;
+
+  //
+  // 32-bit CRC Services
+  //
+  EFI_CALCULATE_CRC32               CalculateCrc32;
+
+  //
+  // Miscellaneous Services
+  //
+  EFI_COPY_MEM                      CopyMem;
+  EFI_SET_MEM                       SetMem;
+  EFI_CREATE_EVENT_EX               CreateEventEx;
+} EFI_BOOT_SERVICES;
+
+///
+/// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the
+/// EFI System Table.
+///
+typedef struct {
+  ///
+  /// The 128-bit GUID value that uniquely identifies the system configuration table.
+  ///
+  EFI_GUID                          VendorGuid;
+  ///
+  /// A pointer to the table associated with VendorGuid.
+  ///
+  VOID                              *VendorTable;
+} EFI_CONFIGURATION_TABLE;
+
+///
+/// EFI System Table
+///
+typedef struct {
+  ///
+  /// The table header for the EFI System Table.
+  ///
+  EFI_TABLE_HEADER                  Hdr;
+  ///
+  /// A pointer to a null terminated string that identifies the vendor
+  /// that produces the system firmware for the platform.
+  ///
+  CHAR16                            *FirmwareVendor;
+  ///
+  /// A firmware vendor specific value that identifies the revision
+  /// of the system firmware for the platform.
+  ///
+  UINT32                            FirmwareRevision;
+  ///
+  /// The handle for the active console input device. This handle must support
+  /// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+  ///
+  EFI_HANDLE                        ConsoleInHandle;
+  ///
+  /// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
+  /// associated with ConsoleInHandle.
+  ///
+  EFI_SIMPLE_TEXT_INPUT_PROTOCOL    *ConIn;
+  ///
+  /// The handle for the active console output device.
+  ///
+  EFI_HANDLE                        ConsoleOutHandle;
+  ///
+  /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+  /// that is associated with ConsoleOutHandle.
+  ///
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *ConOut;
+  ///
+  /// The handle for the active standard error console device.
+  /// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
+  ///
+  EFI_HANDLE                        StandardErrorHandle;
+  ///
+  /// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
+  /// that is associated with StandardErrorHandle.
+  ///
+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL   *StdErr;
+  ///
+  /// A pointer to the EFI Runtime Services Table.
+  ///
+  EFI_RUNTIME_SERVICES              *RuntimeServices;
+  ///
+  /// A pointer to the EFI Boot Services Table.
+  ///
+  EFI_BOOT_SERVICES                 *BootServices;
+  ///
+  /// The number of system configuration tables in the buffer ConfigurationTable.
+  ///
+  UINTN                             NumberOfTableEntries;
+  ///
+  /// A pointer to the system configuration tables.
+  /// The number of entries in the table is NumberOfTableEntries.
+  ///
+  EFI_CONFIGURATION_TABLE           *ConfigurationTable;
+} EFI_SYSTEM_TABLE;
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IMAGE_ENTRY_POINT)(
+  IN  EFI_HANDLE                   ImageHandle,
+  IN  EFI_SYSTEM_TABLE             *SystemTable
+  );
+
+//
+// EFI Load Option. This data structure describes format of UEFI boot option variables.
+//
+// NOTE: EFI Load Option is a byte packed buffer of variable length fields.
+// The first two fields have fixed length. They are declared as members of the
+// EFI_LOAD_OPTION structure. All the other fields are variable length fields.
+// They are listed in the comment block below for reference purposes.
+//
+#pragma pack(1)
+typedef struct _EFI_LOAD_OPTION {
+  ///
+  /// The attributes for this load option entry. All unused bits must be zero
+  /// and are reserved by the UEFI specification for future growth.
+  ///
+  UINT32                           Attributes;
+  ///
+  /// Length in bytes of the FilePathList. OptionalData starts at offset
+  /// sizeof(UINT32) + sizeof(UINT16) + StrSize(Description) + FilePathListLength
+  /// of the EFI_LOAD_OPTION descriptor.
+  ///
+  UINT16                           FilePathListLength;
+  ///
+  /// The user readable description for the load option.
+  /// This field ends with a Null character.
+  ///
+  // CHAR16                        Description[];
+  ///
+  /// A packed array of UEFI device paths. The first element of the array is a
+  /// device path that describes the device and location of the Image for this
+  /// load option. The FilePathList[0] is specific to the device type. Other
+  /// device paths may optionally exist in the FilePathList, but their usage is
+  /// OSV specific. Each element in the array is variable length, and ends at
+  /// the device path end structure. Because the size of Description is
+  /// arbitrary, this data structure is not guaranteed to be aligned on a
+  /// natural boundary. This data structure may have to be copied to an aligned
+  /// natural boundary before it is used.
+  ///
+  // EFI_DEVICE_PATH_PROTOCOL      FilePathList[];
+  ///
+  /// The remaining bytes in the load option descriptor are a binary data buffer
+  /// that is passed to the loaded image. If the field is zero bytes long, a
+  /// NULL pointer is passed to the loaded image. The number of bytes in
+  /// OptionalData can be computed by subtracting the starting offset of
+  /// OptionalData from total size in bytes of the EFI_LOAD_OPTION.
+  ///
+  // UINT8                         OptionalData[];
+} EFI_LOAD_OPTION;
+#pragma pack()
+
+//
+// EFI Load Options Attributes
+//
+#define LOAD_OPTION_ACTIVE              0x00000001
+#define LOAD_OPTION_FORCE_RECONNECT     0x00000002
+#define LOAD_OPTION_HIDDEN              0x00000008
+#define LOAD_OPTION_CATEGORY            0x00001F00
+
+#define LOAD_OPTION_CATEGORY_BOOT       0x00000000
+#define LOAD_OPTION_CATEGORY_APP        0x00000100
+
+#define EFI_BOOT_OPTION_SUPPORT_KEY     0x00000001
+#define EFI_BOOT_OPTION_SUPPORT_APP     0x00000002
+#define EFI_BOOT_OPTION_SUPPORT_SYSPREP 0x00000010
+#define EFI_BOOT_OPTION_SUPPORT_COUNT   0x00000300
+
+///
+/// EFI Boot Key Data
+///
+typedef union {
+  struct {
+    ///
+    /// Indicates the revision of the EFI_KEY_OPTION structure. This revision level should be 0.
+    ///
+    UINT32  Revision        : 8;
+    ///
+    /// Either the left or right Shift keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  ShiftPressed    : 1;
+    ///
+    /// Either the left or right Control keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  ControlPressed  : 1;
+    ///
+    /// Either the left or right Alt keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  AltPressed      : 1;
+    ///
+    /// Either the left or right Logo keys must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  LogoPressed     : 1;
+    ///
+    /// The Menu key must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  MenuPressed     : 1;
+    ///
+    /// The SysReq key must be pressed (1) or must not be pressed (0).
+    ///
+    UINT32  SysReqPressed    : 1;
+    UINT32  Reserved        : 16;
+    ///
+    /// Specifies the actual number of entries in EFI_KEY_OPTION.Keys, from 0-3. If
+    /// zero, then only the shift state is considered. If more than one, then the boot option will
+    /// only be launched if all of the specified keys are pressed with the same shift state.
+    ///
+    UINT32  InputKeyCount   : 2;
+  } Options;
+  UINT32  PackedValue;
+} EFI_BOOT_KEY_DATA;
+
+///
+/// EFI Key Option.
+///
+#pragma pack(1)
+typedef struct {
+  ///
+  /// Specifies options about how the key will be processed.
+  ///
+  EFI_BOOT_KEY_DATA  KeyData;
+  ///
+  /// The CRC-32 which should match the CRC-32 of the entire EFI_LOAD_OPTION to
+  /// which BootOption refers. If the CRC-32s do not match this value, then this key
+  /// option is ignored.
+  ///
+  UINT32             BootOptionCrc;
+  ///
+  /// The Boot#### option which will be invoked if this key is pressed and the boot option
+  /// is active (LOAD_OPTION_ACTIVE is set).
+  ///
+  UINT16             BootOption;
+  ///
+  /// The key codes to compare against those returned by the
+  /// EFI_SIMPLE_TEXT_INPUT and EFI_SIMPLE_TEXT_INPUT_EX protocols.
+  /// The number of key codes (0-3) is specified by the EFI_KEY_CODE_COUNT field in KeyOptions.
+  ///
+  //EFI_INPUT_KEY      Keys[];
+} EFI_KEY_OPTION;
+#pragma pack()
+
+//
+// EFI File location to boot from on removable media devices
+//
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_IA32    L"\\EFI\\BOOT\\BOOTIA32.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_IA64    L"\\EFI\\BOOT\\BOOTIA64.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_X64     L"\\EFI\\BOOT\\BOOTX64.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_ARM     L"\\EFI\\BOOT\\BOOTARM.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64 L"\\EFI\\BOOT\\BOOTAA64.EFI"
+
+#if   defined (MDE_CPU_IA32)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_IA32
+#elif defined (MDE_CPU_IPF)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_IA64
+#elif defined (MDE_CPU_X64)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_X64
+#elif defined (MDE_CPU_EBC)
+#elif defined (MDE_CPU_ARM)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_ARM
+#elif defined (MDE_CPU_AARCH64)
+  #define EFI_REMOVABLE_MEDIA_FILE_NAME   EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64
+#else
+  #error Unknown Processor Type
+#endif
+
+#include <Uefi/UefiPxe.h>
+#include <Uefi/UefiGpt.h>
+#include <Uefi/UefiInternalFormRepresentation.h>
+
+#endif
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 1d92d74c42..3289172c49 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -32,6 +32,7 @@ SUBDIR= 802_11 \
 	dev_mkdb \
 	dntpd \
 	edquota \
+	efidp \
 	efisetup \
 	efivar \
 	faithd \
diff --git a/usr.sbin/efidp/Makefile b/usr.sbin/efidp/Makefile
new file mode 100644
index 0000000000..e53c6ceeb3
--- /dev/null
+++ b/usr.sbin/efidp/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD: head/usr.sbin/efidp/Makefile 314928 2017-03-09 00:33:38Z imp $
+
+PROG=	efidp
+MAN=	efidp.8
+
+LDADD=	-lefivar
+DPADD=	${LIBEFIVAR}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/efidp/efidp.8 b/usr.sbin/efidp/efidp.8
new file mode 100644
index 0000000000..1a9ff86c58
--- /dev/null
+++ b/usr.sbin/efidp/efidp.8
@@ -0,0 +1,56 @@
+.\" Copyright (c) 2017 Netflix, Inc
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: head/usr.sbin/efidp/efidp.8 318794 2017-05-24 17:47:49Z gjb $
+.\"
+.Dd May 31, 2017
+.Dt EFIDP 8
+.Os
+.Sh NAME
+.Nm efidp
+.Nd UEFI Device Path manipulation
+.Sh SYNOPSIS
+.Nm
+.Op Fl fp
+.Op Fl -parse
+.Op Fl -format
+.Sh DESCRIPTION
+This program manages
+.Dq Unified Extensible Firmware Interface
+.Pq UEFI
+Device Paths, as defined in the UEFI standard.
+.Sh SEE ALSO
+.Xr efivar 3 ,
+.Xr efivar 8
+.Pp
+Appendix A of the UEFI specification has the format for GUIDs.
+All GUIDs
+.Pq Dq Globally Unique Identifiers
+have the format described in RFC 4122.
+.El
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 11.1 .
diff --git a/usr.sbin/efidp/efidp.c b/usr.sbin/efidp/efidp.c
new file mode 100644
index 0000000000..c3a2b3d27e
--- /dev/null
+++ b/usr.sbin/efidp/efidp.c
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 2016 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: head/usr.sbin/efidp/efidp.c 314928 2017-03-09 00:33:38Z imp $");
+
+#include <efivar.h>
+#include <efivar-dp.h>
+#include <err.h>
+#include <getopt.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* options descriptor */
+static struct option longopts[] = {
+	{ "format",		no_argument,		NULL,	'f' },
+	{ "parse",		no_argument,		NULL,	'p' },
+	{ NULL,			0,			NULL,	0 }
+};
+
+
+static int flag_format, flag_parse;
+
+static void
+usage(void)
+{
+
+	errx(1, "efidp [-fp]");
+}
+
+static ssize_t
+read_file(int fd, void **rv)
+{
+	uint8_t *retval;
+	size_t len;
+	off_t off;
+	ssize_t red;
+
+	len = 4096;
+	off = 0;
+	retval = malloc(len);
+	do {
+		red = read(fd, retval + off, len - off);
+		off += red;
+		if (red < (ssize_t)(len - off))
+			break;
+		len *= 2;
+		retval = reallocf(retval, len);
+		if (retval == NULL)
+			return -1;
+	} while (1);
+	*rv = retval;
+
+	return off;
+}
+
+static void
+parse_args(int argc, char **argv)
+{
+	int ch;
+
+	while ((ch = getopt_long(argc, argv, "fp",
+		    longopts, NULL)) != -1) {
+		switch (ch) {
+		case 'f':
+			flag_format++;
+			break;
+		case 'p':
+			flag_parse++;
+			break;
+		default:
+			usage();
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	if (argc >= 1)
+		usage();
+
+	if (flag_parse + flag_format != 1) {
+		warnx("Can only use one of -p (--parse), "
+		    "and -f (--format)");
+		usage();
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	void *data;
+	ssize_t len;
+
+	parse_args(argc, argv);
+	len = read_file(STDIN_FILENO, &data);
+	if (len == -1)
+		err(1, "read");
+	if (flag_format) {
+		char buffer[4096];
+		ssize_t fmtlen;
+
+		fmtlen = efidp_format_device_path(buffer, sizeof(buffer),
+		    (const_efidp)data, len);
+		if (fmtlen > 0)
+			printf("%s\n", buffer);
+		free(data);
+	} else if (flag_parse) {
+		efidp dp;
+		ssize_t dplen;
+		char *str;
+
+		dp = malloc(8192);
+		str = realloc(data, len + 1);
+		if (str == NULL || dp == NULL)
+			errx(1, "Can't allocate memory.");
+		str[len] = '\0';
+		dplen = efidp_parse_device_path(str, dp, 8192);
+		if (dplen == -1)
+			errx(1, "Can't parse %s", str);
+		write(STDOUT_FILENO, dp, dplen);
+	}
+}
diff --git a/usr.sbin/efivar/efivar.8 b/usr.sbin/efivar/efivar.8
index 9087bae099..00b51558af 100644
--- a/usr.sbin/efivar/efivar.8
+++ b/usr.sbin/efivar/efivar.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2003 Netflix, Inc
+.\" Copyright (c) 2017 Netflix, Inc
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -22,14 +22,14 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: head/usr.sbin/efivar/efivar.8 307224 2016-10-13 17:03:54Z imp $
+.\" $FreeBSD: head/usr.sbin/efivar/efivar.8 318643 2017-05-22 13:55:59Z gjb $
 .\"
-.Dd September 29, 2016
+.Dd May 31, 2017
 .Dt EFIVAR 8
 .Os
 .Sh NAME
 .Nm efivar
-.Nd UEFI environemnt variable interaction
+.Nd UEFI environment variable interaction
 .Sh SYNOPSIS
 .Nm
 .Op Fl abdDHlLNpRtw
@@ -40,7 +40,9 @@
 .Op Fl -attributes
 .Op Fl -binary
 .Op Fl -delete
+.Op Fl -device-path
 .Op Fl -fromfile Ar file
+.Op Fl -guid
 .Op Fl -hex
 .Op Fl -list-guids
 .Op Fl -list
@@ -50,14 +52,13 @@
 .Op Fl -print-decimal
 .Op Fl -raw-guid
 .Op Fl -write
-.Ar name Ns Op = Ns Ar value
 .Sh DESCRIPTION
 This program manages
 .Dq Unified Extensible Firmware Interface
 .Pq UEFI
 environment variables.
 UEFI variables have three part: A namespace, a name and a value.
-The namespace is a GUID that's self assigned by the group defining the
+The namespace is a GUID that is self assigned by the group defining the
 variables.
 The name is a Unicode name for the variable.
 The value is binary data.
@@ -69,7 +70,7 @@ The following options are available:
 Specify the name of the variable to operate on.
 The
 .Ar name
-argument is the GUID of variable, followed by a dash, followed by the
+argument is the GUID of the variable, followed by a dash, followed by the
 UEFI variable name.
 The GUID may be in numeric format, or may be one of the well known
 symbolic name (see
@@ -85,12 +86,12 @@ This flag implies
 unless the
 .Fl -append
 flag is given.
-This is not well understood and currently unimplemented.
+This behavior is not well understood and is currently unimplemented.
 .It Fl a Fl -append
 Append the specified value to the UEFI variable rather than replacing
 it.
 .It Fl t Ar attr Fl -attributes Ar attr
-Specify, in user hostile hexidecimal, the attributes for this
+Specify, in hexadecimal, the attributes for this
 variable.
 See section 7.2 (GetVariable subsection, Related Definitions) of the
 UEFI Specification for hex values to use.
@@ -116,6 +117,13 @@ flags.
 No
 .Ar value
 may be specified.
+.It Fl d Fl -device Fl -device-path
+Interpret the variables printed as UEFI device paths and print the
+UEFI standard string representation.
+.It Fl g Fl -guid
+If the flag is specified, guids are converted to names if they are known (and
+show up in
+.Fl -list-guids ).
 .It Fl H Fl -hex
 List variable data as a hex dump.
 .It Fl L Fl -list-guids
@@ -133,34 +141,46 @@ flag is also listed, their values will be displayed.
 Do not display the variable name.
 .It Fl p Fl -print
 Print the value of the variable.
-.It Fl d Fl -print-decimal
-Treat the value of the variable as a number and print it as a
-decimal.
-This is currently unimplemented.
 .It Fl R Fl -raw-guid
 Do not substitute well known names for GUID numeric values in output.
 .It Fl w Fl -write
-Write (replace) the variable specified with the value specified.
+Write (replace) the variable specified with the value specified from
+standard input.
+No command line option to do this is available since UEFI variables
+are binary structures rather than strings.
+.Xr echo 1
+.Fl n
+can be used to specify simple strings.
 .It Ar name
 Display the
 .Ar name
 environment variable.
-.It Ar name Ns = Ns Ar value
-Set the specified
-.Ar name
-to
-.Ar value .
-This is not yet implemented.
 .El
 .Sh COMPATIBILITY
 The
 .Nm
 program is intended to be compatible (strict superset) with a program
-of the same name included in the Red Hat libefivar package.
+of the same name included in the Red Hat libefivar package,
+but the
+.Fl d
+and
+.Fl -print-decimal
+flags are not implemented and never will be.
+.Pp
+The
+.Fl d
+flag is short for
+.Fl -device-path .
 .Sh SEE ALSO
-.Xr efivar 3
+.Xr efivar 3 ,
+.Xr efidp 8
 .Pp
 Appendix A of the UEFI specification has the format for GUIDs.
 All GUIDs
 .Pq Dq Globally Unique Identifiers
 have the format described in RFC 4122.
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 11.1 .
diff --git a/usr.sbin/efivar/efivar.c b/usr.sbin/efivar/efivar.c
index 5c62564087..40db6086e6 100644
--- a/usr.sbin/efivar/efivar.c
+++ b/usr.sbin/efivar/efivar.c
@@ -25,10 +25,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/usr.sbin/efivar/efivar.c 307390 2016-10-16 05:53:18Z imp $");
+__FBSDID("$FreeBSD: head/usr.sbin/efivar/efivar.c 314927 2017-03-09 00:31:36Z imp $");
 
 #include <ctype.h>
 #include <efivar.h>
+#include <efivar-dp.h>
 #include <err.h>
 #include <errno.h>
 #include <getopt.h>
@@ -45,7 +46,10 @@ static struct option longopts[] = {
 	{ "attributes",		required_argument,	NULL,	't' },
 	{ "binary",		no_argument,		NULL,	'b' },
 	{ "delete",		no_argument,		NULL,   'D' },
+	{ "device",		no_argument,		NULL,   'd' },
+	{ "device-path",	no_argument,		NULL,   'd' },
 	{ "fromfile",		required_argument,	NULL,	'f' },
+	{ "guid",		no_argument,		NULL,	'g' },
 	{ "hex",		no_argument,		NULL,	'H' },
 	{ "list-guids",		no_argument,		NULL,	'L' },
 	{ "list",		no_argument,		NULL,	'l' },
@@ -59,7 +63,7 @@ static struct option longopts[] = {
 };
 
 
-static int aflag, Aflag, bflag, dflag, Dflag, Hflag, Nflag,
+static int aflag, Aflag, bflag, dflag, Dflag, gflag, Hflag, Nflag,
 	lflag, Lflag, Rflag, wflag, pflag;
 static char *varname;
 static u_long attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
@@ -84,7 +88,7 @@ breakdown_name(char *name, efi_guid_t *guid, char **vname)
 		errx(1, "Invalid name: %s", name);
 	*vname = cp + 1;
 	*cp = '\0';
-	if (efi_str_to_guid(name, guid) < 0)
+	if (efi_name_to_guid(name, guid) < 0)
 		errx(1, "Invalid guid %s", name);
 }
 
@@ -196,6 +200,32 @@ bindump(uint8_t *data, size_t datalen)
 }
 
 static void
+devpath_dump(uint8_t *data, size_t datalen)
+{
+	char buffer[1024];
+
+	efidp_format_device_path(buffer, sizeof(buffer),
+	    (const_efidp)data, datalen);
+	if (!Nflag)
+		printf(": ");
+	printf("%s\n", buffer);
+}
+
+static void
+pretty_guid(efi_guid_t *guid, char **gname)
+{
+	char *pretty = NULL;
+
+	if (gflag)
+		efi_guid_to_name(guid, &pretty);
+
+	if (pretty == NULL)
+		efi_guid_to_str(guid, gname);
+	else
+		*gname = pretty;
+}
+
+static void
 print_var(efi_guid_t *guid, char *name)
 {
 	uint32_t att;
@@ -204,22 +234,25 @@ print_var(efi_guid_t *guid, char *name)
 	char *gname;
 	int rv;
 
-	efi_guid_to_str(guid, &gname);
-	if (!Nflag)
-		printf("%s-%s", gname, name);
+	pretty_guid(guid, &gname);
 	if (pflag) {
 		rv = efi_get_variable(*guid, name, &data, &datalen, &att);
 
 		if (rv < 0)
-			printf("\n --- Error getting value --- %d", errno);
-		else {
-			if (Aflag)
-				asciidump(data, datalen);
-			else if (bflag)
-				bindump(data, datalen);
-			else
-				hexdump(data, datalen);
-		}
+			err(1, "%s-%s", gname, name);
+
+		if (!Nflag)
+			printf("%s-%s", gname, name);
+		if (Aflag)
+			asciidump(data, datalen);
+		else if (bflag)
+			bindump(data, datalen);
+		else if (dflag)
+			devpath_dump(data, datalen);
+		else
+			hexdump(data, datalen);
+	} else {
+		printf("%s-%s", gname, name);
 	}
 	free(gname);
 	if (!Nflag)
@@ -251,11 +284,22 @@ print_variables(void)
 }
 
 static void
+print_known_guid(void)
+{
+	struct uuid_table *tbl;
+	int i, n;
+
+	n = efi_known_guid(&tbl);
+	for (i = 0; i < n; i++)
+		printf("%s %s\n", tbl[i].uuid_str, tbl[i].name);
+}
+
+static void
 parse_args(int argc, char **argv)
 {
 	int ch, i;
 
-	while ((ch = getopt_long(argc, argv, "aAbdDf:HlLNn:pRt:w",
+	while ((ch = getopt_long(argc, argv, "aAbdDf:gHlLNn:pRt:w",
 		    longopts, NULL)) != -1) {
 		switch (ch) {
 		case 'a':
@@ -273,6 +317,9 @@ parse_args(int argc, char **argv)
 		case 'D':
 			Dflag++;
 			break;
+		case 'g':
+			gflag++;
+			break;
 		case 'H':
 			Hflag++;
 			break;
@@ -332,6 +379,8 @@ parse_args(int argc, char **argv)
 		delete_variable(varname);
 	else if (wflag)
 		write_variable(varname, NULL);
+	else if (Lflag)
+		print_known_guid();
 	else if (varname) {
 		pflag++;
 		print_variable(varname);
-- 
2.12.1

