hikey: Add UEFI sources for reference

UEFI needs to be built outside Android build system.
Please follow the instructions in README.

The sources correspond to:
https://github.com/96boards/edk2/commit/14eae0c12e71fd33c4c0fc51e4475e8db02566cf
https://github.com/96boards/arm-trusted-firmware/commit/e9b4909dcd75fc4ae7041cfb83d28ab9adb7afdf
https://github.com/96boards/l-loader/commit/6b784ad5c4ab00e2b1c6f53cd5f74054e5d00a78
https://git.linaro.org/uefi/uefi-tools.git/commit/abe618f8ab72034fff1ce46c9c006a2c6bd40a7e

Change-Id: Ieeefdb63e673e0c8e64e0a1f02c7bddc63b2c7fb
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/ArmCache.c b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/ArmCache.c
new file mode 100644
index 0000000..79c84a0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/ArmCache.c
@@ -0,0 +1,247 @@
+/** @file

+  Cache Maintenance Functions. These functions vary by ARM architecture so the MdePkg 

+  versions are null functions used to make sure things will compile. 

+

+  Copyright (c) 2006 - 2009, 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.

+

+**/

+

+//

+// Include common header file for this module.

+//

+#include <Base.h>

+#include <Library/DebugLib.h>

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+  ASSERT(FALSE);

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, then no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache 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

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  ASSERT(FALSE);

+  return Address;

+}

+

+/**

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes Back and Invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+  ASSERT(FALSE);

+}

+

+/**

+  Writes back and invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes back and invalidates the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, then no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  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 write back and invalidate from the

+                  data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  ASSERT(FALSE);

+  return Address;

+}

+

+/**

+  Writes back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+  ASSERT(FALSE);

+}

+

+/**

+  Writes back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, then no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. 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 write back from the data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  ASSERT(FALSE);

+  return Address;

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+  ASSERT(FALSE);

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, then no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache 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 data cache.

+

+  @return Address

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  ASSERT(FALSE);

+  return Address;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
new file mode 100644
index 0000000..298ba39
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
@@ -0,0 +1,61 @@
+## @file

+#  Instance of Cache Maintenance Library using Base Library services.

+#

+#  Cache Maintenance Library that uses Base Library services to maintain caches.

+#  This library assumes there are no chipset dependencies required to maintain caches.

+#

+#  Copyright (c) 2007 - 2014, 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseCacheMaintenanceLib

+  MODULE_UNI_FILE                = BaseCacheMaintenanceLib.uni

+  FILE_GUID                      = 123dd843-57c9-4158-8418-ce68b3944ce7

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = CacheMaintenanceLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64

+#

+

+[Sources.IA32]

+  X86Cache.c

+

+[Sources.X64]

+  X86Cache.c

+

+[Sources.IPF]

+  IpfCache.c

+

+[Sources.EBC]

+  EbcCache.c

+

+[Sources.ARM]

+  ArmCache.c

+

+[Sources.AARCH64]

+  ArmCache.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+

+[LibraryClasses.Ipf]

+  PalLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.uni
new file mode 100644
index 0000000..54f5e39
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/EbcCache.c b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/EbcCache.c
new file mode 100644
index 0000000..4740590
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/EbcCache.c
@@ -0,0 +1,231 @@
+/** @file

+  Cache Maintenance Functions.

+

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/DebugLib.h>

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, then no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache 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

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+}

+

+/**

+  Writes back and invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes Back and Invalidate the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, then no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  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 write back and invalidate from the

+                  data cache.

+

+  @return Address of cache invalidation.

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Writes back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+}

+

+/**

+  Writes back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, then no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. 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 write back from the data cache.

+

+  @return Address of cache written in main memory.

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, then no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache 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 data cache.

+

+  @return Address.

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return Address;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/IpfCache.c b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/IpfCache.c
new file mode 100644
index 0000000..24e9851
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/IpfCache.c
@@ -0,0 +1,242 @@
+/** @file

+  Cache Maintenance Functions.

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include <Base.h>

+#include <Library/CacheMaintenanceLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PalLib.h>

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+  PalCall (PAL_CACHE_FLUSH, PAL_CACHE_FLUSH_INSTRUCTION_ALL, PAL_CACHE_FLUSH_INVALIDATE_LINES | PAL_CACHE_FLUSH_NO_INTERRUPT, 0);

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, then no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache 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

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return AsmFlushCacheRange (Address, Length);

+}

+

+/**

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+  PalCall (PAL_CACHE_FLUSH, PAL_CACHE_FLUSH_DATA_ALL, PAL_CACHE_FLUSH_INVALIDATE_LINES | PAL_CACHE_FLUSH_NO_INTERRUPT, 0);

+}

+

+/**

+  Writes back and invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes back and invalidates the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, then no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  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 write back and invalidate from the

+                  data cache.

+

+  @return Address of cache invalidation.

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return AsmFlushCacheRange (Address, Length);

+}

+

+/**

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes Back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+  PalCall (PAL_CACHE_FLUSH, PAL_CACHE_FLUSH_DATA_ALL, PAL_CACHE_FLUSH_NO_INVALIDATE_LINES | PAL_CACHE_FLUSH_NO_INTERRUPT, 0);

+}

+

+/**

+  Writes Back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes Back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, then no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. 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 write back from the data cache.

+

+  @return Address of cache written in main memory.

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return AsmFlushCacheRange (Address, Length);

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+  //

+  // Invalidation of the entire data cache without writing back is not supported 

+  // on IPF architecture, so a write back and invalidate operation is performed.

+  //

+  WriteBackInvalidateDataCache ();

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, then no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache 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 data cache.

+

+  @return Address.

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Invalidation of a data cache range without writing back is not supported on

+  // IPF architecture, so write back and invalidate operation is performed.

+  //

+  return AsmFlushCacheRange (Address, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/X86Cache.c b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/X86Cache.c
new file mode 100644
index 0000000..5246893
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCacheMaintenanceLib/X86Cache.c
@@ -0,0 +1,266 @@
+/** @file

+  Cache Maintenance Functions.

+

+  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.

+

+

+**/

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+//

+// This size must be at or below the smallest cache size possible among all

+// supported processors

+//

+#define CACHE_LINE_SIZE             0x20

+

+/**

+  Invalidates the entire instruction cache in cache coherency domain of the

+  calling CPU.

+

+**/

+VOID

+EFIAPI

+InvalidateInstructionCache (

+  VOID

+  )

+{

+}

+

+/**

+  Invalidates a range of instruction cache lines in the cache coherency domain

+  of the calling CPU.

+

+  Invalidates the instruction cache lines specified by Address and Length. If

+  Address is not aligned on a cache line boundary, then entire instruction

+  cache line containing Address is invalidated. If Address + Length is not

+  aligned on a cache line boundary, then the entire instruction cache line

+  containing Address + Length -1 is invalidated. This function may choose to

+  invalidate the entire instruction cache if that is more efficient than

+  invalidating the specified range. If Length is 0, then no instruction cache

+  lines are invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the instruction cache 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

+InvalidateInstructionCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  if (Length == 0) {

+    return Address;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Address));

+  return Address;

+}

+

+/**

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU.

+

+  Writes back and invalidates the entire data cache in cache coherency domain

+  of the calling CPU. This function guarantees that all dirty cache lines are

+  written back to system memory, and also invalidates all the data cache lines

+  in the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackInvalidateDataCache (

+  VOID

+  )

+{

+  AsmWbinvd ();

+}

+

+/**

+  Writes back and invalidates a range of data cache lines in the cache

+  coherency domain of the calling CPU.

+

+  Writes back and invalidates the data cache lines specified by Address and

+  Length. If Address is not aligned on a cache line boundary, then entire data

+  cache line containing Address is written back and invalidated. If Address +

+  Length is not aligned on a cache line boundary, then the entire data cache

+  line containing Address + Length -1 is written back and invalidated. This

+  function may choose to write back and invalidate the entire data cache if

+  that is more efficient than writing back and invalidating the specified

+  range. If Length is 0, then no data cache lines are written back and

+  invalidated. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back and

+                  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 write back and invalidate from the

+                  data cache.

+

+  @return Address of cache invalidation.

+

+**/

+VOID *

+EFIAPI

+WriteBackInvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  UINTN                             Start;

+  UINTN                             End;

+

+  if (Length == 0) {

+    return Address;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Address));

+

+  Start = (UINTN)Address;

+  //

+  // Calculate the cache line alignment

+  // 

+  End = (Start + Length + (CACHE_LINE_SIZE - 1)) & ~(CACHE_LINE_SIZE - 1);

+  Start &= ~((UINTN) CACHE_LINE_SIZE - 1);

+

+  do {

+    Start = (UINTN)AsmFlushCacheLine ((VOID*)Start) + CACHE_LINE_SIZE;

+  } while (Start != End);

+  return Address;

+}

+

+/**

+  Writes back the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Writes back the entire data cache in cache coherency domain of the calling

+  CPU. This function guarantees that all dirty cache lines are written back to

+  system memory. This function may also invalidate all the data cache lines in

+  the cache coherency domain of the calling CPU.

+

+**/

+VOID

+EFIAPI

+WriteBackDataCache (

+  VOID

+  )

+{

+  WriteBackInvalidateDataCache ();

+}

+

+/**

+  Writes back a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Writes back the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is written back. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is written back. This function may choose to write back the entire

+  data cache if that is more efficient than writing back the specified range.

+  If Length is 0, then no data cache lines are written back. This function may

+  also invalidate all the data cache lines in the specified range of the cache

+  coherency domain of the calling CPU. Address is returned.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache lines to write back. 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 write back from the data cache.

+

+  @return Address of cache written in main memory.

+

+**/

+VOID *

+EFIAPI

+WriteBackDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  return WriteBackInvalidateDataCacheRange (Address, Length);

+}

+

+/**

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU.

+

+  Invalidates the entire data cache in cache coherency domain of the calling

+  CPU. This function must be used with care because dirty cache lines are not

+  written back to system memory. It is typically used for cache diagnostics. If

+  the CPU does not support invalidation of the entire data cache, then a write

+  back and invalidate operation should be performed on the entire data cache.

+

+**/

+VOID

+EFIAPI

+InvalidateDataCache (

+  VOID

+  )

+{

+  AsmInvd ();

+}

+

+/**

+  Invalidates a range of data cache lines in the cache coherency domain of the

+  calling CPU.

+

+  Invalidates the data cache lines specified by Address and Length. If Address

+  is not aligned on a cache line boundary, then entire data cache line

+  containing Address is invalidated. If Address + Length is not aligned on a

+  cache line boundary, then the entire data cache line containing Address +

+  Length -1 is invalidated. This function must never invalidate any cache lines

+  outside the specified range. If Length is 0, then no data cache lines are

+  invalidated. Address is returned. This function must be used with care

+  because dirty cache lines are not written back to system memory. It is

+  typically used for cache diagnostics. If the CPU does not support

+  invalidation of a data cache range, then a write back and invalidate

+  operation should be performed on the data cache range.

+

+  If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().

+

+  @param  Address The base address of the data cache 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 data cache.

+

+  @return Address.

+

+**/

+VOID *

+EFIAPI

+InvalidateDataCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Invalidation of a data cache range without writing back is not supported on

+  // x86 architecture, so write back and invalidate operation is performed.

+  //

+  return WriteBackInvalidateDataCacheRange (Address, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/AArch64/CpuFlushTlb.S b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/AArch64/CpuFlushTlb.S
new file mode 100644
index 0000000..8e12bdd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/AArch64/CpuFlushTlb.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# CpuFlushTlb() for ARM

+#

+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# Portions copyright (c) 2011 - 2013, 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

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+ASM_GLOBAL ASM_PFX(CpuFlushTlb)

+

+#/**

+#  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+#

+#  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+#

+#**/

+#VOID

+#EFIAPI

+#CpuFlushTlb (

+#  VOID

+#  )#

+#

+ASM_PFX(CpuFlushTlb):

+  tlbi  vmalle1                 // Invalidate Inst TLB and Data TLB

+  dsb   sy

+  isb

+  ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/AArch64/CpuSleep.S b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/AArch64/CpuSleep.S
new file mode 100644
index 0000000..86c3e63
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/AArch64/CpuSleep.S
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------

+#

+# CpuSleep() for AArch64

+#

+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# Portions copyright (c) 2011 - 2013, 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

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.align 3

+ASM_GLOBAL ASM_PFX(CpuSleep)

+

+#/**

+#  Places the CPU in a sleep state until an interrupt is received.

+#

+#  Places the CPU in a sleep state until an interrupt is received. If interrupts

+#  are disabled prior to calling this function, then the CPU will be placed in a

+#  sleep state indefinitely.

+#

+#**/

+#VOID

+#EFIAPI

+#CpuSleep (

+#  VOID

+#  );

+#

+

+ASM_PFX(CpuSleep):

+    wfi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuFlushTlb.S b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuFlushTlb.S
new file mode 100644
index 0000000..960fd99
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuFlushTlb.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------ 

+#

+# CpuFlushTlb() for ARM

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+GCC_ASM_EXPORT(CpuFlushTlb)

+

+#/**

+#  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+#

+#  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+#

+#**/

+#VOID

+#EFIAPI

+#CpuFlushTlb (

+#  VOID

+#  )#

+#

+ASM_PFX(CpuFlushTlb):

+    mov r0,#0

+    mcr p15,0,r0,c8,c5,0        // Invalidate all the unlocked entried in TLB

+    bx  LR

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuFlushTlb.asm b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuFlushTlb.asm
new file mode 100644
index 0000000..76313ab
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuFlushTlb.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ 

+;

+; CpuFlushTlb() for ARM

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+  EXPORT CpuFlushTlb

+  AREA cpu_flush_tlb, CODE, READONLY

+

+;/**

+;  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+;

+;  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+;

+;**/

+;VOID

+;EFIAPI

+;CpuFlushTlb (

+;  VOID

+;  );

+;

+CpuFlushTlb 

+    MOV r0,#0

+    MCR p15,0,r0,c8,c5,0        ;Invalidate all the unlocked entried in TLB

+    BX LR

+

+  END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuSleep.S b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuSleep.S
new file mode 100644
index 0000000..2c85930
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuSleep.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------ 

+#

+# CpuSleep() for ARMv7

+#

+# ARMv6 versions was:

+#    MOV r0,#0

+#    MCR p15,0,r0,c7,c0,4   ;Wait for Interrupt instruction

+#

+# But this is a no-op on ARMv7

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+GCC_ASM_EXPORT(CpuSleep)

+

+#/**

+#  Places the CPU in a sleep state until an interrupt is received.

+#

+#  Places the CPU in a sleep state until an interrupt is received. If interrupts

+#  are disabled prior to calling this function, then the CPU will be placed in a

+#  sleep state indefinitely.

+#

+#**/

+#VOID

+#EFIAPI

+#CpuSleep (

+#  VOID

+#  );

+#

+ASM_PFX(CpuSleep):

+    wfi

+    bx  lr

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuSleep.asm b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuSleep.asm
new file mode 100644
index 0000000..a51e2cd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Arm/CpuSleep.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------ 

+;

+; CpuSleep() for ARMv7

+;

+; ARMv6 versions was:

+;    MOV r0,#0

+;    MCR p15,0,r0,c7,c0,4   ;Wait for Interrupt instruction

+;

+; But this is a no-op on ARMv7

+;

+; Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+; Portions copyright (c) 2008 - 2011, 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.

+;

+;------------------------------------------------------------------------------

+

+  EXPORT CpuSleep

+  AREA cpu_sleep, CODE, READONLY

+

+;/**

+;  Places the CPU in a sleep state until an interrupt is received.

+;

+;  Places the CPU in a sleep state until an interrupt is received. If interrupts

+;  are disabled prior to calling this function, then the CPU will be placed in a

+;  sleep state indefinitely.

+;

+;**/

+;VOID

+;EFIAPI

+;CpuSleep (

+;  VOID

+;  );

+;

+CpuSleep

+    WFI

+    BX LR

+

+  END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
new file mode 100644
index 0000000..4e0f0a1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@@ -0,0 +1,76 @@
+## @file

+#  Instance of CPU Library for various architecture.

+#

+#  CPU Library implemented using ASM functions for IA-32 and X64,

+#  PAL CALLs for IPF, and empty functions for EBC.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#  Portions copyright (c) 2011 - 2013, 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

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseCpuLib

+  MODULE_UNI_FILE                = BaseCpuLib.uni

+  FILE_GUID                      = 4FBD2538-249C-4b50-8F4A-A9E66609CBF6

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = CpuLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64

+#

+

+[Sources.IA32]

+  Ia32/CpuSleep.c | MSFT 

+  Ia32/CpuFlushTlb.c | MSFT 

+

+  Ia32/CpuSleep.asm | INTEL 

+  Ia32/CpuFlushTlb.asm | INTEL 

+

+  Ia32/CpuSleepGcc.c | GCC 

+  Ia32/CpuFlushTlbGcc.c | GCC 

+

+[Sources.X64]

+  X64/CpuFlushTlb.asm 

+  X64/CpuSleep.asm

+

+  X64/CpuSleep.S | GCC 

+  X64/CpuFlushTlb.S | GCC 

+

+[Sources.IPF]

+  Ipf/CpuFlushTlb.s

+  Ipf/CpuSleep.c

+

+[Sources.EBC]

+  Ebc/CpuSleepFlushTlb.c

+

+[Sources.ARM]

+  Arm/CpuFlushTlb.asm | RVCT

+  Arm/CpuSleep.asm    | RVCT  

+  Arm/CpuFlushTlb.S   | GCC

+  Arm/CpuSleep.S      | GCC  

+

+[Sources.AARCH64]

+  AArch64/CpuFlushTlb.S | GCC

+  AArch64/CpuSleep.S    | GCC

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses.IPF]

+  PalLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.uni
new file mode 100644
index 0000000..aa4b398
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c
new file mode 100644
index 0000000..de63d63
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c
@@ -0,0 +1,46 @@
+/** @file

+  Base Library CPU Functions for EBC

+

+  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.

+

+**/

+#include <Base.h>

+#include <Library/DebugLib.h>

+

+/**

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+**/

+VOID

+EFIAPI

+CpuFlushTlb (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Places the CPU in a sleep state until an interrupt is received.

+

+  Places the CPU in a sleep state until an interrupt is received. If interrupts

+  are disabled prior to calling this function, then the CPU will be placed in a

+  sleep state indefinitely.

+

+**/

+VOID

+EFIAPI

+CpuSleep (

+  VOID

+  )

+{

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlb.asm b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlb.asm
new file mode 100644
index 0000000..271690d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlb.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuFlushTlb.Asm

+;

+; Abstract:

+;

+;   CpuFlushTlb function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuFlushTlb (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuFlushTlb PROC

+    mov     eax, cr3

+    mov     cr3, eax                    ; moving to CR3 flushes TLB

+    ret

+CpuFlushTlb ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlb.c b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlb.c
new file mode 100644
index 0000000..a95153e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlb.c
@@ -0,0 +1,34 @@
+/** @file

+  CpuFlushTlb function.

+

+  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.

+

+**/

+

+

+

+/**

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+**/

+VOID

+EFIAPI

+CpuFlushTlb (

+  VOID

+  )

+{

+  _asm {

+    mov     eax, cr3

+    mov     cr3, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlbGcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlbGcc.c
new file mode 100644
index 0000000..a8ebc38
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuFlushTlbGcc.c
@@ -0,0 +1,32 @@
+/** @file

+  CpuFlushTlb function for Ia32/X64 GCC.

+

+  Copyright (c) 2006 - 2008, 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.

+

+**/

+

+#include <Library/BaseLib.h>

+

+/**

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+  Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU.

+

+**/

+VOID

+EFIAPI

+CpuFlushTlb (

+  VOID

+  )

+{

+  AsmWriteCr3 (AsmReadCr3 ());

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleep.asm b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleep.asm
new file mode 100644
index 0000000..5bfd7b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleep.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuSleep.Asm

+;

+; Abstract:

+;

+;   CpuSleep function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuSleep (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuSleep    PROC

+    hlt

+    ret

+CpuSleep    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleep.c b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleep.c
new file mode 100644
index 0000000..3caf5d3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleep.c
@@ -0,0 +1,34 @@
+/** @file

+  CpuSleep function.

+

+  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.

+

+**/

+

+

+/**

+  Places the CPU in a sleep state until an interrupt is received.

+

+  Places the CPU in a sleep state until an interrupt is received. If interrupts

+  are disabled prior to calling this function, then the CPU will be placed in a

+  sleep state indefinitely.

+

+**/

+VOID

+EFIAPI

+CpuSleep (

+  VOID

+  )

+{

+  _asm {

+    hlt

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleepGcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleepGcc.c
new file mode 100644
index 0000000..eb71fa0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ia32/CpuSleepGcc.c
@@ -0,0 +1,33 @@
+/** @file

+  CpuSleep function for Ia32/X64 GCC.

+

+  Copyright (c) 2006 - 2008, 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.

+

+**/

+

+

+/**

+  Places the CPU in a sleep state until an interrupt is received.

+

+  Places the CPU in a sleep state until an interrupt is received. If interrupts

+  are disabled prior to calling this function, then the CPU will be placed in a

+  sleep state indefinitely.

+

+**/

+VOID

+EFIAPI

+CpuSleep (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("hlt"::: "memory");

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ipf/CpuFlushTlb.s b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ipf/CpuFlushTlb.s
new file mode 100644
index 0000000..911f780
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ipf/CpuFlushTlb.s
@@ -0,0 +1,58 @@
+/// @file

+///   CpuFlushTlb() function for Itanium-based architecture.

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name:  CpuFlushTlb.s

+///

+///

+

+.auto

+.text

+

+ASM_GLOBAL PalCall

+.type   PalCall, @function

+

+.proc   CpuFlushTlb

+.type   CpuFlushTlb, @function

+CpuFlushTlb::

+        alloc               loc0 = ar.pfs, 0, 3, 5, 0

+        mov                 out0 = 0

+        mov                 out1 = 6

+        mov                 out2 = 0

+        mov                 out3 = 0

+        mov                 loc1 = b0

+        mov                 out4 = 0

+        brl.call.sptk       b0  = PalCall

+        mov                 loc2 = psr              // save PSR

+        mov                 ar.pfs = loc0

+        extr.u              r14 = r10, 32, 32       // r14 <- count1

+        rsm                 1 << 14                 // Disable interrupts

+        extr.u              r15 = r11, 32, 32       // r15 <- stride1

+        extr.u              r10 = r10, 0, 32        // r10 <- count2

+        add                 r10 = -1, r10

+        extr.u              r11 = r11, 0, 32        // r11 <- stride2

+        br.cond.sptk        LoopPredicate

+LoopOuter:

+        mov                 ar.lc = r10             // LC <- count2

+        mov                 ar.ec = r0              // EC <- 0

+Loop:

+        ptc.e               r9

+        add                 r9 = r11, r9            // r9 += stride2

+        br.ctop.sptk        Loop

+        add                 r9 = r15, r9            // r9 += stride1

+LoopPredicate:

+        cmp.ne              p6 = r0, r14            // count1 == 0?

+        add                 r14 = -1, r14

+(p6)    br.cond.sptk        LoopOuter

+        mov                 psr.l = loc2

+        mov                 b0  = loc1

+        br.ret.sptk.many    b0

+.endp

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ipf/CpuSleep.c b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ipf/CpuSleep.c
new file mode 100644
index 0000000..59c07ca
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/Ipf/CpuSleep.c
@@ -0,0 +1,66 @@
+/** @file

+  Base Library CPU functions for Itanium

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include <Library/PalLib.h>

+#include <Library/BaseLib.h>

+

+/**

+  Places the CPU in a sleep state until an interrupt is received.

+

+  Places the CPU in a sleep state until an interrupt is received. If interrupts

+  are disabled prior to calling this function, then the CPU will be placed in a

+  sleep state indefinitely.

+

+**/

+VOID

+EFIAPI

+CpuSleep (

+  VOID

+  )

+{

+  UINT64  Tpr;

+

+  //

+  // It is the TPR register that controls if external interrupt would bring processor in LIGHT HALT low-power state

+  // back to normal state. PAL_HALT_LIGHT does not depend on PSR setting.

+  // So here if interrupts are disabled (via PSR.i), TRP.mmi needs to be set to prevent processor being interrupted by external interrupts.

+  // If interrupts are enabled, then just use current TRP setting.

+  //

+  if (GetInterruptState ()) {

+    //

+    // If interrupts are enabled, then call PAL_HALT_LIGHT with the current TPR setting.

+    //

+    PalCall (PAL_HALT_LIGHT, 0, 0, 0);

+  } else {

+    //

+    // If interrupts are disabled on entry, then mask all interrupts in TPR before calling PAL_HALT_LIGHT.

+    //

+

+    //

+    // Save TPR

+    //

+    Tpr = AsmReadTpr();

+    //

+    // Set TPR.mmi to mask all external interrupts

+    //

+    AsmWriteTpr (BIT16 | Tpr);

+

+    PalCall (PAL_HALT_LIGHT, 0, 0, 0);

+

+    //

+    // Restore TPR

+    //

+    AsmWriteTpr (Tpr);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuFlushTlb.S b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuFlushTlb.S
new file mode 100644
index 0000000..852ce14
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuFlushTlb.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------ 

+# 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.

+#

+# Module Name:

+#

+#   CpuFlushTlb.Asm

+#

+# Abstract:

+#

+#   CpuFlushTlb function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(CpuFlushTlb)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# CpuFlushTlb (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(CpuFlushTlb):

+    mov     %cr3, %rax

+    mov     %rax, %cr3

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuFlushTlb.asm b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuFlushTlb.asm
new file mode 100644
index 0000000..6a75287
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuFlushTlb.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuFlushTlb.Asm

+;

+; Abstract:

+;

+;   CpuFlushTlb function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuFlushTlb (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuFlushTlb PROC

+    mov     rax, cr3

+    mov     cr3, rax

+    ret

+CpuFlushTlb ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuSleep.S b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuSleep.S
new file mode 100644
index 0000000..cf76368
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuSleep.S
@@ -0,0 +1,34 @@
+#------------------------------------------------------------------------------ ;

+# 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.

+#

+# Module Name:

+#

+#   CpuSleep.S

+#

+# Abstract:

+#

+#   CpuSleep function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# CpuSleep (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(CpuSleep)

+ASM_PFX(CpuSleep):

+    hlt

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuSleep.asm b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuSleep.asm
new file mode 100644
index 0000000..196438f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseCpuLib/X64/CpuSleep.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuSleep.Asm

+;

+; Abstract:

+;

+;   CpuSleep function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuSleep (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuSleep    PROC

+    hlt

+    ret

+CpuSleep    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
new file mode 100644
index 0000000..a203e18
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
@@ -0,0 +1,36 @@
+## @file

+#  Debug Library with empty functions.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseDebugLibNull

+  MODULE_UNI_FILE                = BaseDebugLibNull.uni

+  FILE_GUID                      = 9ba1d976-0624-41a3-8650-28165e8d9ae8

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DebugLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.uni
new file mode 100644
index 0000000..cb5f433
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/DebugLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/DebugLib.c
new file mode 100644
index 0000000..e88b887
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibNull/DebugLib.c
@@ -0,0 +1,198 @@
+/** @file

+  Null Base Debug Library instance with empty functions.

+

+  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

+  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 <Base.h>

+#include <Library/DebugLib.h>

+

+/**

+  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      Format string for the debug message to print.

+  @param  ...         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

+  )

+{

+  return Buffer;

+}

+

+

+/**

+  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

+  )

+{

+  return FALSE;

+}

+

+

+/**  

+  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

+  )

+{

+  return FALSE;

+}

+

+

+/**  

+  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

+  )

+{

+  return FALSE;

+}

+

+

+/**  

+  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

+  )

+{

+  return FALSE;

+}

+

+/**

+  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

+  )

+{

+  return FALSE;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
new file mode 100644
index 0000000..823511b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
@@ -0,0 +1,49 @@
+## @file

+#  Instance of Debug Library based on Serial Port Library.

+#  It uses Print Library to produce formatted output strings to seiral port device.

+#

+#  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

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseDebugLibSerialPort

+  MODULE_UNI_FILE                = BaseDebugLibSerialPort.uni

+  FILE_GUID                      = BB83F95F-EDBC-4884-A520-CD42AF388FAE

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugLib 

+  CONSTRUCTOR                    = BaseDebugLibSerialPortConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DebugLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  SerialPortLib

+  BaseMemoryLib

+  PcdLib

+  PrintLib

+  BaseLib

+  DebugPrintErrorLevelLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue  ## SOMETIMES_CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask      ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.uni b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.uni
new file mode 100644
index 0000000..b5ae353
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/DebugLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/DebugLib.c
new file mode 100644
index 0000000..6fa235c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugLibSerialPort/DebugLib.c
@@ -0,0 +1,284 @@
+/** @file

+  Base Debug library instance base on Serial Port library.

+  It uses PrintLib to send debug messages to serial port device.

+  

+  NOTE: If the Serial Port library enables hardware flow control, then a call 

+  to DebugPrint() or DebugAssert() may hang if writes to the serial port are 

+  being blocked.  This may occur if a key(s) are pressed in a terminal emulator

+  used to monitor the DEBUG() and ASSERT() messages. 

+

+  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         

+  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 <Base.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PrintLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/SerialPortLib.h>

+#include <Library/DebugPrintErrorLevelLib.h>

+

+//

+// Define the maximum debug and assert message length that this library supports 

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+/**

+  The constructor function initialize the Serial Port Library

+

+  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.

+

+**/

+RETURN_STATUS

+EFIAPI

+BaseDebugLibSerialPortConstructor (

+  VOID

+  )

+{

+  return SerialPortInitialize ();

+}

+

+/**

+  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      Format string for the debug message to print.

+  @param  ...         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,

+  ...

+  )

+{

+  CHAR8    Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver debug mask value and global mask

+  //

+  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {

+    return;

+  }

+

+  //

+  // Convert the DEBUG() message to an ASCII String

+  //

+  VA_START (Marker, Format);

+  AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);

+  VA_END (Marker);

+

+  //

+  // Send the print string to a Serial Port 

+  //

+  SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));

+}

+

+

+/**

+  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

+  )

+{

+  CHAR8  Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Generate the ASSERT() message in Ascii format

+  //

+  AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description);

+

+  //

+  // Send the print string to the Console Output device

+  //

+  SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+  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

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

+

+/**

+  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

+  )

+{

+  return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.c
new file mode 100644
index 0000000..7af127f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.c
@@ -0,0 +1,59 @@
+/** @file

+  Debug Print Error Level library instance that retrieves the current error 

+  level from PcdDebugPrintErrorLevel.  This generic library instance does not 

+  support the setting of the global debug print error level mask for the platform.

+

+  Copyright (c) 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

+  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 <Base.h>

+#include <Library/DebugPrintErrorLevelLib.h>

+#include <Library/PcdLib.h>

+

+/**

+  Returns the debug print error level mask for the current module.

+

+  @return  Debug print error level mask for the current module.

+

+**/

+UINT32

+EFIAPI

+GetDebugPrintErrorLevel (

+  VOID

+  )

+{

+  //

+  // Retrieve the current debug print error level mask from PcdDebugPrintErrorLevel.

+  //

+  return PcdGet32 (PcdDebugPrintErrorLevel);

+}

+

+/**

+  Sets the global debug print error level mask fpr the entire platform.

+  

+  @param   ErrorLevel     Global debug print error level.

+  

+  @retval  TRUE           The debug print error level mask was sucessfully set.

+  @retval  FALSE          The debug print error level mask could not be set.

+

+**/

+BOOLEAN

+EFIAPI

+SetDebugPrintErrorLevel (

+  UINT32  ErrorLevel

+  )

+{

+  //

+  // This library uinstance does not support setting the global debug print error

+  // level mask.

+  //

+  return FALSE;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
new file mode 100644
index 0000000..7f611b0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
@@ -0,0 +1,40 @@
+## @file

+#  Debug Print Error Level library instance based on PcdDebugPrintErrorLevel.

+#  It retrieves the current error level from PcdDebugPrintErrorLevel.  

+#

+#  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseDebugPrintErrorLevelLib

+  MODULE_UNI_FILE                = BaseDebugPrintErrorLevelLib.uni

+  FILE_GUID                      = A2C09E18-E4D2-407e-AFCC-628B79113F72

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugPrintErrorLevelLib

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BaseDebugPrintErrorLevelLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PcdLib

+  

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.uni
new file mode 100644
index 0000000..37d45e5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.c
new file mode 100644
index 0000000..3a12cb1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.c
@@ -0,0 +1,484 @@
+/** @file

+  Provide generic extract guided section functions.

+

+  Copyright (c) 2007 - 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

+  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 <PiPei.h>

+

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/ExtractGuidedSectionLib.h>

+

+#define EXTRACT_HANDLER_INFO_SIGNATURE SIGNATURE_32 ('E', 'G', 'S', 'I')

+

+typedef struct {

+  UINT32                                  Signature;

+  UINT32                                  NumberOfExtractHandler;

+  GUID                                    *ExtractHandlerGuidTable;

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER   *ExtractDecodeHandlerTable;

+  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;

+} EXTRACT_GUIDED_SECTION_HANDLER_INFO;

+

+/**

+  HandlerInfo table address is set by PcdGuidedExtractHandlerTableAddress, which is used to store 

+  the registered guid and Handler list. When it is initialized, it will be directly returned. 

+  Or, HandlerInfo table will be initialized in this function.

+

+  @param[in, out]  InfoPointer   The pointer to the handler information structure.

+

+  @retval  RETURN_SUCCESS            HandlerInfo table can be used to store guid and function tables.

+  @retval  RETURN_OUT_OF_RESOURCES   HandlerInfo table address is not writable.

+**/

+RETURN_STATUS

+GetExtractGuidedSectionHandlerInfo (

+  IN OUT EXTRACT_GUIDED_SECTION_HANDLER_INFO **InfoPointer

+  )

+{

+  EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+  

+  //

+  // Set the available memory address to handler info.

+  //

+  HandlerInfo = (EXTRACT_GUIDED_SECTION_HANDLER_INFO*)(VOID*)(UINTN) PcdGet64 (PcdGuidedExtractHandlerTableAddress);

+  if (HandlerInfo == NULL) {

+    *InfoPointer = NULL;

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // First check whether the handler information structure is initialized.

+  //

+  if (HandlerInfo->Signature == EXTRACT_HANDLER_INFO_SIGNATURE) {

+    //

+    // The handler information has been initialized and is returned.

+    //

+    *InfoPointer = HandlerInfo;

+    return RETURN_SUCCESS;

+  }

+

+  //

+  // Try to initialize the handler information structure

+  //

+  HandlerInfo->Signature = EXTRACT_HANDLER_INFO_SIGNATURE;

+  if (HandlerInfo->Signature != EXTRACT_HANDLER_INFO_SIGNATURE) {

+    //

+    // The handler information structure was not writeable because the memory is not ready.

+    //

+    *InfoPointer = NULL;

+    return RETURN_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Init HandlerInfo structure

+  //

+  HandlerInfo->NumberOfExtractHandler     = 0;

+  HandlerInfo->ExtractHandlerGuidTable    = (GUID *) (HandlerInfo + 1);

+  HandlerInfo->ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (

+                                              (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + 

+                                              PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)

+                                             );

+  HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (

+                                              (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + 

+                                              PcdGet32 (PcdMaximumGuidedExtractHandler) * 

+                                              sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)

+                                             );

+  *InfoPointer = HandlerInfo;

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().

+

+  Sets ExtractHandlerGuidTable so it points at a callee allocated array of registered GUIDs.

+  The total number of GUIDs in the array are returned. Since the array of GUIDs is callee allocated

+  and caller must treat this array of GUIDs as read-only data. 

+  If ExtractHandlerGuidTable is NULL, then ASSERT().

+

+  @param[out]  ExtractHandlerGuidTable  A pointer to the array of GUIDs that have been registered through

+                                        ExtractGuidedSectionRegisterHandlers().

+

+  @return The number of the supported extract guided Handler.

+

+**/

+UINTN

+EFIAPI

+ExtractGuidedSectionGetGuidList (

+  OUT  GUID  **ExtractHandlerGuidTable

+  )

+{

+  RETURN_STATUS                       Status;

+  EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+

+  ASSERT (ExtractHandlerGuidTable != NULL);

+

+  //

+  // Get all registered handler information

+  //

+  Status = GetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (RETURN_ERROR (Status)) {

+    *ExtractHandlerGuidTable = NULL;

+    return 0;

+  }

+

+  //

+  // Get GuidTable and Table Number

+  //

+  ASSERT (HandlerInfo != NULL);

+  *ExtractHandlerGuidTable = HandlerInfo->ExtractHandlerGuidTable;

+  return HandlerInfo->NumberOfExtractHandler;

+}

+

+/**

+  Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER

+  for a specific GUID section type.

+

+  Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.

+  If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.

+  If there are not enough resources available to register the handlers  then RETURN_OUT_OF_RESOURCES is returned.

+  

+  If SectionGuid is NULL, then ASSERT().

+  If GetInfoHandler is NULL, then ASSERT().

+  If DecodeHandler is NULL, then ASSERT().

+

+  @param[in]  SectionGuid    A pointer to the GUID associated with the the handlers

+                             of the GUIDed section type being registered.

+  @param[in]  GetInfoHandler The pointer to a function that examines a GUIDed section and returns the

+                             size of the decoded buffer and the size of an optional scratch buffer

+                             required to actually decode the data in a GUIDed section.

+  @param[in]  DecodeHandler  The pointer to a function that decodes a GUIDed section into a caller

+                             allocated output buffer. 

+

+  @retval  RETURN_SUCCESS           The handlers were registered.

+  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to register the handlers.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionRegisterHandlers (

+  IN CONST  GUID                                     *SectionGuid,

+  IN        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  GetInfoHandler,

+  IN        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    DecodeHandler

+  )

+{

+  UINT32                              Index;

+  RETURN_STATUS                       Status;

+  EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+

+  //

+  // Check input paramter

+  //

+  ASSERT (SectionGuid != NULL);

+  ASSERT (GetInfoHandler != NULL);

+  ASSERT (DecodeHandler != NULL);

+

+  //

+  // Get the registered handler information

+  //

+  Status = GetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {

+      //

+      // If the guided handler has been registered before, only update its handler.

+      //

+      HandlerInfo->ExtractDecodeHandlerTable [Index] = DecodeHandler;

+      HandlerInfo->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;

+      return RETURN_SUCCESS;

+    }

+  }

+

+  //

+  // Check the global table is enough to contain new Handler.

+  //

+  if (HandlerInfo->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Register new Handler and guid value.

+  //

+  CopyGuid (HandlerInfo->ExtractHandlerGuidTable + HandlerInfo->NumberOfExtractHandler, SectionGuid);

+  HandlerInfo->ExtractDecodeHandlerTable [HandlerInfo->NumberOfExtractHandler] = DecodeHandler;

+  HandlerInfo->ExtractGetInfoHandlerTable [HandlerInfo->NumberOfExtractHandler++] = GetInfoHandler;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type

+  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().

+  The selected handler is used to retrieve and return the size of the decoded buffer and the size of an

+  optional scratch buffer required to actually decode the data in a GUIDed section.

+

+  Examines a GUIDed section specified by InputSection.  

+  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),

+  then RETURN_UNSUPPORTED is returned.  

+  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler 

+  of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()

+  is used to retrieve the OututBufferSize, ScratchSize, and Attributes values. The return status from the handler of

+  type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned.

+  

+  If InputSection is NULL, then ASSERT().

+  If OutputBufferSize is NULL, then ASSERT().

+  If ScratchBufferSize is NULL, then ASSERT().

+  If SectionAttribute is NULL, then ASSERT().

+

+  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.

+  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required if the buffer

+                                 specified by InputSection were decoded.

+  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space if the buffer specified by

+                                 InputSection were decoded.

+  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section.  See the Attributes field of

+                                 EFI_GUID_DEFINED_SECTION in the PI Specification.

+

+  @retval  RETURN_SUCCESS      Successfully retrieved the required information.

+  @retval  RETURN_UNSUPPORTED  The GUID from the section specified by InputSection does not match any of

+                               the GUIDs registered with ExtractGuidedSectionRegisterHandlers().

+  @retval  Others              The return status from the handler associated with the GUID retrieved from

+                               the section specified by InputSection.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionGetInfo (

+  IN  CONST VOID    *InputSection,

+  OUT       UINT32  *OutputBufferSize,

+  OUT       UINT32  *ScratchBufferSize,

+  OUT       UINT16  *SectionAttribute   

+  )

+{

+  UINT32                              Index;

+  RETURN_STATUS                       Status;

+  EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+  EFI_GUID                            *SectionDefinitionGuid;

+  

+  //

+  // Check input paramter

+  //

+  ASSERT (InputSection != NULL);

+  ASSERT (OutputBufferSize != NULL);

+  ASSERT (ScratchBufferSize != NULL);

+  ASSERT (SectionAttribute != NULL);

+

+  //

+  // Get all registered handler information.

+  //

+  Status = GetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  if (IS_SECTION2 (InputSection)) {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);

+  } else {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);

+  }

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {

+      //

+      // Call the match handler to get information for the input section data.

+      //

+      return HandlerInfo->ExtractGetInfoHandlerTable [Index] (

+                InputSection,

+                OutputBufferSize,

+                ScratchBufferSize,

+                SectionAttribute

+              );

+    }

+  }

+

+  //

+  // Not found, the input guided section is not supported. 

+  //

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().

+  The selected handler is used to decode the data in a GUIDed section and return the result in a caller

+  allocated output buffer.

+

+  Decodes the GUIDed section specified by InputSection.  

+  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),

+  then RETURN_UNSUPPORTED is returned.  

+  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler

+  of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()

+  is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this

+  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the data in InputSection,

+  then OutputBuffer is set to point at the data in InputSection.  Otherwise, the decoded data will be placed in a caller

+  allocated buffer specified by OutputBuffer.    This function is responsible for computing the  EFI_AUTH_STATUS_PLATFORM_OVERRIDE

+  bit of in AuthenticationStatus.  The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned. 

+   

+  If InputSection is NULL, then ASSERT().

+  If OutputBuffer is NULL, then ASSERT().

+  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().

+  If AuthenticationStatus is NULL, then ASSERT().  

+

+  @param[in]  InputSection   A pointer to a GUIDed section of an FFS formatted file.

+  @param[out] OutputBuffer   A pointer to a buffer that contains the result of a decode operation. 

+  @param[in]  ScratchBuffer  A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation. 

+  @param[out] AuthenticationStatus 

+                             A pointer to the authentication status of the decoded output buffer. See the definition

+                             of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI

+                             Specification.

+

+  @retval  RETURN_SUCCESS           The buffer specified by InputSection was decoded.

+  @retval  RETURN_UNSUPPORTED       The section specified by InputSection does not match the GUID this handler supports.

+  @retval  RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionDecode (

+  IN  CONST VOID    *InputSection,

+  OUT       VOID    **OutputBuffer,

+  IN        VOID    *ScratchBuffer,        OPTIONAL

+  OUT       UINT32  *AuthenticationStatus  

+  )

+{

+  UINT32                              Index;

+  RETURN_STATUS                       Status;

+  EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+  EFI_GUID                            *SectionDefinitionGuid;

+  

+  //

+  // Check input parameter

+  //

+  ASSERT (InputSection != NULL);

+  ASSERT (OutputBuffer != NULL);

+  ASSERT (AuthenticationStatus != NULL);

+

+  //

+  // Get all registered handler information.

+  //  

+  Status = GetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  if (IS_SECTION2 (InputSection)) {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);

+  } else {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);

+  }

+

+  //

+  // Search the match registered Extract handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {

+      //

+      // Call the match handler to extract raw data for the input guided section.

+      //

+      return HandlerInfo->ExtractDecodeHandlerTable [Index] (

+                InputSection,

+                OutputBuffer,

+                ScratchBuffer,

+                AuthenticationStatus

+              );

+    }

+  }

+

+  //

+  // Not found, the input guided section is not supported. 

+  //

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and 

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.

+  

+  Retrieves the handlers associated with SectionGuid and returns them in 

+  GetInfoHandler and DecodeHandler.

+

+  If the GUID value specified by SectionGuid has not been registered, then 

+  return RETURN_NOT_FOUND.

+  

+  If SectionGuid is NULL, then ASSERT().

+

+  @param[in]  SectionGuid    A pointer to the GUID associated with the handlersof the GUIDed 

+                             section type being retrieved.

+  @param[out] GetInfoHandler Pointer to a function that examines a GUIDed section and returns 

+                             the size of the decoded buffer and the size of an optional scratch 

+                             buffer required to actually decode the data in a GUIDed section.  

+                             This is an optional parameter that may be NULL. If it is NULL, then 

+                             the previously registered handler is not returned.

+  @param[out] DecodeHandler  Pointer to a function that decodes a GUIDed section into a caller

+                             allocated output buffer. This is an optional parameter that may be NULL.

+                             If it is NULL, then the previously registered handler is not returned.

+

+  @retval  RETURN_SUCCESS     The handlers were retrieved.

+  @retval  RETURN_NOT_FOUND   No handlers have been registered with the specified GUID.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionGetHandlers (

+  IN CONST   GUID                                     *SectionGuid,

+  OUT        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  *GetInfoHandler,  OPTIONAL

+  OUT        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    *DecodeHandler    OPTIONAL

+  )

+{

+  UINT32                              Index;

+  RETURN_STATUS                       Status;

+  EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+

+  //

+  // Check input paramter

+  //

+  ASSERT (SectionGuid != NULL);

+

+  //

+  // Get the registered handler information

+  //

+  Status = GetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {

+

+      //

+      // If the guided handler has been registered before, then return the registered handlers.

+      //

+      if (GetInfoHandler != NULL) {

+        *GetInfoHandler = HandlerInfo->ExtractGetInfoHandlerTable[Index];

+      }

+      if (DecodeHandler != NULL) {

+        *DecodeHandler = HandlerInfo->ExtractDecodeHandlerTable[Index];

+      }

+      return RETURN_SUCCESS;

+    }

+  }

+  return RETURN_NOT_FOUND;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
new file mode 100644
index 0000000..1bd245e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
@@ -0,0 +1,51 @@
+## @file

+#  Base ExtractGuidedSection Library.

+#  This instance can also be used in SEC phase only when the memory is ready in SEC phase.

+#  PCD PcdGuidedExtractHandlerTableAddress points to the available pysical memory space 

+#  that is used to store Guided Extract Handlers.

+#  Note: A driver of type DXE_RUNTIME_DRIVER can use this ExtractGuidedSectionLib 

+#  in their initialization without any issues. They only have to be careful in 

+#  the implementation of runtime services, because this BASE library instance doesn't 

+#  convert the address pointed by PcdGuidedExtractHandlerTableAddress to the virtual address.

+#  

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseExtractGuidedSectionLib

+  MODULE_UNI_FILE                = BaseExtractGuidedSectionLib.uni

+  FILE_GUID                      = 4e3236e9-d1c8-4c04-a89f-26f1c44b2592

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ExtractGuidedSectionLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  BaseExtractGuidedSectionLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseMemoryLib

+  DebugLib

+  PcdLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler         ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress    ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.uni
new file mode 100644
index 0000000..fde3a59
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
new file mode 100644
index 0000000..d9529eb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
@@ -0,0 +1,73 @@
+## @file

+#  Instance of I/O Library using compiler intrinsics.

+#

+#  I/O Library that uses compiler intrinsics to perform IN and OUT instructions

+#  for IA-32 and x64.  On IPF, I/O port requests are translated into MMIO requests.

+#  MMIO requests are forwarded directly to memory.

+#

+#  Copyright (c) 2007 - 2014, 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseIoLibIntrinsic

+  MODULE_UNI_FILE                = BaseIoLibIntrinsic.uni

+  FILE_GUID                      = 926c9cd0-4bb8-479b-9ac4-8a2a23f85307

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = IoLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF ARM AARCH64

+#

+

+[Sources]

+  IoLibMmioBuffer.c

+  BaseIoLibIntrinsicInternal.h

+  IoHighLevel.c

+

+[Sources.IA32]

+  IoLibGcc.c    | GCC

+  IoLibMsc.c    | MSFT

+  IoLibIcc.c    | INTEL

+  IoLib.c

+

+[Sources.X64]

+  IoLibGcc.c    | GCC

+  IoLibMsc.c    | MSFT

+  IoLibIcc.c    | INTEL

+  IoLib.c

+

+[Sources.IPF]

+  IoLibIpf.c

+

+[Sources.ARM]

+  IoLibArm.c

+

+[Sources.AARCH64]

+  IoLibArm.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

+[LibraryClasses.IPF]

+  PcdLib

+

+[Pcd.IPF]

+  gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf  ## SOMETIMES_CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.uni b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.uni
new file mode 100644
index 0000000..e16f12b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicInternal.h b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicInternal.h
new file mode 100644
index 0000000..52af5fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicInternal.h
@@ -0,0 +1,26 @@
+/** @file

+  Common header file shared by all source files.

+

+  This file includes package header files, dependent library classes.

+

+  Copyright (c) 2007 - 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 __BASEIOLIB_INTRINSIC_INTERNAL_H_

+#define __BASEIOLIB_INTRINSIC_INTERNAL_H_

+

+

+

+#include <Base.h>

+

+#include <Library/IoLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
new file mode 100644
index 0000000..ab1ddf4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoHighLevel.c
@@ -0,0 +1,2356 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  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.

+

+  The following IoLib instances contain the same copy of this file:

+

+    BaseIoLibIntrinsic

+    DxeIoLibCpuIo

+    PeiIoLibCpuIo

+

+**/

+

+#include "BaseIoLibIntrinsicInternal.h"

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) | OrData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) & AndData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) ((IoRead8 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. 

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra bits left in OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra bits left in AndData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, 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 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra bits left in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) | OrData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) & AndData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) ((IoRead16 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  bits left in Value are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra bits left in OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra bits left in AndData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, 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 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra bits left in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  bits left in Value are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra bits left in OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra bits left in AndData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, 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 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra bits left in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  bits left in Value are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra bits left in OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra bits left in AndData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, 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 I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra bits left in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) | OrData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) & AndData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) ((MmioRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra bits left in OrData

+  are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra bits left in AndData are

+  stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, 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 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra bits left in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) | OrData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) & AndData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) ((MmioRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra bits left in OrData

+  are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra bits left in AndData are

+  stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, 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 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra bits left in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra bits left in OrData

+  are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra bits left in AndData are

+  stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, 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 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra bits left in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra bits left in OrData

+  are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra bits left in AndData are

+  stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, 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 MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra bits left in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
new file mode 100644
index 0000000..f6bd819
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLib.c
@@ -0,0 +1,317 @@
+/** @file

+  Common I/O Library routines.

+

+  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.

+

+**/

+

+#include "BaseIoLibIntrinsicInternal.h"

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  UINT8                             Value;

+

+  MemoryFence ();

+  Value = *(volatile UINT8*)Address;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  MemoryFence ();

+  *(volatile UINT8*)Address = Value;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  UINT16                            Value;

+

+  ASSERT ((Address & 1) == 0);

+

+  MemoryFence ();

+  Value = *(volatile UINT16*)Address;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Address & 1) == 0);

+

+  MemoryFence ();

+  *(volatile UINT16*)Address = Value;

+  MemoryFence ();

+  

+  return Value;

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  UINT32                            Value;

+

+  ASSERT ((Address & 3) == 0);

+  

+  MemoryFence ();

+  Value = *(volatile UINT32*)Address;

+  MemoryFence ();

+  

+  return Value;

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Address & 3) == 0);

+  

+  MemoryFence ();

+  *(volatile UINT32*)Address = Value;

+  MemoryFence ();

+  

+  return Value;

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  UINT64                            Value;

+

+  ASSERT ((Address & 7) == 0);

+  

+  MemoryFence ();

+  Value = *(volatile UINT64*)Address;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT ((Address & 7) == 0);

+  

+  MemoryFence ();

+  *(volatile UINT64*)Address = Value;

+  MemoryFence ();

+  

+  return Value;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c
new file mode 100644
index 0000000..b9f4c5e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c
@@ -0,0 +1,430 @@
+/** @file

+  I/O Library for ARM. 

+

+  Copyright (c) 2006 - 2009, 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.

+

+**/

+

+

+//

+// Include common header file for this module.

+//

+#include "BaseIoLibIntrinsicInternal.h"

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT (FALSE);

+  return Value;

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT (FALSE);

+  return Value;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT (FALSE);

+  return Value;

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  UINT8                             Value;

+

+  Value = *(volatile UINT8*)Address;

+  return Value;

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  *(volatile UINT8*)Address = Value;

+  return Value;

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  UINT16                            Value;

+

+  ASSERT ((Address & 1) == 0);

+  Value = *(volatile UINT16*)Address;

+  return Value;

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Address & 1) == 0);

+  *(volatile UINT16*)Address = Value;

+  return Value;

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  UINT32                            Value;

+

+  ASSERT ((Address & 3) == 0);

+  Value = *(volatile UINT32*)Address;

+  return Value;

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Address & 3) == 0);

+  *(volatile UINT32*)Address = Value;

+  return Value;

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  UINT64                            Value;

+

+  ASSERT ((Address & 7) == 0);

+  Value = *(volatile UINT64*)Address;

+  return Value;

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT ((Address & 7) == 0);

+  *(volatile UINT64*)Address = Value;

+  return Value;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
new file mode 100644
index 0000000..40a9a8e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibGcc.c
@@ -0,0 +1,196 @@
+/** @file

+  I/O Library. This file has compiler specifics for GCC as there is no

+  ANSI C standard for doing IO.

+

+  GCC - uses EFIAPI assembler. __asm__ calls GAS. __volatile__ makes sure the

+  compiler puts the assembler in this exact location. The complex GNUC

+  operations are not optimzed. It would be possible to also write these

+  with EFIAPI assembler.

+

+  We don't advocate putting compiler specifics in libraries or drivers but there

+  is no other way to make this work.

+

+  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.

+

+**/

+

+

+#include "BaseIoLibIntrinsicInternal.h"

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+__inline__

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  UINT8   Data;

+

+  __asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));

+  return Data;

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+__inline__

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  __asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));

+  return Value;;

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+__inline__

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  UINT16   Data;

+

+  ASSERT ((Port & 1) == 0);

+  __asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));

+  return Data;

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+__inline__

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Port & 1) == 0);

+  __asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));

+  return Value;;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+__inline__

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  UINT32   Data;

+

+  ASSERT ((Port & 3) == 0);

+  __asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));

+  return Data;

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+__inline__

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Port & 3) == 0);

+  __asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));

+  return Value;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibIcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibIcc.c
new file mode 100644
index 0000000..87bc4cf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibIcc.c
@@ -0,0 +1,214 @@
+/** @file

+  I/O Library. This file has compiler specifics for ICC as there

+  is no ANSI C standard for doing IO.

+

+  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.

+

+**/

+

+#include "BaseIoLibIntrinsicInternal.h"

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  UINT8   Data;

+

+  __asm {

+    mov dx, word ptr [Port]

+    in  al, dx

+

+    mov Data, al

+  }

+  return Data;

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  __asm {

+    mov al, byte ptr [Value]

+    mov dx, word ptr [Port]

+    out dx, al

+  }

+  return Value; 

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  UINT16  Data;

+

+  ASSERT ((Port & 1) == 0);

+

+  __asm {

+    mov dx, word ptr [Port]

+    in  ax, dx

+    mov word ptr [Data], ax

+  }

+

+  return Data;

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Port & 1) == 0);

+

+  __asm {

+    mov ax, word ptr [Value]

+    mov dx, word ptr [Port]

+    out dx, ax

+  }

+

+  return Value;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  UINT32 Data;

+

+  ASSERT ((Port & 3) == 0);

+

+  __asm {

+    mov dx, word ptr [Port]

+    in  eax, dx

+    mov dword ptr [Data], eax

+  }

+  

+  return Data;

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Port & 3) == 0);

+  

+  __asm {

+    mov eax, dword ptr [Value]

+    mov dx, word ptr [Port]

+    out dx, eax

+  }

+

+  return Value;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibIpf.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibIpf.c
new file mode 100644
index 0000000..6b0bf6a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibIpf.c
@@ -0,0 +1,535 @@
+/** @file

+  Common I/O Library routines.

+

+  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.

+

+**/

+

+

+#include "BaseIoLibIntrinsicInternal.h"

+#include <Library/PcdLib.h>

+

+#define MAP_PORT_BASE_TO_MEM(_Port) \

+    ((((_Port) & 0xfffc) << 10) | ((_Port) & 0x0fff))

+

+/**

+  Translates I/O port address to memory address.

+

+  This function translates I/O port address to memory address by adding the 64MB

+  aligned I/O Port space to the I/O address.

+  If I/O Port space base is not 64MB aligned, then ASSERT ().  

+

+  @param  Port  The I/O port to read.

+

+  @return The memory address.

+

+**/

+UINTN

+InternalGetMemoryMapAddress (

+  IN UINTN                  Port

+  )

+{

+  UINTN                     Address;

+  UINTN                     IoBlockBaseAddress;

+

+  Address            = MAP_PORT_BASE_TO_MEM (Port);

+  IoBlockBaseAddress = PcdGet64(PcdIoBlockBaseAddressForIpf);

+

+  //

+  // Make sure that the I/O Port space base is 64MB aligned.

+  // 

+  ASSERT ((IoBlockBaseAddress & 0x3ffffff) == 0);

+  Address += IoBlockBaseAddress;

+

+  return Address;

+}

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  return MmioRead8 (InternalGetMemoryMapAddress (Port));

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  return MmioRead16 (InternalGetMemoryMapAddress (Port));

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  return MmioRead32 (InternalGetMemoryMapAddress (Port));

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (InternalGetMemoryMapAddress (Port), Value);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (InternalGetMemoryMapAddress (Port), Value);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (InternalGetMemoryMapAddress (Port), Value);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  UINT8            Data;

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  Data = *((volatile UINT8 *) Address);

+  MemoryFence ();

+

+  return Data;

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  UINT16           Data;

+

+  //

+  // Make sure that Address is 16-bit aligned.

+  // 

+  ASSERT ((Address & 1) == 0);

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  Data = *((volatile UINT16 *) Address);

+  MemoryFence ();

+

+  return Data;

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  UINT32           Data;

+

+  //

+  // Make sure that Address is 32-bit aligned.

+  // 

+  ASSERT ((Address & 3) == 0);

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  Data = *((volatile UINT32 *) Address);

+  MemoryFence ();

+

+  return Data;

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  UINT64           Data;

+

+  //

+  // Make sure that Address is 64-bit aligned.

+  // 

+  ASSERT ((Address & 7) == 0);

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  Data = *((volatile UINT64 *) Address);

+  MemoryFence ();

+

+  return Data;

+

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  Address |= BIT63;

+

+  MemoryFence ();

+  *((volatile UINT8 *) Address) = Value;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure that Address is 16-bit aligned.

+  // 

+  ASSERT ((Address & 1) == 0);

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  *((volatile UINT16 *) Address) = Value;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure that Address is 32-bit aligned.

+  // 

+  ASSERT ((Address & 3) == 0);

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  *((volatile UINT32 *) Address) = Value;

+  MemoryFence ();

+

+  return Value;

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure that Address is 64-bit aligned.

+  // 

+  ASSERT ((Address & 7) == 0);

+

+  Address |= BIT63;

+

+  MemoryFence ();

+  *((volatile UINT64 *) Address) = Value;

+  MemoryFence ();

+

+  return Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMmioBuffer.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMmioBuffer.c
new file mode 100644
index 0000000..f4aebfa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMmioBuffer.c
@@ -0,0 +1,411 @@
+/** @file

+  I/O Library MMIO Buffer Functions.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include "BaseIoLibIntrinsicInternal.h"

+

+/**

+  Copy data from the MMIO region to system memory by using 8-bit access.

+

+  Copy data from the MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 8-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioReadBuffer8 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT8       *Buffer

+  )

+{

+  UINT8   *ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length-- != 0) {

+    *(Buffer++) = MmioRead8 (StartAddress++);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from the MMIO region to system memory by using 16-bit access.

+

+  Copy data from the MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 16-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioReadBuffer16 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT16      *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length != 0) {

+    *(Buffer++) = MmioRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from the MMIO region to system memory by using 32-bit access.

+

+  Copy data from the MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 32-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioReadBuffer32 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT32      *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length != 0) {

+    *(Buffer++) = MmioRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from the MMIO region to system memory by using 64-bit access.

+

+  Copy data from the MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 64-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioReadBuffer64 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT64      *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length != 0) {

+    *(Buffer++) = MmioRead64 (StartAddress);

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to the MMIO region by using 8-bit access.

+

+  Copy data from system memory specified by Buffer to the MMIO region specified 

+  by starting address StartAddress by using 8-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioWriteBuffer8 (

+  IN  UINTN         StartAddress,

+  IN  UINTN         Length,

+  IN  CONST UINT8   *Buffer

+  )

+{

+  VOID* ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+ 

+  ReturnBuffer = (UINT8 *) Buffer;

+  

+  while (Length-- != 0) {

+     MmioWrite8 (StartAddress++, *(Buffer++));

+  }

+

+  return ReturnBuffer;

+ 

+}

+

+/**

+  Copy data from system memory to the MMIO region by using 16-bit access.

+

+  Copy data from system memory specified by Buffer to the MMIO region specified 

+  by starting address StartAddress by using 16-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioWriteBuffer16 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT16 *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = (UINT16 *) Buffer;

+  

+  while (Length != 0) {

+    MmioWrite16 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to the MMIO region by using 32-bit access.

+

+  Copy data from system memory specified by Buffer to the MMIO region specified 

+  by starting address StartAddress by using 32-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioWriteBuffer32 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT32 *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = (UINT32 *) Buffer;

+  

+  while (Length != 0) {

+    MmioWrite32 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to the MMIO region by using 64-bit access.

+

+  Copy data from system memory specified by Buffer to the MMIO region specified 

+  by starting address StartAddress by using 64-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioWriteBuffer64 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT64 *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = (UINT64 *) Buffer;

+  

+  while (Length != 0) {

+    MmioWrite64 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
new file mode 100644
index 0000000..83bad5e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseIoLibIntrinsic/IoLibMsc.c
@@ -0,0 +1,228 @@
+/** @file

+  I/O Library. This file has compiler specifics for Microsft C as there is no

+  ANSI C standard for doing IO.

+

+  MSC - uses intrinsic functions and the optimize will remove the function call

+  overhead.

+

+  We don't advocate putting compiler specifics in libraries or drivers but there

+  is no other way to make this work.

+

+  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.

+

+**/

+

+

+

+#include "BaseIoLibIntrinsicInternal.h"

+

+//

+// Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+//

+

+int            _inp (unsigned short port);

+unsigned short _inpw (unsigned short port);

+unsigned long  _inpd (unsigned short port);

+int            _outp (unsigned short port, int databyte );

+unsigned short _outpw (unsigned short port, unsigned short dataword );

+unsigned long  _outpd (unsigned short port, unsigned long dataword );

+void          _ReadWriteBarrier (void);

+

+#pragma intrinsic(_inp)

+#pragma intrinsic(_inpw)

+#pragma intrinsic(_inpd)

+#pragma intrinsic(_outp)

+#pragma intrinsic(_outpw)

+#pragma intrinsic(_outpd)

+#pragma intrinsic(_ReadWriteBarrier)

+

+//

+// _ReadWriteBarrier() forces memory reads and writes to complete at the point

+// in the call. This is only a hint to the compiler and does emit code.

+// In past versions of the compiler, _ReadWriteBarrier was enforced only

+// locally and did not affect functions up the call tree. In Visual C++

+// 2005, _ReadWriteBarrier is enforced all the way up the call tree.

+//

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  UINT8                             Value;

+

+  _ReadWriteBarrier ();

+  Value = (UINT8)_inp ((UINT16)Port);

+  _ReadWriteBarrier ();

+  return Value;

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  _ReadWriteBarrier ();

+  (UINT8)_outp ((UINT16)Port, Value);

+  _ReadWriteBarrier ();

+  return Value;

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  UINT16                            Value;

+

+  ASSERT ((Port & 1) == 0);

+  _ReadWriteBarrier ();

+  Value = _inpw ((UINT16)Port);

+  _ReadWriteBarrier ();

+  return Value;

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT ((Port & 1) == 0);

+  _ReadWriteBarrier ();

+  _outpw ((UINT16)Port, Value);

+  _ReadWriteBarrier ();

+  return Value;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  UINT32                            Value;

+

+  ASSERT ((Port & 3) == 0);

+  _ReadWriteBarrier ();

+  Value = _inpd ((UINT16)Port);

+  _ReadWriteBarrier ();

+  return Value;

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT ((Port & 3) == 0);

+  _ReadWriteBarrier ();

+  _outpd ((UINT16)Port, Value);

+  _ReadWriteBarrier ();

+  return Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S
new file mode 100644
index 0000000..fe8c571
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S
@@ -0,0 +1,37 @@
+#------------------------------------------------------------------------------

+#

+# CpuBreakpoint() for AArch64

+#

+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# Portions copyright (c) 2011 - 2013, 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

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+ASM_GLOBAL ASM_PFX(CpuBreakpoint)

+

+#/**

+#  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

+#  );

+#

+ASM_PFX(CpuBreakpoint):

+    svc   0xdbdb    // Superviser exception. Takes 16bit arg -> Armv7 had 'swi' here.

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S
new file mode 100644
index 0000000..b80a7b4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S
@@ -0,0 +1,34 @@
+#------------------------------------------------------------------------------

+#

+# DisableInterrupts() for AArch64

+#

+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# Portions copyright (c) 2011 - 2013, 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

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+ASM_GLOBAL ASM_PFX(DisableInterrupts)

+

+#/**

+#  Disables CPU interrupts.

+#

+#**/

+#VOID

+#EFIAPI

+#DisableInterrupts (

+#  VOID

+#  );

+#

+ASM_PFX(DisableInterrupts):

+   msr  daifset, #2

+   ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S
new file mode 100644
index 0000000..289739c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# EnableInterrupts() for AArch64

+#

+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# Portions copyright (c) 2011 - 2013, 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

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+ASM_GLOBAL ASM_PFX(EnableInterrupts)

+

+

+#/**

+#  Enables CPU interrupts.

+#

+#**/

+#VOID

+#EFIAPI

+#EnableInterrupts (

+#  VOID

+#  );

+#

+ASM_PFX(EnableInterrupts):

+    msr  daifclr, #2

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S
new file mode 100644
index 0000000..5a971f5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S
@@ -0,0 +1,45 @@
+#------------------------------------------------------------------------------

+#

+# GetInterruptState() function for AArch64

+#

+# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+# Portions copyright (c) 2011 - 2013, 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

+# 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+ASM_GLOBAL ASM_PFX(GetInterruptState)

+

+#/**

+#  Retrieves the current CPU interrupt state.

+#

+#  Returns TRUE is interrupts are currently enabled. Otherwise

+#  returns FALSE.

+#

+#  @retval TRUE  CPU interrupts are enabled.

+#  @retval FALSE CPU interrupts are disabled.

+#

+#**/

+#

+#BOOLEAN

+#EFIAPI

+#GetInterruptState (

+#  VOID

+# );

+#

+ASM_PFX(GetInterruptState):

+    mrs    x0, daif

+    tst    x0, #2            // Check if IRQ is enabled. Enabled if 0.

+    mov    w0, #0

+    mov    w1, #1

+    csel   w0, w1, w0, ne

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/MemoryFence.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/MemoryFence.S
new file mode 100644
index 0000000..5c69e08
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/MemoryFence.S
@@ -0,0 +1,39 @@
+##------------------------------------------------------------------------------

+#

+# MemoryFence() for AArch64

+#

+# Copyright (c) 2013, ARM Ltd. All rights reserved.

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php.

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##------------------------------------------------------------------------------

+

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(MemoryFence)

+

+

+#/**

+#  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

+#  );

+#

+ASM_PFX(MemoryFence):

+    // System wide Data Memory Barrier.

+    dmb sy

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S
new file mode 100644
index 0000000..dbc5adb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S
@@ -0,0 +1,97 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2009-2013, ARM Ltd.  All rights reserved.

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php.

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#------------------------------------------------------------------------------

+.text

+.p2align 3

+

+ASM_GLOBAL ASM_PFX(SetJump)

+ASM_GLOBAL ASM_PFX(InternalLongJump)

+

+#define GPR_LAYOUT                         \

+        REG_PAIR (x19, x20,  0);           \

+        REG_PAIR (x21, x22, 16);           \

+        REG_PAIR (x23, x24, 32);           \

+        REG_PAIR (x25, x26, 48);           \

+        REG_PAIR (x27, x28, 64);           \

+        REG_PAIR (x29, x30, 80);/*FP, LR*/ \

+        REG_ONE  (x16,      96) /*IP0*/

+

+#define FPR_LAYOUT                      \

+        REG_PAIR ( d8,  d9, 112);       \

+        REG_PAIR (d10, d11, 128);       \

+        REG_PAIR (d12, d13, 144);       \

+        REG_PAIR (d14, d15, 160);

+

+#/**

+#  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 IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+#

+#  @param  JumpBuffer    A pointer to CPU context buffer.

+#

+#**/

+#

+#UINTN

+#EFIAPI

+#SetJump (

+#  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer  // X0

+#  );

+#

+ASM_PFX(SetJump):

+        mov     x16, sp // use IP0 so save SP

+#define REG_PAIR(REG1, REG2, OFFS)      stp REG1, REG2, [x0, OFFS]

+#define REG_ONE(REG1, OFFS)             str REG1, [x0, OFFS]

+        GPR_LAYOUT

+        FPR_LAYOUT

+#undef REG_PAIR

+#undef REG_ONE

+        mov     w0, #0

+        ret

+

+#/**

+#  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.

+#

+#  @param  JumpBuffer    A pointer to CPU context buffer.

+#  @param  Value         The value to return when the SetJump() context is restored.

+#

+#**/

+#VOID

+#EFIAPI

+#InternalLongJump (

+#  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,  // X0

+#  IN      UINTN                     Value         // X1

+#  );

+#

+ASM_PFX(InternalLongJump):

+#define REG_PAIR(REG1, REG2, OFFS)      ldp REG1, REG2, [x0, OFFS]

+#define REG_ONE(REG1, OFFS)             ldr REG1, [x0, OFFS]

+        GPR_LAYOUT

+        FPR_LAYOUT

+#undef REG_PAIR

+#undef REG_ONE

+        mov     sp, x16

+        cmp     w1, #0

+        mov     w0, #1

+        csel    w0, w1, w0, ne

+        // use br not ret, as ret is guaranteed to mispredict

+        br      x30

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/SwitchStack.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/SwitchStack.S
new file mode 100644
index 0000000..207a569
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/AArch64/SwitchStack.S
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------

+//

+// Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+// Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+// Portions copyright (c) 2011 - 2013, ARM Limited. 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.

+//

+//------------------------------------------------------------------------------

+

+.text

+.align 5

+

+ASM_GLOBAL ASM_PFX(InternalSwitchStackAsm)

+ASM_GLOBAL ASM_PFX(CpuPause)

+

+/**

+//

+//  This allows the caller to switch the stack and goes to the new entry point

+//

+// @param      EntryPoint   The pointer to the location to enter

+// @param      Context      Parameter to pass in

+// @param      Context2     Parameter2 to pass in

+// @param      NewStack     New Location of the stack

+//

+// @return     Nothing. Goes to the Entry Point passing in the new parameters

+//

+VOID

+EFIAPI

+InternalSwitchStackAsm (

+  SWITCH_STACK_ENTRY_POINT EntryPoint,

+  VOID  *Context,

+  VOID  *Context2,

+  VOID  *NewStack

+  );

+**/

+ASM_PFX(InternalSwitchStackAsm):

+    mov   x30, x0

+    mov   sp, x3

+    mov   x0, x1

+    mov   x1, x2

+    ret

+

+/**

+//

+//  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

+  )

+**/

+ASM_PFX(CpuPause):

+    nop

+    nop

+    nop

+    nop

+    nop

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/ARShiftU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/ARShiftU64.c
new file mode 100644
index 0000000..6c799fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/ARShiftU64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  Shifts a 64-bit integer right between 0 and 63 bits. The high bits are filled

+  with the 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

+  )

+{

+  ASSERT (Count < 64);

+  return InternalMathARShiftU64 (Operand, Count);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuBreakpoint.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuBreakpoint.S
new file mode 100644
index 0000000..b6b80a1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuBreakpoint.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------ 

+#

+# CpuBreakpoint() for ARM

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+GCC_ASM_EXPORT(CpuBreakpoint)

+

+#/**

+#  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

+#  );

+#

+ASM_PFX(CpuBreakpoint):

+    swi  0xdbdbdb  

+    bx   lr

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuBreakpoint.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuBreakpoint.asm
new file mode 100644
index 0000000..8a80651
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuBreakpoint.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------ 

+;

+; CpuBreakpoint() for ARM

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+    EXPORT CpuBreakpoint

+

+  AREA Cpu_Breakpoint, CODE, READONLY

+

+;/**

+;  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

+;  );

+;

+CpuBreakpoint

+    swi   0xdbdbdb

+    bx    lr

+    

+  END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuPause.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuPause.asm
new file mode 100644
index 0000000..1956609
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/CpuPause.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------ 

+;

+; CpuPause() for ARM

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+  EXPORT CpuPause

+  AREA cpu_pause, CODE, READONLY

+

+;/**

+;  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

+;  );

+;

+CpuPause

+    NOP

+    NOP

+    NOP

+    NOP

+    NOP

+    BX LR

+

+  END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/DisableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/DisableInterrupts.S
new file mode 100644
index 0000000..e574086
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/DisableInterrupts.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------ 

+#

+# DisableInterrupts() for ARM

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+GCC_ASM_EXPORT(DisableInterrupts)

+

+#/**

+#  Disables CPU interrupts.

+#

+#**/

+#VOID

+#EFIAPI

+#DisableInterrupts (

+#  VOID

+#  );

+#

+ASM_PFX(DisableInterrupts):

+    mrs  R0,CPSR

+    orr  R0,R0,#0x80    @Disable IRQ interrupts

+    msr  CPSR_c,R0

+    bx   LR

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/DisableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/DisableInterrupts.asm
new file mode 100644
index 0000000..4fd8de4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/DisableInterrupts.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ 

+;

+; DisableInterrupts() for ARM

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+    EXPORT DisableInterrupts

+

+    AREA Interrupt_disable, CODE, READONLY

+

+;/**

+;  Disables CPU interrupts.

+;

+;**/

+;VOID

+;EFIAPI

+;DisableInterrupts (

+;  VOID

+;  );

+;

+DisableInterrupts

+    MRS     R0,CPSR

+    ORR     R0,R0,#0x80             ;Disable IRQ interrupts

+    MSR     CPSR_c,R0

+    BX      LR

+    

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/EnableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/EnableInterrupts.S
new file mode 100644
index 0000000..9f3a28a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/EnableInterrupts.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------ 

+#

+# EnableInterrupts() for ARM

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+GCC_ASM_EXPORT(EnableInterrupts)

+

+

+#/**

+#  Enables CPU interrupts.

+#

+#**/

+#VOID

+#EFIAPI

+#EnableInterrupts (

+#  VOID

+#  );

+#

+ASM_PFX(EnableInterrupts):

+    mrs  R0,CPSR

+    bic  R0,R0,#0x80    @Enable IRQ interrupts

+    msr  CPSR_c,R0

+    bx   LR

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/EnableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/EnableInterrupts.asm
new file mode 100644
index 0000000..e758224
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/EnableInterrupts.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ 

+;

+; EnableInterrupts() for ARM

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+    EXPORT EnableInterrupts

+

+    AREA Interrupt_enable, CODE, READONLY

+

+;/**

+;  Enables CPU interrupts.

+;

+;**/

+;VOID

+;EFIAPI

+;EnableInterrupts (

+;  VOID

+;  );

+;

+EnableInterrupts

+    MRS     R0,CPSR

+    BIC     R0,R0,#0x80             ;Enable IRQ interrupts

+    MSR     CPSR_c,R0

+    BX      LR

+    

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/GetInterruptsState.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/GetInterruptsState.S
new file mode 100644
index 0000000..94b3596
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/GetInterruptsState.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------ 

+#

+# GetInterruptState() function for ARM

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+

+.text

+.p2align 2

+GCC_ASM_EXPORT (GetInterruptState)

+

+#/**

+#  Retrieves the current CPU interrupt state.

+#

+#  Returns TRUE is interrupts are currently enabled. Otherwise

+#  returns FALSE.

+#

+#  @retval TRUE  CPU interrupts are enabled.

+#  @retval FALSE CPU interrupts are disabled.

+#

+#**/

+#

+#BOOLEAN

+#EFIAPI

+#GetInterruptState (

+#  VOID

+# );

+#

+ASM_PFX(GetInterruptState):

+    mrs    R0, CPSR

+    tst    R0, #0x80  @Check if IRQ is enabled.

+    moveq  R0, #1

+    movne  R0, #0

+    bx     LR

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/GetInterruptsState.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/GetInterruptsState.asm
new file mode 100644
index 0000000..1e2e49c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/GetInterruptsState.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------ 

+;

+; GetInterruptState() function for ARM

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+    EXPORT GetInterruptState

+

+    AREA Interrupt_enable, CODE, READONLY

+

+;/**

+;  Retrieves the current CPU interrupt state.

+;

+;  Returns TRUE is interrupts are currently enabled. Otherwise

+;  returns FALSE.

+;

+;  @retval TRUE  CPU interrupts are enabled.

+;  @retval FALSE CPU interrupts are disabled.

+;

+;**/

+;

+;BOOLEAN

+;EFIAPI

+;GetInterruptState (

+;  VOID

+; );

+;

+GetInterruptState

+    MRS     R0, CPSR

+    TST     R0, #0x80                ;Check if IRQ is enabled.

+    MOVEQ   R0, #1

+    MOVNE   R0, #0

+    BX      LR

+    

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/InternalSwitchStack.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/InternalSwitchStack.c
new file mode 100644
index 0000000..9f395bb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/InternalSwitchStack.c
@@ -0,0 +1,79 @@
+/** @file

+  SwitchStack() function for ARM.

+

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  Transfers control to a function starting with a new stack.

+

+  This internal worker function transfers control to the function

+  specified by EntryPoint using the new stack specified by NewStack,

+  and passes in the parameters specified by Context1 and Context2.

+  Context1 and Context2 are optional and may be NULL.

+  The function EntryPoint must never return.

+

+  @param EntryPoint   The pointer to the function to enter.

+  @param Context1     The first parameter to pass in.

+  @param Context2     The second Parameter to pass in

+  @param NewStack     The new Location of the stack

+

+**/

+VOID

+EFIAPI

+InternalSwitchStackAsm (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,   OPTIONAL

+  IN      VOID                      *Context2,   OPTIONAL

+  IN      VOID                      *NewStack

+  );

+

+  

+/**

+  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 passes in the parameters specified

+  by Context1 and Context2.  Context1 and Context2 are optional and may

+  be NULL.  The function EntryPoint must never return.

+  Marker will be ignored on IA-32, x64, and EBC.

+  IPF CPUs 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  Marker      A VA_LIST marker for the variable argument list.

+

+**/

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,   OPTIONAL

+  IN      VOID                      *Context2,   OPTIONAL

+  IN      VOID                      *NewStack,

+  IN      VA_LIST                   Marker

+  )

+

+{

+  InternalSwitchStackAsm (EntryPoint, Context1, Context2, NewStack);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/Math64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/Math64.S
new file mode 100755
index 0000000..4d97573
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/Math64.S
@@ -0,0 +1,277 @@
+#------------------------------------------------------------------------------ 

+#

+# Replacement for Math64.c that is coded to use older GCC intrinsics. 

+# Doing this reduces the number of intrinsics that are required when

+# you port to a new version of gcc. 

+#

+# Need to split this into multple files to size optimize the image.

+#

+# Copyright (c) 2009 - 2010, 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.

+#

+#------------------------------------------------------------------------------

+

+	.text

+	.align 2

+	GCC_ASM_EXPORT(InternalMathLShiftU64)

+

+ASM_PFX(InternalMathLShiftU64):

+	stmfd	sp!, {r4, r5, r6}

+	mov	r6, r1

+	rsb	ip, r2, #32

+	mov	r4, r6, asl r2

+	subs	r1, r2, #32

+	orr	r4, r4, r0, lsr ip

+	mov	r3, r0, asl r2

+	movpl	r4, r0, asl r1

+	mov	r5, r0

+	mov	r0, r3

+	mov	r1, r4

+	ldmfd	sp!, {r4, r5, r6}

+	bx	lr

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathRShiftU64)

+

+ASM_PFX(InternalMathRShiftU64):

+	stmfd	sp!, {r4, r5, r6}

+	mov	r5, r0

+	rsb	ip, r2, #32

+	mov	r3, r5, lsr r2

+	subs	r0, r2, #32

+	orr	r3, r3, r1, asl ip

+	mov	r4, r1, lsr r2

+	movpl	r3, r1, lsr r0

+	mov	r6, r1

+	mov	r0, r3

+	mov	r1, r4

+	ldmfd	sp!, {r4, r5, r6}

+	bx	lr

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathARShiftU64)

+

+ASM_PFX(InternalMathARShiftU64):

+	stmfd	sp!, {r4, r5, r6}

+	mov	r5, r0

+	rsb	ip, r2, #32

+	mov	r3, r5, lsr r2

+	subs	r0, r2, #32

+	orr	r3, r3, r1, asl ip

+	mov	r4, r1, asr r2

+	movpl	r3, r1, asr r0

+	mov	r6, r1

+	mov	r0, r3

+	mov	r1, r4

+	ldmfd	sp!, {r4, r5, r6}

+	bx	lr

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathLRotU64)

+

+ASM_PFX(InternalMathLRotU64):

+	stmfd	sp!, {r4, r5, r6, r7, lr}

+	add	r7, sp, #12

+	mov	r6, r1

+	rsb	ip, r2, #32

+	mov	r4, r6, asl r2

+	rsb	lr, r2, #64

+	subs	r1, r2, #32

+	orr	r4, r4, r0, lsr ip

+	mov	r3, r0, asl r2

+	movpl	r4, r0, asl r1

+	sub	ip, r2, #32

+	mov	r5, r0

+	mov	r0, r0, lsr lr

+	rsbs	r2, r2, #32

+	orr	r0, r0, r6, asl ip

+	mov	r1, r6, lsr lr

+	movpl	r0, r6, lsr r2

+	orr	r1, r1, r4

+	orr	r0, r0, r3

+	ldmfd	sp!, {r4, r5, r6, r7, pc}

+

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathRRotU64)

+

+ASM_PFX(InternalMathRRotU64):

+	stmfd	sp!, {r4, r5, r6, r7, lr}

+	add	r7, sp, #12

+	mov	r5, r0

+	rsb	ip, r2, #32

+	mov	r3, r5, lsr r2

+	rsb	lr, r2, #64

+	subs	r0, r2, #32

+	orr	r3, r3, r1, asl ip

+	mov	r4, r1, lsr r2

+	movpl	r3, r1, lsr r0

+	sub	ip, r2, #32

+	mov	r6, r1

+	mov	r1, r1, asl lr

+	rsbs	r2, r2, #32

+	orr	r1, r1, r5, lsr ip

+	mov	r0, r5, asl lr

+	movpl	r1, r5, asl r2

+	orr	r0, r0, r3

+	orr	r1, r1, r4

+	ldmfd	sp!, {r4, r5, r6, r7, pc}

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathMultU64x32)

+

+ASM_PFX(InternalMathMultU64x32):

+	stmfd	sp!, {r7, lr}

+	add	r7, sp, #0

+	mov	r3, #0

+	mov	ip, r0

+	mov	lr, r1

+	umull	r0, r1, ip, r2

+	mla	r1, lr, r2, r1

+	mla	r1, ip, r3, r1

+	ldmfd	sp!, {r7, pc}

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathMultU64x64)

+

+ASM_PFX(InternalMathMultU64x64):

+	stmfd	sp!, {r7, lr}

+	add	r7, sp, #0

+	mov	ip, r0

+	mov	lr, r1

+	umull	r0, r1, ip, r2

+	mla	r1, lr, r2, r1

+	mla	r1, ip, r3, r1

+	ldmfd	sp!, {r7, pc}

+

+	.align 2

+	GCC_ASM_EXPORT(InternalMathDivU64x32)

+

+ASM_PFX(InternalMathDivU64x32):

+	stmfd	sp!, {r7, lr}

+	add	r7, sp, #0

+	mov	r3, #0

+	bl 	ASM_PFX(__udivdi3)

+	ldmfd	sp!, {r7, pc}

+	

+	

+	.align 2

+	GCC_ASM_EXPORT(InternalMathModU64x32)

+

+ASM_PFX(InternalMathModU64x32):

+	stmfd	sp!, {r7, lr}

+	add	r7, sp, #0

+	mov	r3, #0

+	bl 	ASM_PFX(__umoddi3)

+	ldmfd	sp!, {r7, pc}

+	

+	

+	.align 2

+	GCC_ASM_EXPORT(InternalMathDivRemU64x32)

+

+ASM_PFX(InternalMathDivRemU64x32):

+	stmfd	sp!, {r4, r5, r6, r7, lr}

+	add	r7, sp, #12

+	stmfd	sp!, {r10, r11}

+	subs	r6, r3, #0

+	mov	r10, r0

+	mov	r11, r1

+	moveq	r4, r2

+	moveq	r5, #0

+	beq	L22

+	mov	r4, r2

+	mov	r5, #0

+	mov	r3, #0

+	bl 	ASM_PFX(__umoddi3)

+	str	r0, [r6, #0]

+L22:

+	mov	r0, r10

+	mov	r1, r11

+	mov	r2, r4

+	mov	r3, r5

+	bl 	ASM_PFX(__udivdi3)

+	ldmfd	sp!, {r10, r11}

+	ldmfd	sp!, {r4, r5, r6, r7, pc}

+	

+	

+	.align 2

+	GCC_ASM_EXPORT(InternalMathDivRemU64x64)

+

+ASM_PFX(InternalMathDivRemU64x64):

+	stmfd	sp!, {r4, r5, r6, r7, lr}

+	add	r7, sp, #12

+	stmfd	sp!, {r10, r11}

+	ldr	r6, [sp, #28]

+	mov	r4, r0

+	cmp	r6, #0

+	mov	r5, r1

+	mov	r10, r2

+	mov	r11, r3

+	beq	L26

+	bl 	ASM_PFX(__umoddi3)

+	stmia	r6, {r0-r1}

+L26:

+	mov	r0, r4

+	mov	r1, r5

+	mov	r2, r10

+	mov	r3, r11

+	bl 	ASM_PFX(__udivdi3)

+	ldmfd	sp!, {r10, r11}

+	ldmfd	sp!, {r4, r5, r6, r7, pc}

+	

+	

+	.align 2

+	GCC_ASM_EXPORT(InternalMathDivRemS64x64)

+

+ASM_PFX(InternalMathDivRemS64x64):

+	stmfd	sp!, {r4, r5, r6, r7, lr}

+	add	r7, sp, #12

+	stmfd	sp!, {r10, r11}

+	ldr	r6, [sp, #28]

+	mov	r4, r0

+	cmp	r6, #0

+	mov	r5, r1

+	mov	r10, r2

+	mov	r11, r3

+	beq	L30

+	bl 	ASM_PFX(__moddi3)

+	stmia	r6, {r0-r1}

+L30:

+	mov	r0, r4

+	mov	r1, r5

+	mov	r2, r10

+	mov	r3, r11

+	bl 	ASM_PFX(__divdi3)

+	ldmfd	sp!, {r10, r11}

+	ldmfd	sp!, {r4, r5, r6, r7, pc}

+	

+	

+	.align 2

+	GCC_ASM_EXPORT(InternalMathSwapBytes64)

+

+ASM_PFX(InternalMathSwapBytes64):

+	@ args = 0, pretend = 0, frame = 0

+	@ frame_needed = 1, uses_anonymous_args = 0

+	stmfd	sp!, {r4, r5, r6, r7, lr}

+	add	r7, sp, #12

+	mov	r5, r1

+	bl	ASM_PFX(SwapBytes32)

+	mov	r6, r0

+	mov	r0, r5

+	bl	ASM_PFX(SwapBytes32)

+	mov	r4, r6

+	mov	r5, r4, asr #31

+	mov	r2, #0

+	mov	r1, r0, asr #31

+	orr	r0, r0, r2

+	orr	r1, r1, r4

+	ldmfd	sp!, {r4, r5, r6, r7, pc}

+

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
\ No newline at end of file
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/MemoryFence.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/MemoryFence.S
new file mode 100644
index 0000000..a2284ba
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/MemoryFence.S
@@ -0,0 +1,39 @@
+##------------------------------------------------------------------------------

+#

+# MemoryFence() for AArch64

+#

+# Copyright (c) 2013, ARM Ltd. All rights reserved.

+#

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php.

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##------------------------------------------------------------------------------

+

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(MemoryFence)

+

+

+#/**

+#  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

+#  );

+#

+ASM_PFX(MemoryFence):

+    // System wide Data Memory Barrier.

+    dmb

+    bx   lr

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/MemoryFence.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/MemoryFence.asm
new file mode 100644
index 0000000..8f3d05f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/MemoryFence.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; MemoryFence() for AArch64

+;

+; Copyright (c) 2013, ARM Ltd. All rights reserved.

+;

+; This program and the accompanying materials

+; are licensed and made available under the terms and conditions of the BSD License

+; which accompanies this distribution.  The full text of the license may be found at

+; http://opensource.org/licenses/bsd-license.php.

+;

+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+;

+;------------------------------------------------------------------------------

+

+    EXPORT MemoryFence

+

+    AREA MemoryBarriers, CODE, READONLY

+

+;/**

+;  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

+;  );

+;

+MemoryFence FUNCTION

+    dmb

+    bx      lr

+    ENDFUNC

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SetJumpLongJump.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SetJumpLongJump.S
new file mode 100644
index 0000000..2ea8802
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SetJumpLongJump.S
@@ -0,0 +1,70 @@
+#------------------------------------------------------------------------------ 

+#

+# Copyright (c) 2006 - 2009, 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.

+#

+#------------------------------------------------------------------------------

+.text

+.p2align 2

+

+GCC_ASM_EXPORT(SetJump)

+GCC_ASM_EXPORT(InternalLongJump)

+

+#/**

+#  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 IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+#

+#  @param  JumpBuffer    A pointer to CPU context buffer.

+#

+#**/

+#

+#UINTN

+#EFIAPI

+#SetJump (

+#  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer  // R0

+#  );

+#

+ASM_PFX(SetJump):

+  mov   r3, r13

+  stmia r0, {r3-r12,r14}

+  eor   r0, r0, r0

+  bx    lr

+

+#/**

+#  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.

+#

+#  @param  JumpBuffer    A pointer to CPU context buffer.

+#  @param  Value         The value to return when the SetJump() context is restored.

+#

+#**/

+#VOID

+#EFIAPI

+#InternalLongJump (

+#  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,  // R0

+#  IN      UINTN                     Value         // R1

+#  );

+#

+ASM_PFX(InternalLongJump):

+  ldmia  r0, {r3-r12,r14}

+  mov    r13, r3

+  mov    r0, r1

+  bx     lr

+

+ASM_FUNCTION_REMOVE_IF_UNREFERENCED

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SetJumpLongJump.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SetJumpLongJump.asm
new file mode 100644
index 0000000..3346ee8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SetJumpLongJump.asm
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------ 

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+

+  EXPORT  SetJump

+  EXPORT  InternalLongJump

+

+  AREA  BaseLib, CODE, READONLY

+

+;/**

+;  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 IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+;

+;  @param  JumpBuffer    A pointer to CPU context buffer.

+;

+;**/

+;

+;UINTN

+;EFIAPI

+;SetJump (

+;  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer  // R0

+;  )

+;

+SetJump

+  MOV  R3, R13

+  STM  R0, {R3-R12,R14}

+  EOR  R0, R0

+  BX   LR

+

+;/**

+;  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.

+;

+;  @param  JumpBuffer    A pointer to CPU context buffer.

+;  @param  Value         The value to return when the SetJump() context is restored.

+;

+;**/

+;VOID

+;EFIAPI

+;InternalLongJump (

+;  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,  // R0

+;  IN      UINTN                     Value         // R1

+;  );

+;

+InternalLongJump

+  LDM   R0, {R3-R12,R14}

+  MOV   R13, R3

+  MOV   R0, R1

+  BX    LR

+

+  END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SwitchStack.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SwitchStack.S
new file mode 100644
index 0000000..2c15eb8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SwitchStack.S
@@ -0,0 +1,68 @@
+//------------------------------------------------------------------------------ 

+//

+// Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+// Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+// Portions copyright (c) 2011, ARM Limited. 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.

+//

+//------------------------------------------------------------------------------

+  

+.text

+.align 5

+

+GCC_ASM_EXPORT(InternalSwitchStackAsm)

+GCC_ASM_EXPORT(CpuPause)            

+  

+/**

+//

+//  This allows the caller to switch the stack and goes to the new entry point

+//

+// @param      EntryPoint   The pointer to the location to enter

+// @param      Context      Parameter to pass in

+// @param      Context2     Parameter2 to pass in

+// @param      NewStack     New Location of the stack

+//

+// @return     Nothing. Goes to the Entry Point passing in the new parameters

+//

+VOID

+EFIAPI

+InternalSwitchStackAsm (

+  SWITCH_STACK_ENTRY_POINT EntryPoint,

+  VOID  *Context,

+  VOID  *Context2,

+  VOID  *NewStack

+  );

+**/

+ASM_PFX(InternalSwitchStackAsm):

+    MOV   LR, R0

+    MOV   SP, R3

+    MOV   R0, R1

+    MOV   R1, R2

+    BX    LR

+

+/**

+//

+//  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

+  )

+**/

+ASM_PFX(CpuPause):

+    nop

+    nop

+    nop

+    nop

+    nop

+    BX    LR

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SwitchStack.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SwitchStack.asm
new file mode 100644
index 0000000..6517757
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/SwitchStack.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------ 

+;

+; Copyright (c) 2006 - 2009, 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.

+;

+;------------------------------------------------------------------------------

+  

+    EXPORT InternalSwitchStackAsm

+            

+    AREA   Switch_Stack, CODE, READONLY

+  

+;/**

+;  This allows the caller to switch the stack and goes to the new entry point

+;

+; @param      EntryPoint   The pointer to the location to enter

+; @param      Context      Parameter to pass in

+; @param      Context2     Parameter2 to pass in

+; @param      NewStack     New Location of the stack

+;

+; @return     Nothing. Goes to the Entry Point passing in the new parameters

+;

+;**/

+;VOID

+;EFIAPI

+;InternalSwitchStackAsm (

+;  SWITCH_STACK_ENTRY_POINT EntryPoint,

+;  VOID  *Context,

+;  VOID  *Context2,

+;  VOID  *NewStack

+;  );

+;

+InternalSwitchStackAsm

+    MOV   LR, R0

+    MOV   SP, R3

+    MOV   R0, R1

+    MOV   R1, R2

+    BX    LR

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/Unaligned.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/Unaligned.c
new file mode 100644
index 0000000..34f1732
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Arm/Unaligned.c
@@ -0,0 +1,252 @@
+/** @file

+  Unaligned access functions of BaseLib for ARM.

+  

+  volatile was added to work around optimization issues.

+

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  volatile UINT8 LowerByte;

+  volatile UINT8 HigherByte;

+

+  ASSERT (Buffer != NULL);

+

+  LowerByte = ((UINT8*)Buffer)[0];

+  HigherByte = ((UINT8*)Buffer)[1];

+

+  return (UINT16)(LowerByte | (HigherByte << 8));

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  ((volatile UINT8*)Buffer)[0] = (UINT8)Value;

+  ((volatile UINT8*)Buffer)[1] = (UINT8)(Value >> 8);

+

+  return 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT32)(

+            ReadUnaligned16 ((UINT16*)Buffer) |

+            (((UINT8*)Buffer)[2] << 16)

+            );

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);

+  *(UINT8*)((UINT16*)Buffer + 1) = (UINT8)(Value >> 16);

+  return 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

+  )

+{

+  UINT16  LowerBytes;

+  UINT16  HigherBytes;

+

+  ASSERT (Buffer != NULL);

+

+  LowerBytes  = ReadUnaligned16 ((UINT16*) Buffer);

+  HigherBytes = ReadUnaligned16 ((UINT16*) Buffer + 1);

+

+  return (UINT32) (LowerBytes | (HigherBytes << 16));

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);

+  WriteUnaligned16 ((UINT16*)Buffer + 1, (UINT16)(Value >> 16));

+  return 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

+  )

+{

+  UINT32  LowerBytes;

+  UINT32  HigherBytes;

+

+  ASSERT (Buffer != NULL);

+

+  LowerBytes  = ReadUnaligned32 ((UINT32*) Buffer);

+  HigherBytes = ReadUnaligned32 ((UINT32*) Buffer + 1);

+

+  return (UINT64) (LowerBytes | LShiftU64 (HigherBytes, 32));

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned32 ((UINT32*)Buffer, (UINT32)Value);

+  WriteUnaligned32 ((UINT32*)Buffer + 1, (UINT32)RShiftU64 (Value, 32));

+  return Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLib.inf
new file mode 100644
index 0000000..fc0cb96
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLib.inf
@@ -0,0 +1,513 @@
+## @file

+#  Base Library implementation.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

+#  Portions copyright (c) 2011 - 2013, 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

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseLib

+  MODULE_UNI_FILE                = BaseLib.uni

+  FILE_GUID                      = 27d67720-ea68-48ae-93da-a3a074c90e30

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseLib 

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64

+#

+

+[Sources]

+  CheckSum.c

+  SwitchStack.c

+  SwapBytes64.c

+  SwapBytes32.c

+  SwapBytes16.c

+  LongJump.c

+  SetJump.c

+  RShiftU64.c

+  RRotU64.c

+  RRotU32.c

+  MultU64x64.c

+  MultU64x32.c

+  MultS64x64.c

+  ModU64x32.c

+  LShiftU64.c

+  LRotU64.c

+  LRotU32.c

+  LowBitSet64.c

+  LowBitSet32.c

+  HighBitSet64.c

+  HighBitSet32.c

+  GetPowerOfTwo64.c

+  GetPowerOfTwo32.c

+  DivU64x64Remainder.c

+  DivU64x32Remainder.c

+  DivU64x32.c

+  DivS64x64Remainder.c

+  ARShiftU64.c

+  BitField.c

+  CpuDeadLoop.c

+  Cpu.c

+  LinkedList.c

+  SafeString.c

+  String.c

+  FilePaths.c

+  BaseLibInternals.h

+

+[Sources.Ia32]

+  Ia32/Wbinvd.c | MSFT 

+  Ia32/WriteMm7.c | MSFT 

+  Ia32/WriteMm6.c | MSFT 

+  Ia32/WriteMm5.c | MSFT 

+  Ia32/WriteMm4.c | MSFT 

+  Ia32/WriteMm3.c | MSFT 

+  Ia32/WriteMm2.c | MSFT 

+  Ia32/WriteMm1.c | MSFT 

+  Ia32/WriteMm0.c | MSFT 

+  Ia32/WriteLdtr.c | MSFT 

+  Ia32/WriteIdtr.c | MSFT 

+  Ia32/WriteGdtr.c | MSFT 

+  Ia32/WriteDr7.c | MSFT 

+  Ia32/WriteDr6.c | MSFT 

+  Ia32/WriteDr5.c | MSFT 

+  Ia32/WriteDr4.c | MSFT 

+  Ia32/WriteDr3.c | MSFT 

+  Ia32/WriteDr2.c | MSFT 

+  Ia32/WriteDr1.c | MSFT 

+  Ia32/WriteDr0.c | MSFT 

+  Ia32/WriteCr4.c | MSFT 

+  Ia32/WriteCr3.c | MSFT 

+  Ia32/WriteCr2.c | MSFT 

+  Ia32/WriteCr0.c | MSFT 

+  Ia32/WriteMsr64.c | MSFT 

+  Ia32/SwapBytes64.c | MSFT 

+  Ia32/SetJump.c | MSFT 

+  Ia32/RRotU64.c | MSFT 

+  Ia32/RShiftU64.c | MSFT 

+  Ia32/ReadPmc.c | MSFT 

+  Ia32/ReadTsc.c | MSFT 

+  Ia32/ReadLdtr.c | MSFT 

+  Ia32/ReadIdtr.c | MSFT 

+  Ia32/ReadGdtr.c | MSFT 

+  Ia32/ReadTr.c | MSFT 

+  Ia32/ReadSs.c | MSFT 

+  Ia32/ReadGs.c | MSFT 

+  Ia32/ReadFs.c | MSFT 

+  Ia32/ReadEs.c | MSFT 

+  Ia32/ReadDs.c | MSFT 

+  Ia32/ReadCs.c | MSFT 

+  Ia32/ReadMsr64.c | MSFT 

+  Ia32/ReadMm7.c | MSFT 

+  Ia32/ReadMm6.c | MSFT 

+  Ia32/ReadMm5.c | MSFT 

+  Ia32/ReadMm4.c | MSFT 

+  Ia32/ReadMm3.c | MSFT 

+  Ia32/ReadMm2.c | MSFT 

+  Ia32/ReadMm1.c | MSFT 

+  Ia32/ReadMm0.c | MSFT 

+  Ia32/ReadEflags.c | MSFT 

+  Ia32/ReadDr7.c | MSFT 

+  Ia32/ReadDr6.c | MSFT 

+  Ia32/ReadDr5.c | MSFT 

+  Ia32/ReadDr4.c | MSFT 

+  Ia32/ReadDr3.c | MSFT 

+  Ia32/ReadDr2.c | MSFT 

+  Ia32/ReadDr1.c | MSFT 

+  Ia32/ReadDr0.c | MSFT 

+  Ia32/ReadCr4.c | MSFT 

+  Ia32/ReadCr3.c | MSFT 

+  Ia32/ReadCr2.c | MSFT 

+  Ia32/ReadCr0.c | MSFT 

+  Ia32/Mwait.c | MSFT 

+  Ia32/Monitor.c | MSFT 

+  Ia32/ModU64x32.c | MSFT 

+  Ia32/MultU64x64.c | MSFT 

+  Ia32/MultU64x32.c | MSFT 

+  Ia32/LShiftU64.c | MSFT 

+  Ia32/LRotU64.c | MSFT 

+  Ia32/LongJump.c | MSFT 

+  Ia32/Invd.c | MSFT 

+  Ia32/FxRestore.c | MSFT 

+  Ia32/FxSave.c | MSFT 

+  Ia32/FlushCacheLine.c | MSFT 

+  Ia32/EnablePaging32.c | MSFT 

+  Ia32/EnableInterrupts.c | MSFT 

+  Ia32/EnableDisableInterrupts.c | MSFT 

+  Ia32/DivU64x64Remainder.asm | MSFT 

+  Ia32/DivU64x32Remainder.c | MSFT 

+  Ia32/DivU64x32.c | MSFT 

+  Ia32/DisablePaging32.c | MSFT 

+  Ia32/DisableInterrupts.c | MSFT 

+  Ia32/CpuPause.c | MSFT 

+  Ia32/CpuIdEx.c | MSFT 

+  Ia32/CpuId.c | MSFT 

+  Ia32/CpuBreakpoint.c | MSFT 

+  Ia32/ARShiftU64.c | MSFT 

+  Ia32/Thunk16.asm | MSFT

+  Ia32/EnablePaging64.asm | MSFT

+  Ia32/EnableCache.c | MSFT

+  Ia32/DisableCache.c | MSFT

+

+  Ia32/Wbinvd.asm | INTEL 

+  Ia32/WriteMm7.asm | INTEL 

+  Ia32/WriteMm6.asm | INTEL 

+  Ia32/WriteMm5.asm | INTEL 

+  Ia32/WriteMm4.asm | INTEL 

+  Ia32/WriteMm3.asm | INTEL 

+  Ia32/WriteMm2.asm | INTEL 

+  Ia32/WriteMm1.asm | INTEL 

+  Ia32/WriteMm0.asm | INTEL 

+  Ia32/WriteLdtr.asm | INTEL 

+  Ia32/WriteIdtr.asm | INTEL 

+  Ia32/WriteGdtr.asm | INTEL 

+  Ia32/WriteDr7.asm | INTEL 

+  Ia32/WriteDr6.asm | INTEL 

+  Ia32/WriteDr5.asm | INTEL 

+  Ia32/WriteDr4.asm | INTEL 

+  Ia32/WriteDr3.asm | INTEL 

+  Ia32/WriteDr2.asm | INTEL 

+  Ia32/WriteDr1.asm | INTEL 

+  Ia32/WriteDr0.asm | INTEL 

+  Ia32/WriteCr4.asm | INTEL 

+  Ia32/WriteCr3.asm | INTEL 

+  Ia32/WriteCr2.asm | INTEL 

+  Ia32/WriteCr0.asm | INTEL 

+  Ia32/WriteMsr64.asm | INTEL 

+  Ia32/SwapBytes64.asm | INTEL 

+  Ia32/SetJump.asm | INTEL 

+  Ia32/RRotU64.asm | INTEL 

+  Ia32/RShiftU64.asm | INTEL 

+  Ia32/ReadPmc.asm | INTEL 

+  Ia32/ReadTsc.asm | INTEL 

+  Ia32/ReadLdtr.asm | INTEL 

+  Ia32/ReadIdtr.asm | INTEL 

+  Ia32/ReadGdtr.asm | INTEL 

+  Ia32/ReadTr.asm | INTEL 

+  Ia32/ReadSs.asm | INTEL 

+  Ia32/ReadGs.asm | INTEL 

+  Ia32/ReadFs.asm | INTEL 

+  Ia32/ReadEs.asm | INTEL 

+  Ia32/ReadDs.asm | INTEL 

+  Ia32/ReadCs.asm | INTEL 

+  Ia32/ReadMsr64.asm | INTEL 

+  Ia32/ReadMm7.asm | INTEL 

+  Ia32/ReadMm6.asm | INTEL 

+  Ia32/ReadMm5.asm | INTEL 

+  Ia32/ReadMm4.asm | INTEL 

+  Ia32/ReadMm3.asm | INTEL 

+  Ia32/ReadMm2.asm | INTEL 

+  Ia32/ReadMm1.asm | INTEL 

+  Ia32/ReadMm0.asm | INTEL 

+  Ia32/ReadEflags.asm | INTEL 

+  Ia32/ReadDr7.asm | INTEL 

+  Ia32/ReadDr6.asm | INTEL 

+  Ia32/ReadDr5.asm | INTEL 

+  Ia32/ReadDr4.asm | INTEL 

+  Ia32/ReadDr3.asm | INTEL 

+  Ia32/ReadDr2.asm | INTEL 

+  Ia32/ReadDr1.asm | INTEL 

+  Ia32/ReadDr0.asm | INTEL 

+  Ia32/ReadCr4.asm | INTEL 

+  Ia32/ReadCr3.asm | INTEL 

+  Ia32/ReadCr2.asm | INTEL 

+  Ia32/ReadCr0.asm | INTEL 

+  Ia32/Mwait.asm | INTEL 

+  Ia32/Monitor.asm | INTEL 

+  Ia32/ModU64x32.asm | INTEL 

+  Ia32/MultU64x64.asm | INTEL 

+  Ia32/MultU64x32.asm | INTEL 

+  Ia32/LShiftU64.asm | INTEL 

+  Ia32/LRotU64.asm | INTEL 

+  Ia32/LongJump.asm | INTEL 

+  Ia32/Invd.asm | INTEL 

+  Ia32/FxRestore.asm | INTEL 

+  Ia32/FxSave.asm | INTEL 

+  Ia32/FlushCacheLine.asm | INTEL 

+  Ia32/EnablePaging32.asm | INTEL 

+  Ia32/EnableInterrupts.asm | INTEL 

+  Ia32/EnableDisableInterrupts.asm | INTEL 

+  Ia32/DivU64x64Remainder.asm | INTEL 

+  Ia32/DivU64x32Remainder.asm | INTEL 

+  Ia32/DivU64x32.asm | INTEL 

+  Ia32/DisablePaging32.asm | INTEL 

+  Ia32/DisableInterrupts.asm | INTEL 

+  Ia32/CpuPause.asm | INTEL 

+  Ia32/CpuIdEx.asm | INTEL 

+  Ia32/CpuId.asm | INTEL 

+  Ia32/CpuBreakpoint.asm | INTEL 

+  Ia32/ARShiftU64.asm | INTEL 

+  Ia32/Thunk16.asm | INTEL

+  Ia32/EnablePaging64.asm | INTEL

+  Ia32/EnableCache.asm | INTEL

+  Ia32/DisableCache.asm | INTEL

+

+  Ia32/GccInline.c | GCC

+  Ia32/Thunk16.nasm | GCC 

+  Ia32/EnableDisableInterrupts.S | GCC 

+  Ia32/EnablePaging64.S | GCC 

+  Ia32/DisablePaging32.S | GCC 

+  Ia32/EnablePaging32.S | GCC 

+  Ia32/Mwait.S | GCC 

+  Ia32/Monitor.S | GCC 

+  Ia32/CpuIdEx.S | GCC 

+  Ia32/CpuId.S | GCC 

+  Ia32/LongJump.S | GCC 

+  Ia32/SetJump.S | GCC 

+  Ia32/SwapBytes64.S | GCC 

+  Ia32/DivU64x64Remainder.S | GCC 

+  Ia32/DivU64x32Remainder.S | GCC 

+  Ia32/ModU64x32.S | GCC 

+  Ia32/DivU64x32.S | GCC 

+  Ia32/MultU64x64.S | GCC 

+  Ia32/MultU64x32.S | GCC 

+  Ia32/RRotU64.S | GCC 

+  Ia32/LRotU64.S | GCC 

+  Ia32/ARShiftU64.S | GCC 

+  Ia32/RShiftU64.S | GCC 

+  Ia32/LShiftU64.S | GCC 

+  Ia32/EnableCache.S | GCC

+  Ia32/DisableCache.S | GCC

+

+  Ia32/DivS64x64Remainder.c

+  Ia32/InternalSwitchStack.c | MSFT

+  Ia32/InternalSwitchStack.c | INTEL

+  Ia32/InternalSwitchStack.S | GCC

+  Ia32/Non-existing.c

+  Unaligned.c

+  X86WriteIdtr.c

+  X86WriteGdtr.c

+  X86Thunk.c

+  X86ReadIdtr.c

+  X86ReadGdtr.c

+  X86Msr.c

+  X86MemoryFence.c | MSFT

+  X86MemoryFence.c | INTEL

+  X86GetInterruptState.c

+  X86FxSave.c

+  X86FxRestore.c

+  X86EnablePaging64.c

+  X86EnablePaging32.c

+  X86DisablePaging64.c

+  X86DisablePaging32.c

+

+[Sources.X64]

+  X64/Thunk16.asm

+  X64/CpuPause.asm

+  X64/EnableDisableInterrupts.asm

+  X64/DisableInterrupts.asm

+  X64/EnableInterrupts.asm

+  X64/FlushCacheLine.asm

+  X64/Invd.asm

+  X64/Wbinvd.asm

+  X64/DisablePaging64.asm

+  X64/Mwait.asm

+  X64/Monitor.asm

+  X64/ReadPmc.asm

+  X64/ReadTsc.asm

+  X64/WriteMm7.asm

+  X64/WriteMm6.asm

+  X64/WriteMm5.asm

+  X64/WriteMm4.asm

+  X64/WriteMm3.asm

+  X64/WriteMm2.asm

+  X64/WriteMm1.asm

+  X64/WriteMm0.asm

+  X64/ReadMm7.asm

+  X64/ReadMm6.asm

+  X64/ReadMm5.asm

+  X64/ReadMm4.asm

+  X64/ReadMm3.asm

+  X64/ReadMm2.asm

+  X64/ReadMm1.asm

+  X64/ReadMm0.asm

+  X64/FxRestore.asm

+  X64/FxSave.asm

+  X64/WriteLdtr.asm

+  X64/ReadLdtr.asm

+  X64/WriteIdtr.asm

+  X64/ReadIdtr.asm

+  X64/WriteGdtr.asm

+  X64/ReadGdtr.asm

+  X64/ReadTr.asm

+  X64/ReadSs.asm

+  X64/ReadGs.asm

+  X64/ReadFs.asm

+  X64/ReadEs.asm

+  X64/ReadDs.asm

+  X64/ReadCs.asm

+  X64/WriteDr7.asm

+  X64/WriteDr6.asm

+  X64/WriteDr5.asm

+  X64/WriteDr4.asm

+  X64/WriteDr3.asm

+  X64/WriteDr2.asm

+  X64/WriteDr1.asm

+  X64/WriteDr0.asm

+  X64/ReadDr7.asm

+  X64/ReadDr6.asm

+  X64/ReadDr5.asm

+  X64/ReadDr4.asm

+  X64/ReadDr3.asm

+  X64/ReadDr2.asm

+  X64/ReadDr1.asm

+  X64/ReadDr0.asm

+  X64/WriteCr4.asm

+  X64/WriteCr3.asm

+  X64/WriteCr2.asm

+  X64/WriteCr0.asm

+  X64/ReadCr4.asm

+  X64/ReadCr3.asm

+  X64/ReadCr2.asm

+  X64/ReadCr0.asm

+  X64/ReadEflags.asm

+  X64/CpuIdEx.asm

+  X64/CpuId.asm

+  X64/LongJump.asm

+  X64/SetJump.asm

+  X64/SwitchStack.asm

+  X64/EnableCache.asm

+  X64/DisableCache.asm

+

+  X64/CpuBreakpoint.c | MSFT 

+  X64/WriteMsr64.c | MSFT 

+  X64/ReadMsr64.c | MSFT 

+

+  X64/CpuBreakpoint.asm | INTEL 

+  X64/WriteMsr64.asm | INTEL 

+  X64/ReadMsr64.asm | INTEL 

+

+  X64/Non-existing.c

+  Math64.c

+  Unaligned.c

+  X86WriteIdtr.c

+  X86WriteGdtr.c

+  X86Thunk.c

+  X86ReadIdtr.c

+  X86ReadGdtr.c

+  X86Msr.c

+  X86MemoryFence.c | MSFT

+  X86MemoryFence.c | INTEL

+  X86GetInterruptState.c

+  X86FxSave.c

+  X86FxRestore.c

+  X86EnablePaging64.c

+  X86EnablePaging32.c

+  X86DisablePaging64.c

+  X86DisablePaging32.c

+  X64/GccInline.c | GCC

+  X64/Thunk16.nasm | GCC 

+  X64/SwitchStack.S | GCC 

+  X64/SetJump.S | GCC 

+  X64/LongJump.S | GCC 

+  X64/EnableDisableInterrupts.S | GCC 

+  X64/DisablePaging64.S | GCC 

+  X64/CpuId.S | GCC 

+  X64/CpuIdEx.S | GCC 

+  X64/EnableCache.S | GCC

+  X64/DisableCache.S | GCC

+  ChkStkGcc.c  | GCC 

+

+[Sources.IPF]

+  Ipf/AccessGp.s

+  Ipf/ReadCpuid.s

+  Ipf/ExecFc.s

+  Ipf/AsmPalCall.s

+  Ipf/AccessPsr.s

+  Ipf/AccessPmr.s

+  Ipf/AccessKr.s

+  Ipf/AccessKr7.s

+  Ipf/AccessGcr.s

+  Ipf/AccessEicr.s

+  Ipf/AccessDbr.s

+  Ipf/AccessMsr.s        | INTEL

+  Ipf/AccessMsr.s        | GCC

+  Ipf/AccessMsrDb.s      | MSFT

+  Ipf/InternalFlushCacheRange.s

+  Ipf/FlushCacheRange.c

+  Ipf/InternalSwitchStack.c

+  Ipf/GetInterruptState.s

+  Ipf/CpuPause.s

+  Ipf/CpuBreakpoint.c    | INTEL

+  Ipf/CpuBreakpointMsc.c | MSFT

+  Ipf/AsmCpuMisc.s       | GCC

+  Ipf/Unaligned.c

+  Ipf/SwitchStack.s

+  Ipf/LongJmp.s

+  Ipf/SetJmp.s

+  Ipf/ReadCr.s

+  Ipf/ReadAr.s

+  Ipf/Ia64gen.h

+  Ipf/Asm.h

+  Math64.c

+

+[Sources.EBC]

+  Ebc/CpuBreakpoint.c

+  Ebc/SetJumpLongJump.c

+  Ebc/SwitchStack.c

+  Unaligned.c

+  Math64.c

+

+[Sources.ARM]

+  Arm/InternalSwitchStack.c

+  Arm/Unaligned.c

+  Math64.c                   | RVCT 

+    

+  Arm/SwitchStack.asm        | RVCT

+  Arm/SetJumpLongJump.asm    | RVCT

+  Arm/DisableInterrupts.asm  | RVCT

+  Arm/EnableInterrupts.asm   | RVCT

+  Arm/GetInterruptsState.asm | RVCT

+  Arm/CpuPause.asm           | RVCT

+  Arm/CpuBreakpoint.asm      | RVCT

+  Arm/MemoryFence.asm        | RVCT

+ 

+  Arm/Math64.S                  | GCC

+  Arm/SwitchStack.S             | GCC

+  Arm/EnableInterrupts.S        | GCC

+  Arm/DisableInterrupts.S       | GCC

+  Arm/GetInterruptsState.S      | GCC

+  Arm/SetJumpLongJump.S         | GCC

+  Arm/CpuBreakpoint.S           | GCC

+  Arm/MemoryFence.S             | GCC

+

+[Sources.AARCH64]

+  Arm/InternalSwitchStack.c

+  Arm/Unaligned.c

+  Math64.c

+

+  AArch64/MemoryFence.S             | GCC

+  AArch64/SwitchStack.S             | GCC

+  AArch64/EnableInterrupts.S        | GCC

+  AArch64/DisableInterrupts.S       | GCC

+  AArch64/GetInterruptsState.S      | GCC

+  AArch64/SetJumpLongJump.S         | GCC

+  AArch64/CpuBreakpoint.S           | GCC

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PcdLib

+  DebugLib

+  BaseMemoryLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength      ## SOMETIMES_CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength     ## SOMETIMES_CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength   ## SOMETIMES_CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask            ## SOMETIMES_CONSUMES

+

+[FeaturePcd]

+  gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList  ## CONSUMES

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLib.uni
new file mode 100644
index 0000000..41529a3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLibInternals.h
new file mode 100644
index 0000000..fe416a0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -0,0 +1,1655 @@
+/** @file

+  Declaration of internal functions in BaseLib.

+

+  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 __BASE_LIB_INTERNALS__

+#define __BASE_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+//

+// Math functions

+//

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to shift left.

+  @param  Count   The number of bits to shift left.

+

+  @return Operand << Count

+

+**/

+UINT64

+EFIAPI

+InternalMathLShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Shifts a 64-bit integer right between 0 and 63 bits. The 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.

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand >> Count

+

+**/

+UINT64

+EFIAPI

+InternalMathRShiftU64 (

+  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.

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand arithmetically shifted right by Count

+

+**/

+UINT64

+EFIAPI

+InternalMathARShiftU64 (

+  IN      UINT64                    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 filled with the high Count bits of Operand. The rotated

+  value is returned.

+

+  @param  Operand The 64-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count

+

+**/

+UINT64

+EFIAPI

+InternalMathLRotU64 (

+  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 filled with the low Count bits of Operand. The rotated

+  value is returned.

+

+  @param  Operand The 64-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count

+

+**/

+UINT64

+EFIAPI

+InternalMathRRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  );

+

+/**

+  Switches the endianess 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  Operand A 64-bit unsigned value.

+

+  @return The byte swapped Operand.

+

+**/

+UINT64

+EFIAPI

+InternalMathSwapBytes64 (

+  IN      UINT64                    Operand

+  );

+

+/**

+  Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer

+  and generates a 64-bit unsigned result.

+

+  This function multiplies 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

+InternalMathMultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  );

+

+/**

+  Multiplies 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

+InternalMathMultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    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.

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+InternalMathDivU64x32 (

+  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.

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend % Divisor

+

+**/

+UINT32

+EFIAPI

+InternalMathModU64x32 (

+  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.

+

+  @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

+InternalMathDivRemU64x32 (

+  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.

+

+  @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

+InternalMathDivRemU64x64 (

+  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 an 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.

+

+  @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

+InternalMathDivRemS64x64 (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder  OPTIONAL

+  );

+

+/**

+  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.

+  Marker will be ignored on IA-32, x64, and EBC.

+  IPF CPUs 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  Marker      VA_LIST marker for the variable argument list.

+

+**/

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,   OPTIONAL

+  IN      VOID                      *Context2,   OPTIONAL

+  IN      VOID                      *NewStack,

+  IN      VA_LIST                   Marker

+  );

+

+

+/**

+  Worker function that locates the Node in the List.

+

+  By searching the List, finds the location of the Node in List. At the same time,

+  verifies the validity of this list.

+

+  If List is NULL, then ASSERT().

+  If List->ForwardLink is NULL, then ASSERT().

+  If List->backLink is NULL, then ASSERT().

+  If Node is NULL, 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  List  A pointer to a node in a linked list.

+  @param  Node  A pointer to one nod.

+

+  @retval TRUE   Node is in List.

+  @retval FALSE  Node isn't in List, or List is invalid.

+

+**/

+BOOLEAN

+EFIAPI

+IsNodeInList (

+  IN      CONST LIST_ENTRY      *List,

+  IN      CONST LIST_ENTRY      *Node

+  );

+

+/**

+  Worker function that returns a bit field from Operand.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+

+  @return The bit field read.

+

+**/

+UINTN

+EFIAPI

+BitFieldReadUint (

+  IN      UINTN                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  );

+

+

+/**

+  Worker function that reads a bit field from Operand, 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 AndData. All other bits in Operand are

+  preserved. The new value is returned.

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+  @param  OrData    The value to OR with the read value from the value

+

+  @return The new value.

+

+**/

+UINTN

+EFIAPI

+BitFieldOrUint (

+  IN      UINTN                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINTN                     OrData

+  );

+

+

+/**

+  Worker function that reads a bit field from Operand, 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 value is returned.

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+  @param  AndData    The value to And with the read value from the value

+

+  @return The new value.

+

+**/

+UINTN

+EFIAPI

+BitFieldAndUint (

+  IN      UINTN                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINTN                     AndData

+  );

+

+

+/**

+  Worker function that checks ASSERT condition for JumpBuffer

+

+  Checks ASSERT condition for JumpBuffer.

+

+  If JumpBuffer is NULL, then ASSERT().

+  For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+

+**/

+VOID

+EFIAPI

+InternalAssertJumpBuffer (

+  IN      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.

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+  @param  Value         The value to return when the SetJump() context is restored.

+

+**/

+VOID

+EFIAPI

+InternalLongJump (

+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                     Value

+  );

+

+

+//

+// Ia32 and x64 specific functions

+//

+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)

+

+/**

+  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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadGdtr (

+  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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  );

+

+/**

+  Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current IDTR descriptor and returns it in Idtr. This

+  function is only available on IA-32 and x64.

+

+  @param  Idtr  The pointer to an IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  );

+

+/**

+  Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Writes the current IDTR descriptor and returns it in Idtr. This function is

+  only available on IA-32 and x64.

+

+  @param  Idtr  The pointer to an IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  );

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxSave (

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxRestore (

+  IN      CONST IA32_FX_BUFFER      *Buffer

+  );

+

+/**

+  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.

+

+  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

+InternalX86EnablePaging32 (

+  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.

+

+  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

+InternalX86DisablePaging32 (

+  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.

+

+  @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

+InternalX86EnablePaging64 (

+  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.

+

+  @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

+InternalX86DisablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT32                    EntryPoint,

+  IN      UINT32                    Context1,  OPTIONAL

+  IN      UINT32                    Context2,  OPTIONAL

+  IN      UINT32                    NewStack

+  );

+

+

+#elif defined (MDE_CPU_IPF)

+//

+//

+// IPF specific functions

+//

+

+/**

+  Reads control register DCR.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_DCR.

+

+  @return The 64-bit control register DCR.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterDcr (

+  VOID

+  );

+

+

+/**

+  Reads control register ITM.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_ITM.

+

+  @return The 64-bit control register ITM.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterItm (

+  VOID

+  );

+

+

+/**

+  Reads control register IVA.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IVA.

+

+  @return The 64-bit control register IVA.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIva (

+  VOID

+  );

+

+

+/**

+  Reads control register PTA.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_PTA.

+

+  @return The 64-bit control register PTA.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterPta (

+  VOID

+  );

+

+

+/**

+  Reads control register IPSR.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IPSR.

+

+  @return The 64-bit control register IPSR.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIpsr (

+  VOID

+  );

+

+

+/**

+  Reads control register ISR.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_ISR.

+

+  @return The 64-bit control register ISR.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIsr (

+  VOID

+  );

+

+

+/**

+  Reads control register IIP.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IIP.

+

+  @return The 64-bit control register IIP.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIip (

+  VOID

+  );

+

+

+/**

+  Reads control register IFA.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IFA.

+

+  @return The 64-bit control register IFA.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIfa (

+  VOID

+  );

+

+

+/**

+  Reads control register ITIR.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_ITIR.

+

+  @return The 64-bit control register ITIR.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterItir (

+  VOID

+  );

+

+

+/**

+  Reads control register IIPA.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IIPA.

+

+  @return The 64-bit control register IIPA.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIipa (

+  VOID

+  );

+

+

+/**

+  Reads control register IFS.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IFS.

+

+  @return The 64-bit control register IFS.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIfs (

+  VOID

+  );

+

+

+/**

+  Reads control register IIM.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IIM.

+

+  @return The 64-bit control register IIM.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIim (

+  VOID

+  );

+

+

+/**

+  Reads control register IHA.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IHA.

+

+  @return The 64-bit control register IHA.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIha (

+  VOID

+  );

+

+

+/**

+  Reads control register LID.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_LID.

+

+  @return The 64-bit control register LID.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterLid (

+  VOID

+  );

+

+

+/**

+  Reads control register IVR.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IVR.

+

+  @return The 64-bit control register IVR.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIvr (

+  VOID

+  );

+

+

+/**

+  Reads control register TPR.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_TPR.

+

+  @return The 64-bit control register TPR.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterTpr (

+  VOID

+  );

+

+

+/**

+  Reads control register EOI.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_EOI.

+

+  @return The 64-bit control register EOI.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterEoi (

+  VOID

+  );

+

+

+/**

+  Reads control register IRR0.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IRR0.

+

+  @return The 64-bit control register IRR0.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIrr0 (

+  VOID

+  );

+

+

+/**

+  Reads control register IRR1.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IRR1.

+

+  @return The 64-bit control register IRR1.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIrr1 (

+  VOID

+  );

+

+

+/**

+  Reads control register IRR2.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IRR2.

+

+  @return The 64-bit control register IRR2.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIrr2 (

+  VOID

+  );

+

+

+/**

+  Reads control register IRR3.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_IRR3.

+

+  @return The 64-bit control register IRR3.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterIrr3 (

+  VOID

+  );

+

+

+/**

+  Reads control register ITV.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_ITV.

+

+  @return The 64-bit control register ITV.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterItv (

+  VOID

+  );

+

+

+/**

+  Reads control register PMV.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_PMV.

+

+  @return The 64-bit control register PMV.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterPmv (

+  VOID

+  );

+

+

+/**

+  Reads control register CMCV.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_CMCV.

+

+  @return The 64-bit control register CMCV.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterCmcv (

+  VOID

+  );

+

+

+/**

+  Reads control register LRR0.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_LRR0.

+

+  @return The 64-bit control register LRR0.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterLrr0 (

+  VOID

+  );

+

+

+/**

+  Reads control register LRR1.

+

+  This is a worker function for AsmReadControlRegister()

+  when its parameter Index is IPF_CONTROL_REGISTER_LRR1.

+

+  @return The 64-bit control register LRR1.

+

+**/

+UINT64

+EFIAPI

+AsmReadControlRegisterLrr1 (

+  VOID

+  );

+

+

+/**

+  Reads application register K0.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K0.

+

+  @return The 64-bit application register K0.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK0 (

+  VOID

+  );

+

+

+

+/**

+  Reads application register K1.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K1.

+

+  @return The 64-bit application register K1.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK1 (

+  VOID

+  );

+

+

+/**

+  Reads application register K2.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K2.

+

+  @return The 64-bit application register K2.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK2 (

+  VOID

+  );

+

+

+/**

+  Reads application register K3.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K3.

+

+  @return The 64-bit application register K3.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK3 (

+  VOID

+  );

+

+

+/**

+  Reads application register K4.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K4.

+

+  @return The 64-bit application register K4.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK4 (

+  VOID

+  );

+

+

+/**

+  Reads application register K5.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K5.

+

+  @return The 64-bit application register K5.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK5 (

+  VOID

+  );

+

+

+/**

+  Reads application register K6.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K6.

+

+  @return The 64-bit application register K6.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK6 (

+  VOID

+  );

+

+

+/**

+  Reads application register K7.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_K7.

+

+  @return The 64-bit application register K7.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterK7 (

+  VOID

+  );

+

+

+/**

+  Reads application register RSC.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_RSC.

+

+  @return The 64-bit application register RSC.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterRsc (

+  VOID

+  );

+

+

+/**

+  Reads application register BSP.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_BSP.

+

+  @return The 64-bit application register BSP.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterBsp (

+  VOID

+  );

+

+

+/**

+  Reads application register BSPSTORE.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_BSPSTORE.

+

+  @return The 64-bit application register BSPSTORE.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterBspstore (

+  VOID

+  );

+

+

+/**

+  Reads application register RNAT.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_RNAT.

+

+  @return The 64-bit application register RNAT.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterRnat (

+  VOID

+  );

+

+

+/**

+  Reads application register FCR.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_FCR.

+

+  @return The 64-bit application register FCR.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterFcr (

+  VOID

+  );

+

+

+/**

+  Reads application register EFLAG.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_EFLAG.

+

+  @return The 64-bit application register EFLAG.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterEflag (

+  VOID

+  );

+

+

+/**

+  Reads application register CSD.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_CSD.

+

+  @return The 64-bit application register CSD.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterCsd (

+  VOID

+  );

+

+

+/**

+  Reads application register SSD.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_SSD.

+

+  @return The 64-bit application register SSD.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterSsd (

+  VOID

+  );

+

+

+/**

+  Reads application register CFLG.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_CFLG.

+

+  @return The 64-bit application register CFLG.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterCflg (

+  VOID

+  );

+

+

+/**

+  Reads application register FSR.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_FSR.

+

+  @return The 64-bit application register FSR.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterFsr (

+  VOID

+  );

+

+

+/**

+  Reads application register FIR.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_FIR.

+

+  @return The 64-bit application register FIR.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterFir (

+  VOID

+  );

+

+

+/**

+  Reads application register FDR.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_FDR.

+

+  @return The 64-bit application register FDR.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterFdr (

+  VOID

+  );

+

+

+/**

+  Reads application register CCV.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_CCV.

+

+  @return The 64-bit application register CCV.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterCcv (

+  VOID

+  );

+

+

+/**

+  Reads application register UNAT.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_UNAT.

+

+  @return The 64-bit application register UNAT.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterUnat (

+  VOID

+  );

+

+

+/**

+  Reads application register FPSR.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_FPSR.

+

+  @return The 64-bit application register FPSR.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterFpsr (

+  VOID

+  );

+

+

+/**

+  Reads application register ITC.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_ITC.

+

+  @return The 64-bit application register ITC.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterItc (

+  VOID

+  );

+

+

+/**

+  Reads application register PFS.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_PFS.

+

+  @return The 64-bit application register PFS.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterPfs (

+  VOID

+  );

+

+

+/**

+  Reads application register LC.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_LC.

+

+  @return The 64-bit application register LC.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterLc (

+  VOID

+  );

+

+

+/**

+  Reads application register EC.

+

+  This is a worker function for AsmReadApplicationRegister()

+  when its parameter Index is IPF_APPLICATION_REGISTER_EC.

+

+  @return The 64-bit application register EC.

+

+**/

+UINT64

+EFIAPI

+AsmReadApplicationRegisterEc (

+  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.

+

+  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  NewBsp      A pointer to the new memory location for RSE backing

+                      store.

+

+**/

+VOID

+EFIAPI

+AsmSwitchStackAndBackingStore (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack,

+  IN      VOID                      *NewBsp

+  );

+

+/**

+  Internal worker function to invalidate a range of instruction cache lines

+  in the cache coherency domain of the calling CPU.

+

+  Internal worker function to invalidate the instruction cache lines specified

+  by Address and Length. If Address is not aligned on a cache line boundary,

+  then entire instruction cache line containing Address is invalidated. If

+  Address + Length is not aligned on a cache line boundary, then the entire

+  instruction cache line containing Address + Length -1 is invalidated. This

+  function may choose to invalidate the entire instruction cache if that is more

+  efficient than invalidating the specified range. If Length is 0, the no instruction

+  cache lines are invalidated. Address is returned.

+  This function is only available on IPF.

+

+  @param  Address The base address of the instruction cache 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

+InternalFlushCacheRange (

+  IN      VOID                      *Address,

+  IN      UINTN                     Length

+  );

+

+#else

+

+#endif

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/BitField.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BitField.c
new file mode 100644
index 0000000..eb9e276
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/BitField.c
@@ -0,0 +1,922 @@
+/** @file

+  Bit field functions of BaseLib.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  Worker function that returns a bit field from Operand.

+

+  Returns the bitfield specified by the StartBit and the EndBit from Operand.

+

+  @param  Operand   Operand on which to perform the bitfield operation.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+

+  @return The bit field read.

+

+**/

+UINTN

+EFIAPI

+InternalBaseLibBitFieldReadUint (

+  IN      UINTN                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  //

+  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]

+  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.

+  //

+  return (Operand & ~((UINTN)-2 << EndBit)) >> StartBit;

+}

+

+/**

+  Worker function that reads a bit field from Operand, 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 AndData. All other bits in Operand are

+  preserved. The new value is returned.

+

+  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.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+  @param  OrData    The value to OR with the read value from the value.

+

+  @return The new value.

+

+**/

+UINTN

+EFIAPI

+InternalBaseLibBitFieldOrUint (

+  IN      UINTN                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINTN                     OrData

+  )

+{

+  //

+  // Higher bits in OrData those are not used must be zero. 

+  //

+  // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,

+  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.

+  //

+  ASSERT ((OrData >> (EndBit - StartBit)) == ((OrData >> (EndBit - StartBit)) & 1));

+  

+  //

+  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]

+  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.

+  //

+  return Operand | ((OrData << StartBit) & ~((UINTN) -2 << EndBit));

+}

+

+/**

+  Worker function that reads a bit field from Operand, 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 value is returned.

+

+  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.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+  @param  AndData    The value to And with the read value from the value.

+

+  @return The new value.

+

+**/

+UINTN

+EFIAPI

+InternalBaseLibBitFieldAndUint (

+  IN      UINTN                     Operand,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINTN                     AndData

+  )

+{

+  //

+  // Higher bits in AndData those are not used must be zero. 

+  //

+  // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,

+  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.

+  //

+  ASSERT ((AndData >> (EndBit - StartBit)) == ((AndData >> (EndBit - StartBit)) & 1));

+

+  //

+  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]

+  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.

+  //

+  return Operand & ~((~AndData << StartBit) & ~((UINTN)-2 << EndBit));

+}

+

+/**

+  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

+  )

+{

+  ASSERT (EndBit < 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT8)InternalBaseLibBitFieldReadUint (Operand, StartBit, 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     The 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

+  )

+{

+  ASSERT (EndBit < 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, 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

+  )

+{

+  ASSERT (EndBit < 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT8)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT8)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < 8);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr8 (

+           BitFieldAnd8 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           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

+  )

+{

+  ASSERT (EndBit < 16);

+  ASSERT (StartBit <= EndBit);

+  return (UINT16)InternalBaseLibBitFieldReadUint (Operand, StartBit, 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     The 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

+  )

+{

+  ASSERT (EndBit < 16);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, 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

+  )

+{

+  ASSERT (EndBit < 16);

+  ASSERT (StartBit <= EndBit);

+  return (UINT16)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < 16);

+  ASSERT (StartBit <= EndBit);

+  return (UINT16)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < 16);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr16 (

+           BitFieldAnd16 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           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

+  )

+{

+  ASSERT (EndBit < 32);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)InternalBaseLibBitFieldReadUint (Operand, StartBit, 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     The 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

+  )

+{

+  ASSERT (EndBit < 32);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, 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

+  )

+{

+  ASSERT (EndBit < 32);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < 32);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < 32);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr32 (

+           BitFieldAnd32 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           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

+  )

+{

+  ASSERT (EndBit < 64);

+  ASSERT (StartBit <= EndBit);

+  return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);

+}

+

+/**

+  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     The 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

+  )

+{

+  ASSERT (EndBit < 64);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, 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

+  )

+{

+  UINT64  Value1;

+  UINT64  Value2;

+

+  ASSERT (EndBit < 64);

+  ASSERT (StartBit <= EndBit);

+  //

+  // Higher bits in OrData those are not used must be zero. 

+  //

+  // EndBit - StartBit + 1 might be 64 while the result right shifting 64 on RShiftU64() API is invalid,

+  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.

+  //

+  ASSERT (RShiftU64 (OrData, EndBit - StartBit) == (RShiftU64 (OrData, EndBit - StartBit) & 1));

+

+  Value1 = LShiftU64 (OrData, StartBit);

+  Value2 = LShiftU64 ((UINT64) - 2, EndBit);

+

+  return Operand | (Value1 & ~Value2);

+}

+

+/**

+  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

+  )

+{

+  UINT64  Value1;

+  UINT64  Value2;

+  

+  ASSERT (EndBit < 64);

+  ASSERT (StartBit <= EndBit);

+  //

+  // Higher bits in AndData those are not used must be zero. 

+  //

+  // EndBit - StartBit + 1 might be 64 while the right shifting 64 on RShiftU64() API is invalid,

+  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.

+  //

+  ASSERT (RShiftU64 (AndData, EndBit - StartBit) == (RShiftU64 (AndData, EndBit - StartBit) & 1));

+

+  Value1 = LShiftU64 (~AndData, StartBit);

+  Value2 = LShiftU64 ((UINT64)-2, EndBit);

+

+  return Operand & ~(Value1 & ~Value2);

+}

+

+/**

+  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

+  )

+{

+  ASSERT (EndBit < 64);

+  ASSERT (StartBit <= EndBit);

+  return BitFieldOr64 (

+           BitFieldAnd64 (Operand, StartBit, EndBit, AndData),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/CheckSum.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/CheckSum.c
new file mode 100644
index 0000000..2968829
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/CheckSum.c
@@ -0,0 +1,337 @@
+/** @file

+  Utility functions to generate checksum based on 2's complement

+  algorithm.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  UINT8     Sum;

+  UINTN     Count;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));

+

+  for (Sum = 0, Count = 0; Count < Length; Count++) {

+    Sum = (UINT8) (Sum + *(Buffer + Count));

+  }

+  

+  return Sum;

+}

+

+

+/**

+  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 2's complement checksum of Buffer.

+

+**/

+UINT8

+EFIAPI

+CalculateCheckSum8 (

+  IN      CONST UINT8              *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  UINT8     CheckSum;

+

+  CheckSum = CalculateSum8 (Buffer, Length);

+

+  //

+  // Return the checksum based on 2's complement.

+  //

+  return (UINT8) (0x100 - CheckSum);

+}

+

+/**

+  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

+  )

+{

+  UINT16    Sum;

+  UINTN     Count;

+  UINTN     Total;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN) Buffer & 0x1) == 0);

+  ASSERT ((Length & 0x1) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));

+

+  Total = Length / sizeof (*Buffer);

+  for (Sum = 0, Count = 0; Count < Total; Count++) {

+    Sum = (UINT16) (Sum + *(Buffer + Count));

+  }

+  

+  return Sum;

+}

+

+

+/**

+  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 2's complement checksum of Buffer.

+

+**/

+UINT16

+EFIAPI

+CalculateCheckSum16 (

+  IN      CONST UINT16             *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  UINT16     CheckSum;

+

+  CheckSum = CalculateSum16 (Buffer, Length);

+

+  //

+  // Return the checksum based on 2's complement.

+  //

+  return (UINT16) (0x10000 - CheckSum);

+}

+

+

+/**

+  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

+  )

+{

+  UINT32    Sum;

+  UINTN     Count;

+  UINTN     Total;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN) Buffer & 0x3) == 0);

+  ASSERT ((Length & 0x3) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));

+

+  Total = Length / sizeof (*Buffer);

+  for (Sum = 0, Count = 0; Count < Total; Count++) {

+    Sum = Sum + *(Buffer + Count);

+  }

+  

+  return Sum;

+}

+

+

+/**

+  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 2's complement checksum of Buffer.

+

+**/

+UINT32

+EFIAPI

+CalculateCheckSum32 (

+  IN      CONST UINT32             *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  UINT32     CheckSum;

+

+  CheckSum = CalculateSum32 (Buffer, Length);

+

+  //

+  // Return the checksum based on 2's complement.

+  //

+  return (UINT32) ((UINT32)(-1) - CheckSum + 1);

+}

+

+

+/**

+  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

+  )

+{

+  UINT64    Sum;

+  UINTN     Count;

+  UINTN     Total;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN) Buffer & 0x7) == 0);

+  ASSERT ((Length & 0x7) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));

+

+  Total = Length / sizeof (*Buffer);

+  for (Sum = 0, Count = 0; Count < Total; Count++) {

+    Sum = Sum + *(Buffer + Count);

+  }

+  

+  return Sum;

+}

+

+

+/**

+  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 2's complement checksum of Buffer.

+

+**/

+UINT64

+EFIAPI

+CalculateCheckSum64 (

+  IN      CONST UINT64             *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  UINT64     CheckSum;

+

+  CheckSum = CalculateSum64 (Buffer, Length);

+

+  //

+  // Return the checksum based on 2's complement.

+  //

+  return (UINT64) ((UINT64)(-1) - CheckSum + 1);

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/ChkStkGcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/ChkStkGcc.c
new file mode 100644
index 0000000..ecba385
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/ChkStkGcc.c
@@ -0,0 +1,24 @@
+/** @file

+  Provides hack function for passng GCC build.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  Hack function for passing GCC build.

+**/

+VOID 

+__chkstk() 

+{

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Cpu.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Cpu.c
new file mode 100644
index 0000000..8bcbf25
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Cpu.c
@@ -0,0 +1,65 @@
+/** @file

+  Base Library CPU Functions for all architectures.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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

+  )

+{

+  BOOLEAN                           InterruptState;

+

+  InterruptState = GetInterruptState ();

+  DisableInterrupts ();

+  return InterruptState;

+}

+

+/**

+  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 be enabled. FALSE if

+                          interrupts should be disabled.

+

+  @return InterruptState

+

+**/

+BOOLEAN

+EFIAPI

+SetInterruptState (

+  IN      BOOLEAN                   InterruptState

+  )

+{

+  if (InterruptState) {

+    EnableInterrupts ();

+  } else {

+    DisableInterrupts ();

+  }

+  return InterruptState;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/CpuDeadLoop.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/CpuDeadLoop.c
new file mode 100644
index 0000000..3f94405
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/CpuDeadLoop.c
@@ -0,0 +1,38 @@
+/** @file

+  Base Library CPU Functions for all architectures.

+

+  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.

+

+**/

+

+

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+

+/**

+  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

+  )

+{

+  volatile UINTN  Index;

+

+  for (Index = 0; Index == 0;);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivS64x64Remainder.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivS64x64Remainder.c
new file mode 100644
index 0000000..bb2fddc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivS64x64Remainder.c
@@ -0,0 +1,53 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivRemS64x64 (Dividend, Divisor, Remainder);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x32.c
new file mode 100644
index 0000000..3e637cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x32.c
@@ -0,0 +1,45 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivU64x32 (Dividend, Divisor);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x32Remainder.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x32Remainder.c
new file mode 100644
index 0000000..cf51f13
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x32Remainder.c
@@ -0,0 +1,49 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivRemU64x32 (Dividend, Divisor, Remainder);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x64Remainder.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x64Remainder.c
new file mode 100644
index 0000000..1366ca4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/DivU64x64Remainder.c
@@ -0,0 +1,49 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathDivRemU64x64 (Dividend, Divisor, Remainder);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/CpuBreakpoint.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/CpuBreakpoint.c
new file mode 100644
index 0000000..9b7d875
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/CpuBreakpoint.c
@@ -0,0 +1,129 @@
+/** @file

+  Base Library CPU Functions for EBC

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+extern

+UINT64

+_break (

+  CHAR8 BreakCode

+  );

+

+/**

+  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

+  )

+{

+  _break (3);

+}

+

+/**

+  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

+  )

+{

+}

+

+/**

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Retrieves the current CPU interrupt state.

+

+  Returns TRUE means interrupts are currently enabled. Otherwise,

+  returns FALSE.

+

+  @retval TRUE  CPU interrupts are enabled.

+  @retval FALSE CPU interrupts are disabled.

+

+**/

+BOOLEAN

+EFIAPI

+GetInterruptState (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+  return FALSE;

+}

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  )

+{

+  EnableInterrupts ();

+  DisableInterrupts ();

+}

+

+/**

+  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

+  )

+{

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c
new file mode 100644
index 0000000..4c0dba5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/SetJumpLongJump.c
@@ -0,0 +1,67 @@
+/** @file

+  Implementation of SetJump() and LongJump() on EBC.

+

+  SetJump() and LongJump() are not currently supported for the EBC processor type.

+  Implementation for EBC just returns 0 for SetJump(), and ASSERT() for LongJump().

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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 IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+

+  @retval 0 Indicates a return from SetJump().

+

+**/

+UINTN

+EFIAPI

+SetJump (

+  OUT      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+  )

+{

+  InternalAssertJumpBuffer (JumpBuffer);

+  return 0;

+}

+

+/**

+  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 it resumes execution based on the state of JumpBuffer.

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+  @param  Value         The value to return when the SetJump() context is restored.

+

+**/

+VOID

+EFIAPI

+InternalLongJump (

+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                     Value

+  )

+{

+  //

+  // This function cannot work on EBC

+  //

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/SwitchStack.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/SwitchStack.c
new file mode 100644
index 0000000..a6df173
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ebc/SwitchStack.c
@@ -0,0 +1,58 @@
+/** @file

+  Switch Stack functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+  Marker will be ignored on IA-32, x64, and EBC.

+  IPF CPUs 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  Marker      A VA_LIST marker for the variable argument list.

+

+**/

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,   OPTIONAL

+  IN      VOID                      *Context2,   OPTIONAL

+  IN      VOID                      *NewStack,

+  IN      VA_LIST                   Marker

+  )

+

+{

+  //

+  // This version of this function does not actually change the stack pointer

+  // This is to support compilation of CPU types that do not support assemblers

+  // such as EBC

+  //

+  EntryPoint (Context1, Context2);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/FilePaths.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/FilePaths.c
new file mode 100644
index 0000000..b7ff480
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/FilePaths.c
@@ -0,0 +1,126 @@
+/** @file

+  Defines file-path manipulation functions.

+

+  Copyright (c) 2011 - 2014, 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  <Uefi/UefiBaseType.h>

+#include  <Library/BaseMemoryLib.h>

+#include  <Library/BaseLib.h>

+#include  <Protocol/SimpleTextIn.h>

+

+/**

+  Removes the last directory or file entry in a path by changing the last

+  L'\' to a CHAR_NULL.

+

+  @param[in,out] Path     A 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

+  )

+{

+  CHAR16        *Walker;

+  CHAR16        *LastSlash;

+  //

+  // get directory name from path... ('chop' off extra)

+  //

+  for ( Walker = Path, LastSlash = NULL

+      ; Walker != NULL && *Walker != CHAR_NULL

+      ; Walker++

+     ){

+    if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {

+      LastSlash = Walker+1;

+    }

+  }

+  if (LastSlash != NULL) {

+    *LastSlash = CHAR_NULL;

+    return (TRUE);

+  }

+  return (FALSE);

+}

+

+/**

+  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 occured.

+**/

+CHAR16*

+EFIAPI

+PathCleanUpDirectories(

+  IN CHAR16 *Path

+  )

+{

+  CHAR16  *TempString;

+  UINTN   TempSize;

+

+  if (Path==NULL) {

+    return(NULL);

+  }

+  //

+  // Fix up the '/' vs '\'

+  //

+  for (TempString = Path ; TempString != NULL && *TempString != CHAR_NULL ; TempString++) {

+    if (*TempString == L'/') {

+      *TempString = L'\\';

+    }

+  }

+  //

+  // Fix up the ..

+  //

+  while ((TempString = StrStr(Path, L"\\..\\")) != NULL) {

+    *TempString = CHAR_NULL;

+    TempString  += 4;

+    PathRemoveLastItem(Path);

+    TempSize = StrSize(TempString);

+    CopyMem(Path+StrLen(Path), TempString, TempSize);

+  }

+  if ((TempString = StrStr(Path, L"\\..")) != NULL && *(TempString + 3) == CHAR_NULL) {

+    *TempString = CHAR_NULL;

+    PathRemoveLastItem(Path);

+  }

+  //

+  // Fix up the .

+  //

+  while ((TempString = StrStr(Path, L"\\.\\")) != NULL) {

+    *TempString = CHAR_NULL;

+    TempString  += 2;

+    TempSize = StrSize(TempString);

+    CopyMem(Path+StrLen(Path), TempString, TempSize);

+  }

+  if ((TempString = StrStr(Path, L"\\.")) != NULL && *(TempString + 2) == CHAR_NULL) {

+    *(TempString + 1) = CHAR_NULL;

+  }

+

+  while ((TempString = StrStr(Path, L"\\\\")) != NULL) {

+    *TempString = CHAR_NULL;

+    TempString  += 1;

+    TempSize = StrSize(TempString);

+    CopyMem(Path+StrLen(Path), TempString, TempSize);

+  }

+  if ((TempString = StrStr(Path, L"\\\\")) != NULL && *(TempString + 1) == CHAR_NULL) {

+    *(TempString) = CHAR_NULL;

+  }

+

+  return (Path);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/GetPowerOfTwo32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/GetPowerOfTwo32.c
new file mode 100644
index 0000000..913efb7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/GetPowerOfTwo32.c
@@ -0,0 +1,44 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (0 == Operand) {

+    return 0;

+  }

+

+  return 1ul << HighBitSet32 (Operand);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/GetPowerOfTwo64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/GetPowerOfTwo64.c
new file mode 100644
index 0000000..3574bc4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/GetPowerOfTwo64.c
@@ -0,0 +1,44 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Operand == 0) {

+    return 0;

+  }

+

+  return LShiftU64 (1, (UINTN) HighBitSet64 (Operand));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/HighBitSet32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/HighBitSet32.c
new file mode 100644
index 0000000..8d055fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/HighBitSet32.c
@@ -0,0 +1,47 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  INTN                              BitIndex;

+

+  if (Operand == 0) {

+    return - 1;

+  }

+  for (BitIndex = 31; (INT32)Operand > 0; BitIndex--, Operand <<= 1);

+  return BitIndex;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/HighBitSet64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/HighBitSet64.c
new file mode 100644
index 0000000..23abb73
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/HighBitSet64.c
@@ -0,0 +1,55 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Operand == (UINT32)Operand) {

+    //

+    // Operand is just a 32-bit integer

+    //

+    return HighBitSet32 ((UINT32)Operand);

+  }

+

+  //

+  // Operand is really a 64-bit integer

+  //

+  if (sizeof (UINTN) == sizeof (UINT32)) {

+    return HighBitSet32 (((UINT32*)&Operand)[1]) + 32;

+  } else {

+    return HighBitSet32 ((UINT32)RShiftU64 (Operand, 32)) + 32;

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.S
new file mode 100644
index 0000000..8f73ed4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ARShiftU64.S

+#

+# Abstract:

+#

+#   64-bit arithmetic right shift function for IA-32

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathARShiftU64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathARShiftU64 (

+#   IN      UINT64                    Operand,

+#   IN      UINTN                     Count

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathARShiftU64):

+    movb    12(%esp), %cl

+    movl    8(%esp), %eax

+    cltd

+    testb   $32, %cl

+    cmovz   %eax, %edx

+    cmovz   4(%esp), %eax

+    shrdl   %cl, %edx, %eax

+    sar     %cl, %edx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.asm
new file mode 100644
index 0000000..9d53969
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ARShiftU64.asm

+;

+; Abstract:

+;

+;   64-bit arithmetic right shift function for IA-32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathARShiftU64 (

+;   IN      UINT64                    Operand,

+;   IN      UINTN                     Count

+;   );

+;------------------------------------------------------------------------------

+InternalMathARShiftU64  PROC

+    mov     cl, [esp + 12]

+    mov     eax, [esp + 8]

+    cdq

+    test    cl, 32

+    cmovz   edx, eax

+    cmovz   eax, [esp + 4]

+    shrd    eax, edx, cl

+    sar     edx, cl

+    ret

+InternalMathARShiftU64  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.c
new file mode 100644
index 0000000..754b25f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ARShiftU64.c
@@ -0,0 +1,49 @@
+/** @file

+  64-bit arithmetic right shift function for IA-32.

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand arithmetically shifted right by Count.

+

+**/

+UINT64

+EFIAPI

+InternalMathARShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  _asm {

+    mov     cl, byte ptr [Count]

+    mov     eax, dword ptr [Operand + 4]

+    cdq

+    test    cl, 32

+    cmovz   edx, eax

+    cmovz   eax, dword ptr [Operand + 0]

+    shrd    eax, edx, cl

+    sar     edx, cl

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.asm
new file mode 100644
index 0000000..e436405
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuBreakpoint.Asm

+;

+; Abstract:

+;

+;   CpuBreakpoint function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuBreakpoint (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_CpuBreakpoint   PROC

+    int  3

+    ret

+_CpuBreakpoint   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.c
new file mode 100644
index 0000000..f5df7f2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuBreakpoint.c
@@ -0,0 +1,41 @@
+/** @file

+  CpuBreakpoint function.

+

+  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.

+

+**/

+

+

+

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+void __debugbreak ();

+

+#pragma intrinsic(__debugbreak)

+

+/**

+  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

+  )

+{

+  __debugbreak ();

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.S
new file mode 100644
index 0000000..b3b71a3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.S
@@ -0,0 +1,63 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CpuId.S

+#

+# Abstract:

+#

+#   AsmCpuid function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL  ASM_PFX(AsmCpuid)

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  AsmCpuid (

+#    IN   UINT32  RegisterInEax,

+#    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(AsmCpuid):

+    push    %ebx

+    push    %ebp

+    movl    %esp, %ebp

+    movl    12(%ebp), %eax

+    cpuid

+    push    %ecx

+    movl    16(%ebp), %ecx

+    jecxz   L1

+    movl    %eax, (%ecx)

+L1:

+    movl    20(%ebp), %ecx

+    jecxz   L2

+    movl    %ebx, (%ecx)

+L2:

+    movl    24(%ebp), %ecx

+    jecxz   L3

+    popl    (%ecx)

+L3:

+    movl    28(%ebp), %ecx

+    jecxz   L4

+    movl    %edx, (%ecx)

+L4:

+    movl    12(%ebp), %eax

+    leave

+    pop     %ebx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.asm
new file mode 100644
index 0000000..0141cb2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuId.Asm

+;

+; Abstract:

+;

+;   AsmCpuid function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  AsmCpuid (

+;    IN   UINT32  RegisterInEax,

+;    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+;    );

+;------------------------------------------------------------------------------

+AsmCpuid    PROC    USES    ebx

+    push    ebp

+    mov     ebp, esp

+    mov     eax, [ebp + 12]

+    cpuid

+    push    ecx

+    mov     ecx, [ebp + 16]

+    jecxz   @F

+    mov     [ecx], eax

+@@:

+    mov     ecx, [ebp + 20]

+    jecxz   @F

+    mov     [ecx], ebx

+@@:

+    mov     ecx, [ebp + 24]

+    jecxz   @F

+    pop     [ecx]

+@@:

+    mov     ecx, [ebp + 28]

+    jecxz   @F

+    mov     [ecx], edx

+@@:

+    mov     eax, [ebp + 12]

+    leave

+    ret

+AsmCpuid    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.c
new file mode 100644
index 0000000..09487f7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuId.c
@@ -0,0 +1,74 @@
+/** @file

+  AsmCpuid function.

+

+  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.

+

+**/

+

+/**

+  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  RegisterEax   A pointer to the 32-bit EAX value returned by the CPUID

+                        instruction. This is an optional parameter that may be NULL.

+  @param  RegisterEbx   A pointer to the 32-bit EBX value returned by the CPUID

+                        instruction. This is an optional parameter that may be NULL.

+  @param  RegisterEcx   A pointer to the 32-bit ECX value returned by the CPUID

+                        instruction. This is an optional parameter that may be NULL.

+  @param  RegisterEdx   A 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                    *RegisterEax,  OPTIONAL

+  OUT     UINT32                    *RegisterEbx,  OPTIONAL

+  OUT     UINT32                    *RegisterEcx,  OPTIONAL

+  OUT     UINT32                    *RegisterEdx   OPTIONAL

+  )

+{

+  _asm {

+    mov     eax, Index

+    cpuid

+    push    ecx

+    mov     ecx, RegisterEax

+    jecxz   SkipEax

+    mov     [ecx], eax

+SkipEax:

+    mov     ecx, RegisterEbx

+    jecxz   SkipEbx

+    mov     [ecx], ebx

+SkipEbx:

+    pop     eax

+    mov     ecx, RegisterEcx

+    jecxz   SkipEcx

+    mov     [ecx], eax

+SkipEcx:

+    mov     ecx, RegisterEdx

+    jecxz   SkipEdx

+    mov     [ecx], edx

+SkipEdx:

+    mov     eax, Index

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.S
new file mode 100644
index 0000000..0d34c56
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.S
@@ -0,0 +1,67 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CpuIdEx.S

+#

+# Abstract:

+#

+#   AsmCpuidEx function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+    .code:

+

+#------------------------------------------------------------------------------

+#  UINT32

+#  EFIAPI

+#  AsmCpuidEx (

+#    IN   UINT32  RegisterInEax,

+#    IN   UINT32  RegisterInEcx,

+#    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmCpuidEx)

+ASM_PFX(AsmCpuidEx):

+    push    %ebx

+    push    %ebp

+    movl    %esp, %ebp

+    movl    12(%ebp), %eax

+    movl    16(%ebp), %ecx

+    cpuid

+    push    %ecx

+    movl    20(%ebp), %ecx

+    jecxz   L1

+    movl    %eax, (%ecx)

+L1:

+    movl    24(%ebp), %ecx

+    jecxz   L2

+    movl    %ebx, (%ecx)

+L2:

+    movl    32(%ebp), %ecx

+    jecxz   L3

+    movl    %edx, (%ecx)

+L3:

+    movl    28(%ebp), %ecx

+    jecxz   L4

+    popl    (%ecx)

+L4:

+    movl    12(%ebp), %eax

+    leave

+    pop     %ebx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.asm
new file mode 100644
index 0000000..504b397
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.asm
@@ -0,0 +1,68 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CpuIdEx.Asm

+;

+; Abstract:

+;

+;   AsmCpuidEx function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  UINT32

+;  EFIAPI

+;  AsmCpuidEx (

+;    IN   UINT32  RegisterInEax,

+;    IN   UINT32  RegisterInEcx,

+;    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+;    )

+;------------------------------------------------------------------------------

+AsmCpuidEx  PROC    USES    ebx

+    push    ebp

+    mov     ebp, esp

+    mov     eax, [ebp + 12]

+    mov     ecx, [ebp + 16]

+    cpuid

+    push    ecx

+    mov     ecx, [ebp + 20]

+    jecxz   @F

+    mov     [ecx], eax

+@@:

+    mov     ecx, [ebp + 24]

+    jecxz   @F

+    mov     [ecx], ebx

+@@:

+    mov     ecx, [ebp + 32]

+    jecxz   @F

+    mov     [ecx], edx

+@@:

+    mov     ecx, [ebp + 28]

+    jecxz   @F

+    pop     [ecx]

+@@:

+    mov     eax, [ebp + 12]

+    leave

+    ret

+AsmCpuidEx  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.c
new file mode 100644
index 0000000..9f6463d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuIdEx.c
@@ -0,0 +1,82 @@
+/** @file

+  AsmCpuidEx function.

+

+  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.

+

+**/

+

+/**

+  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  RegisterEax   A pointer to the 32-bit EAX value returned by the CPUID

+                        instruction. This is an optional parameter that may be

+                        NULL.

+  @param  RegisterEbx   A pointer to the 32-bit EBX value returned by the CPUID

+                        instruction. This is an optional parameter that may be

+                        NULL.

+  @param  RegisterEcx   A pointer to the 32-bit ECX value returned by the CPUID

+                        instruction. This is an optional parameter that may be

+                        NULL.

+  @param  RegisterEdx   A 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                    *RegisterEax,  OPTIONAL

+  OUT     UINT32                    *RegisterEbx,  OPTIONAL

+  OUT     UINT32                    *RegisterEcx,  OPTIONAL

+  OUT     UINT32                    *RegisterEdx   OPTIONAL

+  )

+{

+  _asm {

+    mov     eax, Index

+    mov     ecx, SubIndex

+    cpuid

+    push    ecx

+    mov     ecx, RegisterEax

+    jecxz   SkipEax

+    mov     [ecx], eax

+SkipEax:

+    mov     ecx, RegisterEbx

+    jecxz   SkipEbx

+    mov     [ecx], ebx

+SkipEbx:

+    pop     eax

+    mov     ecx, RegisterEcx

+    jecxz   SkipEcx

+    mov     [ecx], eax

+SkipEcx:

+    mov     ecx, RegisterEdx

+    jecxz   SkipEdx

+    mov     [ecx], edx

+SkipEdx:

+    mov     eax, Index

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.asm
new file mode 100644
index 0000000..7a5aef5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuPause.Asm

+;

+; Abstract:

+;

+;   CpuPause function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuPause (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuPause    PROC

+    pause

+    ret

+CpuPause    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.c
new file mode 100644
index 0000000..056dde4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/CpuPause.c
@@ -0,0 +1,35 @@
+/** @file

+  CpuPause function.

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    pause

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.S
new file mode 100644
index 0000000..5f86da4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.S
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   DisableCache.S

+#

+# Abstract:

+#

+#   Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a

+#   WBINVD instruction.

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmDisableCache (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmDisableCache)

+ASM_PFX(AsmDisableCache):

+    movl    %cr0, %eax

+    btsl    $30, %eax

+    btrl    $29, %eax

+    movl    %eax, %cr0

+    wbinvd

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.asm
new file mode 100644
index 0000000..1d1c9e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   DisableCache.Asm

+;

+; Abstract:

+;

+;   Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a

+;   WBINVD instruction.

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmDisableCache (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmDisableCache PROC

+    mov     eax, cr0

+    bts     eax, 30

+    btr     eax, 29

+    mov     cr0, eax

+    wbinvd

+    ret

+AsmDisableCache ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.c
new file mode 100644
index 0000000..dbfb429
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableCache.c
@@ -0,0 +1,36 @@
+/** @file

+  AsmDisableCache function

+

+  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.

+

+**/

+

+/**

+  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

+  )

+{

+  _asm {

+    mov     eax, cr0

+    bts     eax, 30

+    btr     eax, 29

+    mov     cr0, eax

+    wbinvd

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.asm
new file mode 100644
index 0000000..823d0dd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DisableInterrupts.Asm

+;

+; Abstract:

+;

+;   DisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; DisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+DisableInterrupts   PROC

+    cli

+    ret

+DisableInterrupts   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.c
new file mode 100644
index 0000000..d30ab5d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisableInterrupts.c
@@ -0,0 +1,32 @@
+/** @file

+  DisableInterrupts function.

+

+  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.

+

+**/

+

+

+

+

+/**

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{

+  _asm {

+    cli

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.S
new file mode 100644
index 0000000..c6daf6a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   DisablePaging32.S

+#

+# Abstract:

+#

+#   InternalX86DisablePaging32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalX86DisablePaging32)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalX86DisablePaging32 (

+#   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+#   IN      VOID                      *Context1,    OPTIONAL

+#   IN      VOID                      *Context2,    OPTIONAL

+#   IN      VOID                      *NewStack

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalX86DisablePaging32):

+    movl    4(%esp), %ebx

+    movl    8(%esp), %ecx

+    movl    12(%esp), %edx

+    pushfl

+    pop     %edi                        # save EFLAGS to edi

+    cli

+    movl    %cr0, %eax

+    btrl    $31, %eax

+    movl    16(%esp), %esp

+    movl    %eax, %cr0

+    push    %edi

+    popfl                               # restore EFLAGS from edi

+    push    %edx

+    push    %ecx

+    call    *%ebx

+    jmp     .                           # EntryPoint() should not return

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.asm
new file mode 100644
index 0000000..5a3887e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DisablePaging32.Asm

+;

+; Abstract:

+;

+;   AsmDisablePaging32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86DisablePaging32 (

+;   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+;   IN      VOID                      *Context1,    OPTIONAL

+;   IN      VOID                      *Context2,    OPTIONAL

+;   IN      VOID                      *NewStack

+;   );

+;------------------------------------------------------------------------------

+InternalX86DisablePaging32    PROC

+    mov     ebx, [esp + 4]

+    mov     ecx, [esp + 8]

+    mov     edx, [esp + 12]

+    pushfd

+    pop     edi                         ; save EFLAGS to edi

+    cli

+    mov     eax, cr0

+    btr     eax, 31

+    mov     esp, [esp + 16]

+    mov     cr0, eax

+    push    edi

+    popfd                               ; restore EFLAGS from edi

+    push    edx

+    push    ecx

+    call    ebx

+    jmp     $                           ; EntryPoint() should not return

+InternalX86DisablePaging32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.c
new file mode 100644
index 0000000..26e9bd5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DisablePaging32.c
@@ -0,0 +1,77 @@
+/** @file

+  AsmDisablePaging32 function.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+

+  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.

+

+**/

+__declspec (naked)

+VOID

+EFIAPI

+InternalX86DisablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,    OPTIONAL

+  IN      VOID                      *Context2,    OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  _asm {

+    push    ebp

+    mov     ebp, esp

+    mov     ebx, EntryPoint

+    mov     ecx, Context1

+    mov     edx, Context2

+    pushfd

+    pop     edi                         // save EFLAGS to edi

+    cli

+    mov     eax, cr0

+    btr     eax, 31

+    mov     esp, NewStack

+    mov     cr0, eax

+    push    edi

+    popfd                               // restore EFLAGS from edi

+    push    edx

+    push    ecx

+    call    ebx

+    jmp     $                           // EntryPoint() should not return

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivS64x64Remainder.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivS64x64Remainder.c
new file mode 100644
index 0000000..cca08ed
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivS64x64Remainder.c
@@ -0,0 +1,53 @@
+/** @file

+  Integer division worker functions for Ia32.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  Worker function that 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.

+

+  @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

+InternalMathDivRemS64x64 (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder  OPTIONAL

+  )

+{

+  INT64                             Quot;

+

+  Quot = InternalMathDivRemU64x64 (

+           (UINT64) (Dividend >= 0 ? Dividend : -Dividend),

+           (UINT64) (Divisor >= 0 ? Divisor : -Divisor),

+           (UINT64 *) Remainder

+           );

+  if (Remainder != NULL && Dividend < 0) {

+    *Remainder = -*Remainder;

+  }

+  return (Dividend ^ Divisor) >= 0 ? Quot : -Quot;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.S
new file mode 100644
index 0000000..5d3f452
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   DivU64x32.S

+#

+# Abstract:

+#

+#   Calculate the quotient of a 64-bit integer by a 32-bit integer

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathDivU64x32)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathDivU64x32 (

+#   IN      UINT64                    Dividend,

+#   IN      UINT32                    Divisor

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathDivU64x32):

+    movl    8(%esp), %eax

+    movl    12(%esp), %ecx

+    xorl    %edx, %edx

+    divl    %ecx

+    push    %eax                    # save quotient on stack

+    movl    8(%esp), %eax

+    divl    %ecx

+    pop     %edx                    # restore high-order dword of the quotient

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.asm
new file mode 100644
index 0000000..b479383
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DivU64x32.asm

+;

+; Abstract:

+;

+;   Calculate the quotient of a 64-bit integer by a 32-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathDivU64x32 (

+;   IN      UINT64                    Dividend,

+;   IN      UINT32                    Divisor

+;   );

+;------------------------------------------------------------------------------

+InternalMathDivU64x32   PROC

+    mov     eax, [esp + 8]

+    mov     ecx, [esp + 12]

+    xor     edx, edx

+    div     ecx

+    push    eax                     ; save quotient on stack

+    mov     eax, [esp + 8]

+    div     ecx

+    pop     edx                     ; restore high-order dword of the quotient

+    ret

+InternalMathDivU64x32   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.c
new file mode 100644
index 0000000..3c3620b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32.c
@@ -0,0 +1,50 @@
+/** @file

+  Calculate the quotient of a 64-bit integer by a 32-bit integer

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend / Divisor

+

+**/

+UINT64

+EFIAPI

+InternalMathDivU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  _asm {

+    mov     eax, dword ptr [Dividend + 4]

+    mov     ecx, Divisor

+    xor     edx, edx

+    div     ecx

+    push    eax                     ; save quotient on stack

+    mov     eax, dword ptr [Dividend]

+    div     ecx

+    pop     edx                     ; restore high-order dword of the quotient

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.S
new file mode 100644
index 0000000..d9eb8e9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   DivError.S

+#

+# Abstract:

+#

+#   Set error flag for all division functions

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathDivRemU64x32)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathDivRemU64x32 (

+#   IN      UINT64                    Dividend,

+#   IN      UINT32                    Divisor,

+#   OUT     UINT32                    *Remainder

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathDivRemU64x32):

+    movl    12(%esp), %ecx          # ecx <- divisor

+    movl    8(%esp), %eax           # eax <- dividend[32..63]

+    xorl    %edx, %edx

+    divl    %ecx                    # eax <- quotient[32..63], edx <- remainder

+    push    %eax

+    movl    8(%esp), %eax           # eax <- dividend[0..31]

+    divl    %ecx                    # eax <- quotient[0..31]

+    movl    20(%esp), %ecx          # ecx <- Remainder

+    jecxz   L1                      # abandon remainder if Remainder == NULL

+    movl    %edx, (%ecx)

+L1:

+    pop     %edx                    # edx <- quotient[32..63]

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm
new file mode 100644
index 0000000..30b0417
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm
@@ -0,0 +1,51 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DivError.asm

+;

+; Abstract:

+;

+;   Set error flag for all division functions

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathDivRemU64x32 (

+;   IN      UINT64                    Dividend,

+;   IN      UINT32                    Divisor,

+;   OUT     UINT32                    *Remainder

+;   );

+;------------------------------------------------------------------------------

+InternalMathDivRemU64x32    PROC

+    mov     ecx, [esp + 12]         ; ecx <- divisor

+    mov     eax, [esp + 8]          ; eax <- dividend[32..63]

+    xor     edx, edx

+    div     ecx                     ; eax <- quotient[32..63], edx <- remainder

+    push    eax

+    mov     eax, [esp + 8]          ; eax <- dividend[0..31]

+    div     ecx                     ; eax <- quotient[0..31]

+    mov     ecx, [esp + 20]         ; ecx <- Remainder

+    jecxz   @F                      ; abandon remainder if Remainder == NULL

+    mov     [ecx], edx

+@@:

+    pop     edx                     ; edx <- quotient[32..63]

+    ret

+InternalMathDivRemU64x32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.c
new file mode 100644
index 0000000..87eef8b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.c
@@ -0,0 +1,55 @@
+/** @file

+  Set error flag for all division functions

+

+  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.

+

+**/

+

+/**

+  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.

+

+  @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

+InternalMathDivRemU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor,

+  OUT     UINT32                    *Remainder

+  )

+{

+  _asm {

+    mov     ecx, Divisor

+    mov     eax, dword ptr [Dividend + 4]

+    xor     edx, edx

+    div     ecx

+    push    eax

+    mov     eax, dword ptr [Dividend + 0]

+    div     ecx

+    mov     ecx, Remainder

+    jecxz   RemainderNull                      // abandon remainder if Remainder == NULL

+    mov     [ecx], edx

+RemainderNull:

+    pop     edx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.S
new file mode 100644
index 0000000..f4df094
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.S
@@ -0,0 +1,89 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   DivU64x64Remainder.S

+#

+# Abstract:

+#

+#   Calculate the quotient of a 64-bit integer by a 64-bit integer and returns

+#   both the quotient and the remainder

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathDivRemU64x32), ASM_PFX(InternalMathDivRemU64x64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathDivRemU64x64 (

+#   IN      UINT64                    Dividend,

+#   IN      UINT64                    Divisor,

+#   OUT     UINT64                    *Remainder    OPTIONAL

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathDivRemU64x64):

+    movl    16(%esp), %ecx              # ecx <- divisor[32..63]

+    testl   %ecx, %ecx

+    jnz     Hard                        # call _@DivRemU64x64 if Divisor > 2^32

+    movl    20(%esp), %ecx

+    jecxz   L1

+    andl     $0, 4(%ecx)                # zero high dword of remainder

+    movl    %ecx, 16(%esp)              # set up stack frame to match DivRemU64x32

+L1:

+    jmp     ASM_PFX(InternalMathDivRemU64x32)

+Hard:

+    push    %ebx

+    push    %esi

+    push    %edi

+    mov     20(%esp), %edx

+    mov     16(%esp), %eax              # edx:eax <- dividend

+    movl    %edx, %edi

+    movl    %eax, %esi                  # edi:esi <- dividend

+    mov     24(%esp), %ebx              # ecx:ebx <- divisor

+L2:

+    shrl    %edx

+    rcrl    $1, %eax

+    shrdl   $1, %ecx, %ebx

+    shrl    %ecx

+    jnz     L2

+    divl    %ebx

+    movl    %eax, %ebx                  # ebx <- quotient                     

+    movl    28(%esp), %ecx              # ecx <- high dword of divisor        

+    mull    24(%esp)                    # edx:eax <- quotient * divisor[0..31]

+    imull   %ebx, %ecx                  # ecx <- quotient * divisor[32..63]   

+    addl    %ecx, %edx                  # edx <- (quotient * divisor)[32..63] 

+    mov     32(%esp), %ecx              # ecx <- addr for Remainder           

+    jc      TooLarge                    # product > 2^64                      

+    cmpl    %edx, %edi                  # compare high 32 bits                

+    ja      Correct                                                           

+    jb      TooLarge                    # product > dividend                  

+    cmpl    %eax, %esi                                                        

+    jae     Correct                     # product <= dividend                 

+TooLarge:

+    decl    %ebx                        # adjust quotient by -1              

+    jecxz   Return                      # return if Remainder == NULL        

+    sub     24(%esp), %eax                                                   

+    sbb     28(%esp), %edx              # edx:eax <- (quotient - 1) * divisor

+Correct:

+    jecxz   Return

+    subl    %eax, %esi

+    sbbl    %edx, %edi                  # edi:esi <- remainder

+    movl    %esi, (%ecx)

+    movl    %edi, 4(%ecx)

+Return:

+    movl    %ebx, %eax                  # eax <- quotient         

+    xorl    %edx, %edx                  # quotient is 32 bits long

+    pop     %edi

+    pop     %esi

+    pop     %ebx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm
new file mode 100644
index 0000000..98dddb0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm
@@ -0,0 +1,92 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DivU64x64Remainder.asm

+;

+; Abstract:

+;

+;   Calculate the quotient of a 64-bit integer by a 64-bit integer and returns

+;   both the quotient and the remainder

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+EXTERN  InternalMathDivRemU64x32:PROC

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathDivRemU64x64 (

+;   IN      UINT64                    Dividend,

+;   IN      UINT64                    Divisor,

+;   OUT     UINT64                    *Remainder    OPTIONAL

+;   );

+;------------------------------------------------------------------------------

+InternalMathDivRemU64x64    PROC

+    mov     ecx, [esp + 16]             ; ecx <- divisor[32..63]

+    test    ecx, ecx

+    jnz     _@DivRemU64x64              ; call _@DivRemU64x64 if Divisor > 2^32

+    mov     ecx, [esp + 20]

+    jecxz   @F

+    and     dword ptr [ecx + 4], 0      ; zero high dword of remainder

+    mov     [esp + 16], ecx             ; set up stack frame to match DivRemU64x32

+@@:

+    jmp     InternalMathDivRemU64x32

+InternalMathDivRemU64x64    ENDP

+

+_@DivRemU64x64  PROC    USES    ebx esi edi

+    mov     edx, dword ptr [esp + 20]

+    mov     eax, dword ptr [esp + 16]   ; edx:eax <- dividend

+    mov     edi, edx

+    mov     esi, eax                    ; edi:esi <- dividend

+    mov     ebx, dword ptr [esp + 24]   ; ecx:ebx <- divisor

+@@:

+    shr     edx, 1

+    rcr     eax, 1

+    shrd    ebx, ecx, 1

+    shr     ecx, 1

+    jnz     @B

+    div     ebx

+    mov     ebx, eax                    ; ebx <- quotient

+    mov     ecx, [esp + 28]             ; ecx <- high dword of divisor

+    mul     dword ptr [esp + 24]        ; edx:eax <- quotient * divisor[0..31]

+    imul    ecx, ebx                    ; ecx <- quotient * divisor[32..63]

+    add     edx, ecx                    ; edx <- (quotient * divisor)[32..63]

+    mov     ecx, dword ptr [esp + 32]   ; ecx <- addr for Remainder

+    jc      @TooLarge                   ; product > 2^64

+    cmp     edi, edx                    ; compare high 32 bits

+    ja      @Correct

+    jb      @TooLarge                   ; product > dividend

+    cmp     esi, eax

+    jae     @Correct                    ; product <= dividend

+@TooLarge:

+    dec     ebx                         ; adjust quotient by -1

+    jecxz   @Return                     ; return if Remainder == NULL

+    sub     eax, dword ptr [esp + 24]

+    sbb     edx, dword ptr [esp + 28]   ; edx:eax <- (quotient - 1) * divisor

+@Correct:

+    jecxz   @Return

+    sub     esi, eax

+    sbb     edi, edx                    ; edi:esi <- remainder

+    mov     [ecx], esi

+    mov     [ecx + 4], edi

+@Return:

+    mov     eax, ebx                    ; eax <- quotient

+    xor     edx, edx                    ; quotient is 32 bits long

+    ret

+_@DivRemU64x64  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.S
new file mode 100644
index 0000000..bc3aa2f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.S
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   EnableCache.S

+#

+# Abstract:

+#

+#   Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear 

+#   the NW bit of CR0 to 0

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmEnableCache (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmEnableCache)

+ASM_PFX(AsmEnableCache):

+    wbinvd

+    movl    %cr0, %eax

+    btrl    $30, %eax

+    btrl    $29, %eax

+    movl    %eax, %cr0

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.asm
new file mode 100644
index 0000000..238431c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   EnableCache.Asm

+;

+; Abstract:

+;

+;  Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear 

+;  the NW bit of CR0 to 0

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmEnableCache (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmEnableCache PROC

+    wbinvd

+    mov     eax, cr0

+    btr     eax, 29

+    btr     eax, 30

+    mov     cr0, eax

+    ret

+AsmEnableCache ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.c
new file mode 100644
index 0000000..ec4ea45
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableCache.c
@@ -0,0 +1,36 @@
+/** @file

+  AsmEnableCache function

+

+  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.

+

+**/

+

+/**

+  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

+  )

+{

+  _asm {

+    wbinvd

+    mov     eax, cr0

+    btr     eax, 30

+    btr     eax, 29

+    mov     cr0, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.S
new file mode 100644
index 0000000..bc89c25
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   EnableDisableInterrupts.S

+#

+# Abstract:

+#

+#   EnableDisableInterrupts function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(EnableDisableInterrupts)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# EnableDisableInterrupts (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(EnableDisableInterrupts):

+    sti

+    cli

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.asm
new file mode 100644
index 0000000..e54f14e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   EnableDisableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableDisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableDisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_EnableDisableInterrupts    PROC

+    sti

+    cli

+    ret

+_EnableDisableInterrupts    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.c
new file mode 100644
index 0000000..d085d8d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableDisableInterrupts.c
@@ -0,0 +1,36 @@
+/** @file

+  EnableDisableInterrupts function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  )

+{

+  _asm {

+    sti

+    nop

+    nop

+    cli

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.S
new file mode 100644
index 0000000..3caf7ec
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   EnableInterrupts.S

+#

+# Abstract:

+#

+#   EnableInterrupts function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(EnableInterrupts)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# EnableInterrupts (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(EnableInterrupts):

+    sti

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.asm
new file mode 100644
index 0000000..58fc72d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   EnableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_EnableInterrupts   PROC

+    sti

+    ret

+_EnableInterrupts   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.c
new file mode 100644
index 0000000..f2f6430
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnableInterrupts.c
@@ -0,0 +1,32 @@
+/** @file

+  EnableInterrupts function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  _asm {

+    sti

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.S
new file mode 100644
index 0000000..1a168c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   EnablePaging32.S

+#

+# Abstract:

+#

+#   InternalX86EnablePaging32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalX86EnablePaging32)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalX86EnablePaging32 (

+#   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+#   IN      VOID                      *Context1,    OPTIONAL

+#   IN      VOID                      *Context2,    OPTIONAL

+#   IN      VOID                      *NewStack

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalX86EnablePaging32):

+    movl    4(%esp), %ebx

+    movl    8(%esp), %ecx

+    movl    12(%esp), %edx

+    pushfl

+    pop     %edi                        # save flags in edi

+    cli

+    movl    %cr0, %eax

+    btsl    $31, %eax

+    movl    16(%esp), %esp

+    movl    %eax, %cr0

+    push    %edi

+    popfl                               # restore flags

+    push    %edx

+    push    %ecx

+    call    *%ebx

+    jmp     .

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm
new file mode 100644
index 0000000..e8db4b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   EnablePaging32.Asm

+;

+; Abstract:

+;

+;   AsmEnablePaging32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86EnablePaging32 (

+;   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+;   IN      VOID                      *Context1,    OPTIONAL

+;   IN      VOID                      *Context2,    OPTIONAL

+;   IN      VOID                      *NewStack

+;   );

+;------------------------------------------------------------------------------

+InternalX86EnablePaging32 PROC

+    mov     ebx, [esp + 4]

+    mov     ecx, [esp + 8]

+    mov     edx, [esp + 12]

+    pushfd

+    pop     edi                         ; save flags in edi

+    cli

+    mov     eax, cr0

+    bts     eax, 31

+    mov     esp, [esp + 16]

+    mov     cr0, eax

+    push    edi

+    popfd                               ; restore flags

+    push    edx

+    push    ecx

+    call    ebx

+    jmp     $

+InternalX86EnablePaging32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.c
new file mode 100644
index 0000000..d0c2e94
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.c
@@ -0,0 +1,81 @@
+/** @file

+  AsmEnablePaging32 function

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+

+  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.

+

+**/

+__declspec (naked)

+VOID

+EFIAPI

+InternalX86EnablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,    OPTIONAL

+  IN      VOID                      *Context2,    OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  _asm {

+    push    ebp

+    mov     ebp, esp

+    mov     ebx, EntryPoint

+    mov     ecx, Context1

+    mov     edx, Context2

+    pushfd

+    pop     edi

+    cli

+    mov     eax, cr0

+    bts     eax, 31

+    mov     esp, NewStack

+    mov     cr0, eax

+    push    edi

+    popfd

+    push    edx

+    push    ecx

+    call    ebx

+    jmp     $

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.S
new file mode 100644
index 0000000..08950ce
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.S
@@ -0,0 +1,63 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   EnablePaging64.S

+#

+# Abstract:

+#

+#   InternalX86EnablePaging64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalX86EnablePaging64)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalX86EnablePaging64 (

+#   IN      UINT16                    CodeSelector,

+#   IN      UINT64                    EntryPoint,

+#   IN      UINT64                    Context1,    OPTIONAL

+#   IN      UINT64                    Context2,    OPTIONAL

+#   IN      UINT64                    NewStack

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalX86EnablePaging64):

+    cli

+    movl    $LongStart, (%esp)          # offset for far retf, seg is the 1st arg

+    movl    %cr4, %eax

+    orb     $0x20, %al

+    movl    %eax, %cr4                  # enable PAE

+    movl    $0xc0000080, %ecx

+    rdmsr

+    orb     $1, %ah                     # set LME

+    wrmsr

+    movl    %cr0, %eax

+    btsl    $31, %eax                   # set PG

+    movl    %eax, %cr0                  # enable paging

+    lret                                # topmost 2 dwords hold the address

+LongStart:                              # long mode starts here

+    .byte   0x67, 0x48                  # 32-bit address size, 64-bit operand size

+    movl    (%esp), %ebx                # mov rbx, [esp]

+    .byte   0x67, 0x48

+    movl    8(%esp), %ecx               # mov rcx, [esp + 8]

+    .byte   0x67, 0x48

+    movl    0x10(%esp), %edx            # mov rdx, [esp + 10h]

+    .byte   0x67, 0x48

+    movl    0x18(%esp), %esp            # mov rsp, [esp + 18h]

+    .byte   0x48

+    addl    $-0x20, %esp                # add rsp, -20h

+    call    *%ebx                       # call rbx

+    jmp     .                           # no one should get here

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm
new file mode 100644
index 0000000..5cc1d6b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm
@@ -0,0 +1,68 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   EnablePaging64.Asm

+;

+; Abstract:

+;

+;   AsmEnablePaging64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86EnablePaging64 (

+;   IN      UINT16                    Cs,

+;   IN      UINT64                    EntryPoint,

+;   IN      UINT64                    Context1,  OPTIONAL

+;   IN      UINT64                    Context2,  OPTIONAL

+;   IN      UINT64                    NewStack

+;   );

+;------------------------------------------------------------------------------

+InternalX86EnablePaging64 PROC

+    cli

+    mov     [esp], @F                   ; offset for far retf, seg is the 1st arg

+    mov     eax, cr4

+    or      al, (1 SHL 5)

+    mov     cr4, eax                    ; enable PAE

+    mov     ecx, 0c0000080h

+    rdmsr

+    or      ah, 1                       ; set LME

+    wrmsr

+    mov     eax, cr0

+    bts     eax, 31                     ; set PG

+    mov     cr0, eax                    ; enable paging

+    retf                                ; topmost 2 dwords hold the address

+@@:                                     ; long mode starts here

+    DB      67h, 48h                    ; 32-bit address size, 64-bit operand size

+    mov     ebx, [esp]                  ; mov rbx, [esp]

+    DB      67h, 48h

+    mov     ecx, [esp + 8]              ; mov rcx, [esp + 8]

+    DB      67h, 48h

+    mov     edx, [esp + 10h]            ; mov rdx, [esp + 10h]

+    DB      67h, 48h

+    mov     esp, [esp + 18h]            ; mov rsp, [esp + 18h]

+    DB      48h

+    add     esp, -20h                   ; add rsp, -20h

+    call    ebx                         ; call rbx

+    hlt                                 ; no one should get here

+InternalX86EnablePaging64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.asm
new file mode 100644
index 0000000..124d761
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   FlushCacheLine.Asm

+;

+; Abstract:

+;

+;   AsmFlushCacheLine function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID *

+; EFIAPI

+; AsmFlushCacheLine (

+;   IN      VOID                      *LinearAddress

+;   );

+;------------------------------------------------------------------------------

+AsmFlushCacheLine   PROC

+    mov     eax, [esp + 4]

+    clflush [eax]

+    ret

+AsmFlushCacheLine   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.c
new file mode 100644
index 0000000..3b3a433
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FlushCacheLine.c
@@ -0,0 +1,44 @@
+/** @file

+  AsmFlushCacheLine function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    mov     eax, LinearAddress

+    clflush [eax]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm
new file mode 100644
index 0000000..5b773d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   FxRestore.Asm

+;

+; Abstract:

+;

+;   AsmFxRestore function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86FxRestore (

+;   IN CONST IA32_FX_BUFFER *Buffer

+;   );

+;------------------------------------------------------------------------------

+InternalX86FxRestore  PROC

+    mov     eax, [esp + 4]              ; Buffer must be 16-byte aligned

+    fxrstor [eax]

+    ret

+InternalX86FxRestore  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.c
new file mode 100644
index 0000000..abfc6cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.c
@@ -0,0 +1,40 @@
+/** @file

+  AsmFxRestore function

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxRestore (

+  IN CONST IA32_FX_BUFFER *Buffer

+  )

+{

+  _asm {

+    mov     eax, Buffer

+    fxrstor [eax]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm
new file mode 100644
index 0000000..417106a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   FxSave.Asm

+;

+; Abstract:

+;

+;   AsmFxSave function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86FxSave (

+;   OUT IA32_FX_BUFFER *Buffer

+;   );

+;------------------------------------------------------------------------------

+InternalX86FxSave PROC

+    mov     eax, [esp + 4]              ; Buffer must be 16-byte aligned

+    fxsave  [eax]

+    ret

+InternalX86FxSave ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxSave.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxSave.c
new file mode 100644
index 0000000..74949f2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/FxSave.c
@@ -0,0 +1,40 @@
+/** @file

+  AsmFxSave function

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxSave (

+  OUT IA32_FX_BUFFER *Buffer

+  )

+{

+  _asm {

+    mov     eax, Buffer

+    fxsave  [eax]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/GccInline.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/GccInline.c
new file mode 100644
index 0000000..02af3f6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/GccInline.c
@@ -0,0 +1,1758 @@
+/** @file

+  GCC inline implementation of BaseLib processor specific functions.

+  

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+

+/**

+  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

+  )

+{

+  // This is a little bit of overkill and it is more about the compiler that it is

+  // actually processor synchronization. This is like the _ReadWriteBarrier 

+  // Microsoft specific intrinsic

+  __asm__ __volatile__ ("":::"memory");

+}

+

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("sti"::: "memory");

+}

+

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{  

+  __asm__ __volatile__ ("cli"::: "memory");

+}

+

+

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ ("pause");

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ ("int $3");

+}

+

+

+

+/**

+  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

+  )

+{

+  UINT64 Data;

+  

+  __asm__ __volatile__ (

+    "rdmsr"

+    : "=A" (Data)   // %0

+    : "c"  (Index)  // %1

+    );

+    

+  return Data;

+}

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "wrmsr"

+    :

+    : "c" (Index),

+      "A" (Value)

+    );

+    

+  return Value;

+}

+

+

+

+/**

+  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

+  )

+{

+  UINTN Eflags;

+  

+  __asm__ __volatile__ (

+    "pushfl     \n\t"

+    "popl %0        "

+    : "=r" (Eflags)

+    );

+    

+  return Eflags;

+}

+

+

+

+/**

+  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

+  )

+{

+  UINTN   Data;

+  

+  __asm__ __volatile__ (

+    "movl %%cr0,%0" 

+    : "=a" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%cr2, %0" 

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%cr3, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%cr4, %0"

+    : "=a" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%cr0"

+    :

+    : "r" (Cr0)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%cr2"

+    :

+    : "r" (Cr2)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%cr3"

+    :

+    : "r" (Cr3)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%cr4"

+    :

+    : "r" (Cr4)

+    );

+  return 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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr0, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr1, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr2, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr3, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr4, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr5, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr6, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "movl %%dr7, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr0"

+    :

+    : "r" (Dr0)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr1"

+    :

+    : "r" (Dr1)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr2"

+    :

+    : "r" (Dr2)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr3"

+    :

+    : "r" (Dr3)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr4"

+    :

+    : "r" (Dr4)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr5"

+    :

+    : "r" (Dr5)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr6"

+    :

+    : "r" (Dr6)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "movl %0, %%dr7"

+    :

+    : "r" (Dr7)

+    );

+  return 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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov   %%cs, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%ds, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%es, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%fs, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%gs, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%ds, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "str  %0"

+    : "=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadGdtr (

+  OUT     IA32_DESCRIPTOR           *Gdtr

+  )

+{

+  __asm__ __volatile__ (

+    "sgdt %0"

+    : "=m" (*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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  )

+{

+  __asm__ __volatile__ (

+    "lgdt %0"

+    :

+    : "m" (*Gdtr)

+    );

+    

+}

+

+

+/**

+  Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current IDTR descriptor and returns it in Idtr. This

+  function is only available on IA-32 and X64.

+

+  @param  Idtr  The pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  )

+{

+  __asm__ __volatile__ (

+    "sidt  %0"

+    : "=m" (*Idtr)

+    );

+}

+

+

+/**

+  Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Writes the current IDTR descriptor and returns it in Idtr. This function is

+  only available on IA-32 and X64.

+

+  @param  Idtr  The pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  )

+{

+  __asm__ __volatile__ (

+    "lidt %0"

+    :

+    : "m" (*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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "sldt  %0"

+    : "=g" (Data)   // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  Writes the current Local Descriptor Table Register (GDTR) 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

+  )

+{

+  __asm__ __volatile__ (

+    "lldtw  %0"

+    :

+    : "g" (Ldtr)   // %0

+    );

+}

+

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxSave (

+  OUT     IA32_FX_BUFFER            *Buffer

+  )

+{

+  __asm__ __volatile__ (

+    "fxsave %0"

+    :

+    : "m" (*Buffer)  // %0

+    );    

+}

+

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxRestore (

+  IN      CONST IA32_FX_BUFFER      *Buffer

+  )

+{

+  __asm__ __volatile__ (

+    "fxrstor %0"

+    :

+    : "m" (*Buffer)  // %0

+    );

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm0,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm1,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm2,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm3,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm4,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm5,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm6,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "push %%eax          \n\t"

+    "push %%eax          \n\t"

+    "movq %%mm7,  (%%esp)\n\t"

+    "pop  %%eax          \n\t"

+    "pop  %%edx          \n\t"

+    : "=A"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm0"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm1"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm2"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm3"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm4"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm5"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm6"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movq %0, %%mm7"  // %0

+    :  

+    : "m" (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

+  )

+{

+  UINT64  Data;

+  

+  __asm__ __volatile__ (

+    "rdtsc"

+    : "=A" (Data)

+    );

+  

+  return Data;  

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+  

+  __asm__ __volatile__ (

+    "rdpmc"

+    : "=A" (Data)

+    : "c"  (Index)

+    );

+  

+  return Data;  

+}

+

+

+

+

+/**

+  Executes a WBINVD instruction.

+

+  Executes a WBINVD instruction. This function is only available on IA-32 and

+  X64.

+

+**/

+VOID

+EFIAPI

+AsmWbinvd (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("wbinvd":::"memory");

+}

+

+

+/**

+  Executes a INVD instruction.

+

+  Executes a INVD instruction. This function is only available on IA-32 and

+  X64.

+

+**/

+VOID

+EFIAPI

+AsmInvd (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("invd":::"memory");

+    

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "clflush (%0)"

+    : "+a" (LinearAddress) 

+    : 

+    : "memory"

+    );

+    

+    return LinearAddress;

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S
new file mode 100644
index 0000000..dc0cbd4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S
@@ -0,0 +1,48 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>

+# Portions copyright (c) 2011, 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.

+#

+# Module Name:

+#

+#   InternalSwitchStack.S

+#

+# Abstract:

+#

+#   Implementation of a stack switch on IA-32.

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalSwitchStack)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalSwitchStack (

+#   IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+#   IN      VOID                      *Context1,   OPTIONAL

+#   IN      VOID                      *Context2,   OPTIONAL

+#   IN      VOID                      *NewStack

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalSwitchStack):

+  pushl %ebp

+	movl	%esp, %ebp

+

+	movl	20(%ebp), %esp      # switch stack

+	subl	$8, %esp

+

+	movl	16(%ebp), %eax

+	movl	%eax, 4(%esp)

+	movl	12(%ebp), %eax

+	movl	%eax, (%esp)

+	pushl $0                  # keeps gdb from unwinding stack

+	jmp   *8(%ebp)            # call and never return 

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.c
new file mode 100644
index 0000000..4b82b33
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.c
@@ -0,0 +1,60 @@
+/** @file

+  SwitchStack() function for IA-32.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+  Marker will be ignored on IA-32, x64, and EBC.

+  IPF CPUs 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  Marker      VA_LIST marker for the variable argument list.

+

+**/

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,   OPTIONAL

+  IN      VOID                      *Context2,   OPTIONAL

+  IN      VOID                      *NewStack,

+  IN      VA_LIST                   Marker

+  )

+{

+  BASE_LIBRARY_JUMP_BUFFER  JumpBuffer;

+

+  JumpBuffer.Eip = (UINTN)EntryPoint;

+  JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*);

+  JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2);

+  ((VOID**)JumpBuffer.Esp)[1] = Context1;

+  ((VOID**)JumpBuffer.Esp)[2] = Context2;

+

+  LongJump (&JumpBuffer, (UINTN)-1);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Invd.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Invd.asm
new file mode 100644
index 0000000..fadf3df
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Invd.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Invd.Asm

+;

+; Abstract:

+;

+;   AsmInvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmInvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+_AsmInvd    PROC

+    invd

+    ret

+_AsmInvd    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Invd.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Invd.c
new file mode 100644
index 0000000..b02ab86
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Invd.c
@@ -0,0 +1,35 @@
+/** @file

+  AsmInvd function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Executes a INVD instruction.

+

+  Executes a INVD instruction. This function is only available on IA-32 and

+  x64.

+

+**/

+VOID

+EFIAPI

+AsmInvd (

+  VOID

+  )

+{

+  _asm {

+    invd

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.S
new file mode 100644
index 0000000..e9aeeb6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   LRotU64.S

+#

+# Abstract:

+#

+#   64-bit left rotation for Ia32

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathLRotU64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathLRotU64 (

+#   IN      UINT64                    Operand,

+#   IN      UINTN                     Count

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathLRotU64):

+    push    %ebx

+    movb    16(%esp), %cl

+    movl    12(%esp), %edx

+    movl    8(%esp), %eax

+    shldl   %cl, %edx, %ebx

+    shldl   %cl, %eax, %edx

+    rorl    %cl, %ebx

+    shldl   %cl, %ebx, %eax

+    testb   $32, %cl                    # Count >= 32?

+    cmovnz  %eax, %ecx

+    cmovnz  %edx, %eax

+    cmovnz  %ecx, %edx

+    pop     %ebx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.asm
new file mode 100644
index 0000000..bfdf82d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   LRotU64.asm

+;

+; Abstract:

+;

+;   64-bit left rotation for Ia32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathLRotU64 (

+;   IN      UINT64                    Operand,

+;   IN      UINTN                     Count

+;   );

+;------------------------------------------------------------------------------

+InternalMathLRotU64 PROC    USES    ebx

+    mov     cl, [esp + 16]

+    mov     edx, [esp + 12]

+    mov     eax, [esp + 8]

+    shld    ebx, edx, cl

+    shld    edx, eax, cl

+    ror     ebx, cl

+    shld    eax, ebx, cl

+    test    cl, 32                      ; Count >= 32?

+    cmovnz  ecx, eax

+    cmovnz  eax, edx

+    cmovnz  edx, ecx

+    ret

+InternalMathLRotU64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.c
new file mode 100644
index 0000000..1c805aa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LRotU64.c
@@ -0,0 +1,53 @@
+/** @file

+  64-bit left rotation for Ia32

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count

+

+**/

+UINT64

+EFIAPI

+InternalMathLRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  _asm {

+    mov     cl, byte ptr [Count]

+    mov     edx, dword ptr [Operand + 4]

+    mov     eax, dword ptr [Operand + 0]

+    shld    ebx, edx, cl

+    shld    edx, eax, cl

+    ror     ebx, cl

+    shld    eax, ebx, cl

+    test    cl, 32                      ; Count >= 32?

+    cmovnz  ecx, eax

+    cmovnz  eax, edx

+    cmovnz  edx, ecx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.S
new file mode 100644
index 0000000..31df0d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   LShiftU64.S

+#

+# Abstract:

+#

+#   64-bit left shift function for IA-32

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathLShiftU64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathLShiftU64 (

+#   IN      UINT64                    Operand,

+#   IN      UINTN                     Count

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathLShiftU64):

+    movb    12(%esp), %cl

+    xorl    %eax, %eax

+    movl    4(%esp), %edx

+    testb   $32, %cl                    # Count >= 32?

+    cmovz   %edx, %eax

+    cmovz   0x8(%esp), %edx

+    shld    %cl, %eax, %edx

+    shl     %cl, %eax

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.asm
new file mode 100644
index 0000000..a5447e8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   LShiftU64.asm

+;

+; Abstract:

+;

+;   64-bit left shift function for IA-32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathLShiftU64 (

+;   IN      UINT64                    Operand,

+;   IN      UINTN                     Count

+;   );

+;------------------------------------------------------------------------------

+InternalMathLShiftU64   PROC

+    mov     cl, [esp + 12]

+    xor     eax, eax

+    mov     edx, [esp + 4]

+    test    cl, 32                      ; Count >= 32?

+    cmovz   eax, edx

+    cmovz   edx, [esp + 8]

+    shld    edx, eax, cl

+    shl     eax, cl

+    ret

+InternalMathLShiftU64   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.c
new file mode 100644
index 0000000..472fed1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LShiftU64.c
@@ -0,0 +1,49 @@
+/** @file

+  64-bit left shift function for IA-32.

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to shift left.

+  @param  Count   The number of bits to shift left.

+

+  @return Operand << Count

+

+**/

+UINT64

+EFIAPI

+InternalMathLShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  _asm {

+    mov     cl, byte ptr [Count]

+    xor     eax, eax

+    mov     edx, dword ptr [Operand + 0]

+    test    cl, 32                      // Count >= 32?

+    cmovz   eax, edx

+    cmovz   edx, dword ptr [Operand + 4]

+    shld    edx, eax, cl

+    shl     eax, cl

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.S
new file mode 100644
index 0000000..4514cd3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   LongJump.S

+#

+# Abstract:

+#

+#   Implementation of _LongJump() on IA-32.

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalLongJump)

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalLongJump (

+#   IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+#   IN      UINTN                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalLongJump):

+    pop     %eax                        # skip return address

+    pop     %edx                        # edx <- JumpBuffer

+    pop     %eax                        # eax <- Value

+    movl    (%edx), %ebx

+    movl    4(%edx), %esi

+    movl    8(%edx), %edi

+    movl    12(%edx), %ebp

+    movl    16(%edx), %esp

+    jmp     *20(%edx)                   # restore "eip"

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm
new file mode 100644
index 0000000..d1f1d77
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   LongJump.Asm

+;

+; Abstract:

+;

+;   Implementation of _LongJump() on IA-32.

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalLongJump (

+;   IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+;   IN      UINTN                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalLongJump    PROC

+    pop     eax                         ; skip return address

+    pop     edx                         ; edx <- JumpBuffer

+    pop     eax                         ; eax <- Value

+    mov     ebx, [edx]

+    mov     esi, [edx + 4]

+    mov     edi, [edx + 8]

+    mov     ebp, [edx + 12]

+    mov     esp, [edx + 16]

+    jmp     dword ptr [edx + 20]        ; restore "eip"

+InternalLongJump    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.c
new file mode 100644
index 0000000..73973a9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/LongJump.c
@@ -0,0 +1,50 @@
+/** @file

+  Implementation of _LongJump() on IA-32.

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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.

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+  @param  Value         The value to return when the SetJump() context is restored.

+

+**/

+__declspec (naked)

+VOID

+EFIAPI

+InternalLongJump (

+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+  IN      UINTN                     Value

+  )

+{

+  _asm {

+    pop     eax                         ; skip return address

+    pop     edx                         ; edx <- JumpBuffer

+    pop     eax                         ; eax <- Value

+    mov     ebx, [edx]

+    mov     esi, [edx + 4]

+    mov     edi, [edx + 8]

+    mov     ebp, [edx + 12]

+    mov     esp, [edx + 16]

+    jmp     dword ptr [edx + 20]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.S
new file mode 100644
index 0000000..beb2217
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.S
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   DivU64x32.S

+#

+# Abstract:

+#

+#   Calculate the remainder of a 64-bit integer by a 32-bit integer

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathModU64x32)

+

+#------------------------------------------------------------------------------

+# UINT32

+# EFIAPI

+# InternalMathModU64x32 (

+#   IN      UINT64                    Dividend,

+#   IN      UINT32                    Divisor

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathModU64x32):

+    movl    8(%esp), %eax

+    movl    12(%esp), %ecx

+    xorl    %edx, %edx

+    divl    %ecx

+    movl    4(%esp), %eax

+    divl    %ecx

+    movl    %edx, %eax

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.asm
new file mode 100644
index 0000000..a910fd3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DivU64x32.asm

+;

+; Abstract:

+;

+;   Calculate the remainder of a 64-bit integer by a 32-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InternalMathModU64x32 (

+;   IN      UINT64                    Dividend,

+;   IN      UINT32                    Divisor

+;   );

+;------------------------------------------------------------------------------

+InternalMathModU64x32   PROC

+    mov     eax, [esp + 8]

+    mov     ecx, [esp + 12]

+    xor     edx, edx

+    div     ecx

+    mov     eax, [esp + 4]

+    div     ecx

+    mov     eax, edx

+    ret

+InternalMathModU64x32   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.c
new file mode 100644
index 0000000..f66ea0b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ModU64x32.c
@@ -0,0 +1,48 @@
+/** @file

+  Calculate the remainder of a 64-bit integer by a 32-bit integer

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend % Divisor

+

+**/

+UINT32

+EFIAPI

+InternalMathModU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  _asm {

+    mov     eax, dword ptr [Dividend + 4]

+    mov     ecx, Divisor

+    xor     edx, edx

+    div     ecx

+    mov     eax, dword ptr [Dividend + 0]

+    div     ecx

+    mov     eax, edx

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.S
new file mode 100644
index 0000000..1e5f40e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.S
@@ -0,0 +1,40 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   Monitor.S

+#

+# Abstract:

+#

+#   AsmMonitor function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(AsmMonitor)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmMonitor (

+#   IN      UINTN                     Eax,

+#   IN      UINTN                     Ecx,

+#   IN      UINTN                     Edx

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(AsmMonitor):

+    movl    4(%esp), %eax

+    movl    8(%esp), %ecx

+    movl    12(%esp), %edx

+    monitor %eax, %ecx, %edx            # monitor

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.asm
new file mode 100644
index 0000000..a8f8612
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Monitor.Asm

+;

+; Abstract:

+;

+;   AsmMonitor function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmMonitor (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx,

+;   IN      UINTN                     Edx

+;   );

+;------------------------------------------------------------------------------

+AsmMonitor  PROC

+    mov     eax, [esp + 4]

+    mov     ecx, [esp + 8]

+    mov     edx, [esp + 12]

+    DB      0fh, 1, 0c8h                ; monitor

+    ret

+AsmMonitor  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.c
new file mode 100644
index 0000000..9d13ac5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Monitor.c
@@ -0,0 +1,48 @@
+/** @file

+  AsmMonitor function

+

+  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.

+

+**/

+

+/**

+  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  RegisterEax The value to load into EAX or RAX before executing the MONITOR

+                      instruction.

+  @param  RegisterEcx The value to load into ECX or RCX before executing the MONITOR

+                      instruction.

+  @param  RegisterEdx The value to load into EDX or RDX before executing the MONITOR

+                      instruction.

+

+  @return RegisterEax

+

+**/

+UINTN

+EFIAPI

+AsmMonitor (

+  IN      UINTN                     RegisterEax,

+  IN      UINTN                     RegisterEcx,

+  IN      UINTN                     RegisterEdx

+  )

+{

+  _asm {

+    mov     eax, RegisterEax

+    mov     ecx, RegisterEcx

+    mov     edx, RegisterEdx

+    _emit   0x0f             // monitor

+    _emit   0x01

+    _emit   0xc8

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.S
new file mode 100644
index 0000000..8e3f6f5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.S
@@ -0,0 +1,41 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   MultU64x32.S

+#

+# Abstract:

+#

+#   Calculate the product of a 64-bit integer and a 32-bit integer

+#

+#------------------------------------------------------------------------------

+

+

+    .code:

+

+ASM_GLOBAL ASM_PFX(InternalMathMultU64x32)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathMultU64x32 (

+#   IN      UINT64                    Multiplicand,

+#   IN      UINT32                    Multiplier

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathMultU64x32):

+    movl    12(%esp), %ecx

+    movl    %ecx, %eax

+    imull   8(%esp), %ecx               # overflow not detectable

+    mull    0x4(%esp)

+    addl    %ecx, %edx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.asm
new file mode 100644
index 0000000..9648d65
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   MultU64x32.asm

+;

+; Abstract:

+;

+;   Calculate the product of a 64-bit integer and a 32-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathMultU64x32 (

+;   IN      UINT64                    Multiplicand,

+;   IN      UINT32                    Multiplier

+;   );

+;------------------------------------------------------------------------------

+InternalMathMultU64x32  PROC

+    mov     ecx, [esp + 12]

+    mov     eax, ecx

+    imul    ecx, [esp + 8]              ; overflow not detectable

+    mul     dword ptr [esp + 4]

+    add     edx, ecx

+    ret

+InternalMathMultU64x32  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.c
new file mode 100644
index 0000000..42f64fc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x32.c
@@ -0,0 +1,47 @@
+/** @file

+  Calculate the product of a 64-bit integer and a 32-bit integer

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+InternalMathMultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  )

+{

+  _asm {

+    mov     ecx, Multiplier

+    mov     eax, ecx

+    imul    ecx, dword ptr [Multiplicand + 4]  // overflow not detectable

+    mul     dword ptr [Multiplicand + 0]

+    add     edx, ecx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.S
new file mode 100644
index 0000000..48f4ae0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.S
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   MultU64x64.S

+#

+# Abstract:

+#

+#   Calculate the product of a 64-bit integer and another 64-bit integer

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathMultU64x64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathMultU64x64 (

+#   IN      UINT64                    Multiplicand,

+#   IN      UINT64                    Multiplier

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathMultU64x64):

+    push    %ebx                                     

+    movl    8(%esp), %ebx             # ebx <- M1[0..31]                

+    movl    16(%esp), %edx            # edx <- M2[0..31]                                   

+    movl    %ebx, %ecx                                                  

+    movl    %edx, %eax                

+    imull   20(%esp), %ebx            # ebx <- M1[0..31] * M2[32..63]   

+    imull   12(%esp), %edx            # edx <- M1[32..63] * M2[0..31]   

+    addl    %edx, %ebx                # carries are abandoned           

+    mull    %ecx                      # edx:eax <- M1[0..31] * M2[0..31]

+    addl    %ebx, %edx                # carries are abandoned           

+    pop     %ebx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm
new file mode 100644
index 0000000..061301f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   MultU64x64.asm

+;

+; Abstract:

+;

+;   Calculate the product of a 64-bit integer and another 64-bit integer

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathMultU64x64 (

+;   IN      UINT64                    Multiplicand,

+;   IN      UINT64                    Multiplier

+;   );

+;------------------------------------------------------------------------------

+InternalMathMultU64x64  PROC    USES    ebx

+    mov     ebx, [esp + 8]              ; ebx <- M1[0..31]

+    mov     edx, [esp + 16]             ; edx <- M2[0..31]

+    mov     ecx, ebx

+    mov     eax, edx

+    imul    ebx, [esp + 20]             ; ebx <- M1[0..31] * M2[32..63]

+    imul    edx, [esp + 12]             ; edx <- M1[32..63] * M2[0..31]

+    add     ebx, edx                    ; carries are abandoned

+    mul     ecx                         ; edx:eax <- M1[0..31] * M2[0..31]

+    add     edx, ebx                    ; carries are abandoned

+    ret

+InternalMathMultU64x64  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.c
new file mode 100644
index 0000000..8f6bdc7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.c
@@ -0,0 +1,51 @@
+/** @file

+  Calculate the product of a 64-bit integer and another 64-bit integer

+

+  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.

+

+**/

+

+

+

+

+/**

+  Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer

+  and generates a 64-bit unsigned result.

+

+  This function multiplies 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

+InternalMathMultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    Multiplier

+  )

+{

+  _asm {

+    mov     ebx, dword ptr [Multiplicand + 0]

+    mov     edx, dword ptr [Multiplier + 0]

+    mov     ecx, ebx

+    mov     eax, edx

+    imul    ebx, dword ptr [Multiplier + 4]

+    imul    edx, dword ptr [Multiplicand + 4]

+    add     ebx, edx

+    mul     ecx

+    add     edx, ebx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.S
new file mode 100644
index 0000000..22b3ffd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   Mwait.S

+#

+# Abstract:

+#

+#   AsmMwait function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(AsmMwait)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmMwait (

+#   IN      UINTN                     Eax,

+#   IN      UINTN                     Ecx

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(AsmMwait):

+    movl    4(%esp), %eax

+    movl    8(%esp), %ecx

+    mwait

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.asm
new file mode 100644
index 0000000..3ae3085
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Mwait.Asm

+;

+; Abstract:

+;

+;   AsmMwait function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmMwait (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx

+;   );

+;------------------------------------------------------------------------------

+AsmMwait    PROC

+    mov     eax, [esp + 4]

+    mov     ecx, [esp + 8]

+    DB      0fh, 1, 0c9h                ; mwait

+    ret

+AsmMwait    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.c
new file mode 100644
index 0000000..e9ecb2c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Mwait.c
@@ -0,0 +1,44 @@
+/** @file

+  AsmMwait function

+

+  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.

+

+**/

+

+/**

+  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  RegisterEax The value to load into EAX or RAX before executing the MONITOR

+                      instruction.

+  @param  RegisterEcx The value to load into ECX or RCX before executing the MONITOR

+                      instruction.

+

+  @return RegisterEax

+

+**/

+UINTN

+EFIAPI

+AsmMwait (

+  IN      UINTN                     RegisterEax,

+  IN      UINTN                     RegisterEcx

+  )

+{

+  _asm {

+    mov     eax, RegisterEax

+    mov     ecx, RegisterEcx

+    _emit   0x0f              // mwait

+    _emit   0x01

+    _emit   0xC9

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Non-existing.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Non-existing.c
new file mode 100644
index 0000000..edd38d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Non-existing.c
@@ -0,0 +1,57 @@
+/** @file

+  Non-existing BaseLib functions on Ia32

+

+  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.

+

+**/

+

+#include <Library/DebugLib.h>

+

+/**

+  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.

+

+  @param  CodeSelector  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

+InternalX86DisablePaging64 (

+  IN      UINT16                    CodeSelector,

+  IN      UINT32                    EntryPoint,

+  IN      UINT32                    Context1,  OPTIONAL

+  IN      UINT32                    Context2,  OPTIONAL

+  IN      UINT32                    NewStack

+  )

+{

+  //

+  // This function cannot work on IA32 platform

+  //

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.S
new file mode 100644
index 0000000..54fc089
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   RRotU64.S

+#

+# Abstract:

+#

+#   64-bit right rotation for Ia32

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMathRRotU64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathRRotU64 (

+#   IN      UINT64                    Operand,

+#   IN      UINTN                     Count

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathRRotU64):

+    push    %ebx

+    movb    16(%esp), %cl

+    movl    8(%esp), %eax

+    movl    12(%esp), %edx

+    shrdl   %cl, %eax, %ebx

+    shrdl   %cl, %edx, %eax

+    roll    %cl, %ebx

+    shrdl   %cl, %ebx, %edx

+    testb   $32, %cl                    # Count >= 32?

+    cmovnz  %eax, %ecx                  # switch eax & edx if Count >= 32

+    cmovnz  %edx, %eax

+    cmovnz  %ecx, %edx

+    pop     %ebx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm
new file mode 100644
index 0000000..a719d29
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   RRotU64.asm

+;

+; Abstract:

+;

+;   64-bit right rotation for Ia32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathRRotU64 (

+;   IN      UINT64                    Operand,

+;   IN      UINTN                     Count

+;   );

+;------------------------------------------------------------------------------

+InternalMathRRotU64 PROC    USES    ebx

+    mov     cl, [esp + 16]

+    mov     eax, [esp + 8]

+    mov     edx, [esp + 12]

+    shrd    ebx, eax, cl

+    shrd    eax, edx, cl

+    rol     ebx, cl

+    shrd    edx, ebx, cl

+    test    cl, 32                      ; Count >= 32?

+    cmovnz  ecx, eax                    ; switch eax & edx if Count >= 32

+    cmovnz  eax, edx

+    cmovnz  edx, ecx

+    ret

+InternalMathRRotU64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.c
new file mode 100644
index 0000000..f6ee6d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.c
@@ -0,0 +1,53 @@
+/** @file

+  64-bit right rotation for Ia32

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count

+

+**/

+UINT64

+EFIAPI

+InternalMathRRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  _asm {

+    mov     cl, byte ptr [Count]

+    mov     eax, dword ptr [Operand + 0]

+    mov     edx, dword ptr [Operand + 4]

+    shrd    ebx, eax, cl

+    shrd    eax, edx, cl

+    rol     ebx, cl

+    shrd    edx, ebx, cl

+    test    cl, 32                      // Count >= 32?

+    cmovnz  ecx, eax

+    cmovnz  eax, edx

+    cmovnz  edx, ecx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.S
new file mode 100644
index 0000000..17cdedb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.S
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   RShiftU64.S

+#

+# Abstract:

+#

+#   64-bit logical right shift function for IA-32

+#

+#------------------------------------------------------------------------------

+

+

+    .code:

+

+ASM_GLOBAL ASM_PFX(InternalMathRShiftU64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathRShiftU64 (

+#   IN      UINT64                    Operand,

+#   IN      UINTN                     Count

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMathRShiftU64):

+    movb    12(%esp), %cl               # cl <- Count

+    xorl    %edx, %edx

+    movl    8(%esp), %eax

+    testb   $32, %cl                    # Count >= 32?

+    cmovz   %eax, %edx

+    cmovz   0x4(%esp), %eax

+    shrdl   %cl, %edx, %eax

+    shr     %cl, %edx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm
new file mode 100644
index 0000000..2fe6057
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   RShiftU64.asm

+;

+; Abstract:

+;

+;   64-bit logical right shift function for IA-32

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathRShiftU64 (

+;   IN      UINT64                    Operand,

+;   IN      UINTN                     Count

+;   );

+;------------------------------------------------------------------------------

+InternalMathRShiftU64   PROC

+    mov     cl, [esp + 12]              ; cl <- Count

+    xor     edx, edx

+    mov     eax, [esp + 8]

+    test    cl, 32                      ; Count >= 32?

+    cmovz   edx, eax

+    cmovz   eax, [esp + 4]

+    shrd    eax, edx, cl

+    shr     edx, cl

+    ret

+InternalMathRShiftU64   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.c
new file mode 100644
index 0000000..89b0e95
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.c
@@ -0,0 +1,49 @@
+/** @file

+  64-bit logical right shift function for IA-32

+

+  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.

+

+**/

+

+

+

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand >> Count

+

+**/

+UINT64

+EFIAPI

+InternalMathRShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  _asm {

+    mov     cl, byte ptr [Count]

+    xor     edx, edx

+    mov     eax, dword ptr [Operand + 4]

+    test    cl, 32

+    cmovz   edx, eax

+    cmovz   eax, dword ptr [Operand + 0]

+    shrd    eax, edx, cl

+    shr     edx, cl

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.asm
new file mode 100644
index 0000000..13d0920
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr0.Asm

+;

+; Abstract:

+;

+;   AsmReadCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr0  PROC

+    mov     eax, cr0

+    ret

+AsmReadCr0  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.c
new file mode 100644
index 0000000..ddd5483
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr0.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmReadCr0 function

+

+  Copyright (c) 2006 - 2014, 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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, cr0

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.asm
new file mode 100644
index 0000000..7a267d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr2.Asm

+;

+; Abstract:

+;

+;   AsmReadCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr2  PROC

+    mov     eax, cr2

+    ret

+AsmReadCr2  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.c
new file mode 100644
index 0000000..8942273
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr2.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadCr2 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, cr2

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.asm
new file mode 100644
index 0000000..d4ba412
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr3.Asm

+;

+; Abstract:

+;

+;   AsmReadCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr3  PROC

+    mov     eax, cr3

+    ret

+AsmReadCr3  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.c
new file mode 100644
index 0000000..0dd9289
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr3.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadCr3 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, cr3

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.asm
new file mode 100644
index 0000000..02f9072
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr4.Asm

+;

+; Abstract:

+;

+;   AsmReadCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr4  PROC

+    mov     eax, cr4

+    ret

+AsmReadCr4  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.c
new file mode 100644
index 0000000..c9045ff
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCr4.c
@@ -0,0 +1,40 @@
+/** @file

+  AsmReadCr4 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    _emit  0x0f  // mov  eax, cr4

+    _emit  0x20

+    _emit  0xE0

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.asm
new file mode 100644
index 0000000..f9f1eef
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCs.Asm

+;

+; Abstract:

+;

+;   AsmReadCs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadCs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCs   PROC

+    mov     eax, cs

+    ret

+AsmReadCs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.c
new file mode 100644
index 0000000..0d5bed4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadCs.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadCs function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    xor     eax, eax

+    mov     ax, cs

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.asm
new file mode 100644
index 0000000..8a8c4d2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr0.Asm

+;

+; Abstract:

+;

+;   AsmReadDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr0  PROC

+    mov     eax, dr0

+    ret

+AsmReadDr0  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.c
new file mode 100644
index 0000000..5ef1087
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr0.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDr0 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, dr0

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.asm
new file mode 100644
index 0000000..cb9808b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr1.Asm

+;

+; Abstract:

+;

+;   AsmReadDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr1  PROC

+    mov     eax, dr1

+    ret

+AsmReadDr1  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.c
new file mode 100644
index 0000000..f62516d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr1.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDr1 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, dr1

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.asm
new file mode 100644
index 0000000..bbc77b6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr2.Asm

+;

+; Abstract:

+;

+;   AsmReadDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr2  PROC

+    mov     eax, dr2

+    ret

+AsmReadDr2  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.c
new file mode 100644
index 0000000..4ea6586
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr2.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDr2 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, dr2

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.asm
new file mode 100644
index 0000000..a6dc443
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr3.Asm

+;

+; Abstract:

+;

+;   AsmReadDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr3  PROC

+    mov     eax, dr3

+    ret

+AsmReadDr3  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.c
new file mode 100644
index 0000000..e9a73b8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr3.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDr3 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, dr3

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm
new file mode 100644
index 0000000..2d0c7a6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr4.Asm

+;

+; Abstract:

+;

+;   AsmReadDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr4  PROC

+    ;

+    ; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, reading

+    ; this register will cause a #UD exception.

+    ;

+    ; MS assembler doesn't support this instruction since no one would use it

+    ; under normal circustances. Here opcode is used.

+    ;

+    DB      0fh, 21h, 0e0h

+    ret

+AsmReadDr4  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.c
new file mode 100644
index 0000000..c31a894
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.c
@@ -0,0 +1,40 @@
+/** @file

+  AsmReadDr4 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    _emit  0x0f

+    _emit  0x21

+    _emit  0xe0

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm
new file mode 100644
index 0000000..58b4ac2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr5.Asm

+;

+; Abstract:

+;

+;   AsmReadDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr5  PROC

+    ;

+    ; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, reading

+    ; this register will cause a #UD exception.

+    ;

+    ; MS assembler doesn't support this instruction since no one would use it

+    ; under normal circustances. Here opcode is used.

+    ;

+    DB      0fh, 21h, 0e8h

+    ret

+AsmReadDr5  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.c
new file mode 100644
index 0000000..169c15e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.c
@@ -0,0 +1,40 @@
+/** @file

+  AsmReadDr5 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    _emit  0x0f

+    _emit  0x21

+    _emit  0xe8

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.asm
new file mode 100644
index 0000000..6ecac10
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr6.Asm

+;

+; Abstract:

+;

+;   AsmReadDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr6  PROC

+    mov     eax, dr6

+    ret

+AsmReadDr6  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.c
new file mode 100644
index 0000000..d6fd27b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr6.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDr6 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, dr6

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.asm
new file mode 100644
index 0000000..3869bb1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr7.Asm

+;

+; Abstract:

+;

+;   AsmReadDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr7  PROC

+    mov     eax, dr7

+    ret

+AsmReadDr7  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.c
new file mode 100644
index 0000000..ffaf4fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDr7.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDr7 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    mov     eax, dr7

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.asm
new file mode 100644
index 0000000..d134926
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDs.Asm

+;

+; Abstract:

+;

+;   AsmReadDs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadDs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDs   PROC

+    mov     eax, ds

+    ret

+AsmReadDs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.c
new file mode 100644
index 0000000..3b098c3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadDs.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadDs function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    xor     eax, eax

+    mov     ax, ds

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.asm
new file mode 100644
index 0000000..4b210d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadEflags.Asm

+;

+; Abstract:

+;

+;   AsmReadEflags function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadEflags (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadEflags   PROC

+    pushfd

+    pop     eax

+    ret

+AsmReadEflags   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.c
new file mode 100644
index 0000000..e52dea8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEflags.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmReadEflags function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    pushfd

+    pop     eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.asm
new file mode 100644
index 0000000..4c5d0cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadEs.Asm

+;

+; Abstract:

+;

+;   AsmReadEs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadEs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadEs   PROC

+    mov     eax, es

+    ret

+AsmReadEs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.c
new file mode 100644
index 0000000..f605464
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadEs.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadEs function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Reads the current value of ES Data 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

+  )

+{

+  __asm {

+    xor     eax, eax

+    mov     ax, es

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.asm
new file mode 100644
index 0000000..bdcb97f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadFs.Asm

+;

+; Abstract:

+;

+;   AsmReadFs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadFs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadFs   PROC

+    mov     eax, fs

+    ret

+AsmReadFs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.c
new file mode 100644
index 0000000..cbe45b1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadFs.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadFs function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    xor     eax, eax

+    mov     ax, fs

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.asm
new file mode 100644
index 0000000..68c125a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadGdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86ReadGdtr (

+;   OUT IA32_DESCRIPTOR  *Gdtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86ReadGdtr   PROC

+    mov     eax, [esp + 4]

+    sgdt    fword ptr [eax]

+    ret

+InternalX86ReadGdtr   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.c
new file mode 100644
index 0000000..da4733e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmReadGdtr function

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadGdtr (

+  OUT IA32_DESCRIPTOR  *Gdtr

+  )

+{

+  _asm {

+    mov     eax, Gdtr

+    sgdt    fword ptr [eax]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.asm
new file mode 100644
index 0000000..db505de
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadGs.Asm

+;

+; Abstract:

+;

+;   AsmReadGs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadGs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadGs   PROC

+    mov     eax, gs

+    ret

+AsmReadGs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.c
new file mode 100644
index 0000000..1113baf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadGs.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadGs function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    xor     eax, eax

+    mov     ax, gs

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.asm
new file mode 100644
index 0000000..40b8bf8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadIdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86ReadIdtr (

+;   OUT     IA32_DESCRIPTOR           *Idtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86ReadIdtr PROC

+    mov     eax, [esp + 4]

+    sidt    fword ptr [eax]

+    ret

+InternalX86ReadIdtr ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.c
new file mode 100644
index 0000000..abc06b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadIdtr.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadIdtr function

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current IDTR descriptor and returns it in Idtr. This

+  function is only available on IA-32 and x64.

+

+  @param  Idtr  The pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  )

+{

+  _asm {

+    mov     eax, Idtr

+    sidt    fword ptr [eax]

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.asm
new file mode 100644
index 0000000..f38ebbf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadLdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadLdtr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadLdtr PROC

+    sldt    ax

+    ret

+AsmReadLdtr ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.c
new file mode 100644
index 0000000..edb961f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadLdtr.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmReadLdtr function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    sldt    ax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.asm
new file mode 100644
index 0000000..990b647
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm0.Asm

+;

+; Abstract:

+;

+;   AsmReadMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm0  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm0

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm0  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.c
new file mode 100644
index 0000000..a234c7a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm0.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm0 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm0

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.asm
new file mode 100644
index 0000000..d241fac
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm1.Asm

+;

+; Abstract:

+;

+;   AsmReadMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm1  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm1

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm1  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.c
new file mode 100644
index 0000000..9567d05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm1.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm1 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm1

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.asm
new file mode 100644
index 0000000..07bf0ea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm2.Asm

+;

+; Abstract:

+;

+;   AsmReadMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm2  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm2

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm2  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.c
new file mode 100644
index 0000000..361cf39
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm2.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm2 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm2

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.asm
new file mode 100644
index 0000000..d323188
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm3.Asm

+;

+; Abstract:

+;

+;   AsmReadMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm3  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm3

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm3  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.c
new file mode 100644
index 0000000..b0d62d8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm3.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm3 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm3

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.asm
new file mode 100644
index 0000000..3d63eae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm4.Asm

+;

+; Abstract:

+;

+;   AsmReadMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm4  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm4

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm4  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.c
new file mode 100644
index 0000000..d34f164
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm4.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm4 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm4

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.asm
new file mode 100644
index 0000000..39d0c7e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm5.Asm

+;

+; Abstract:

+;

+;   AsmReadMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm5  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm5

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm5  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.c
new file mode 100644
index 0000000..a529900
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm5.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm5 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm5

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.asm
new file mode 100644
index 0000000..2673710
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm6.Asm

+;

+; Abstract:

+;

+;   AsmReadMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm6  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm6

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm6  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.c
new file mode 100644
index 0000000..c1d1065
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm6.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm6 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm6

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.asm
new file mode 100644
index 0000000..eadb1ac
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm7.Asm

+;

+; Abstract:

+;

+;   AsmReadMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm7  PROC

+    push    eax

+    push    eax

+    movq    [esp], mm7

+    pop     eax

+    pop     edx

+    ret

+AsmReadMm7  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.c
new file mode 100644
index 0000000..d8a4cc4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMm7.c
@@ -0,0 +1,42 @@
+/** @file

+  AsmReadMm7 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    push    eax

+    push    eax

+    movq    [esp], mm7

+    pop     eax

+    pop     edx

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.S
new file mode 100644
index 0000000..43eb35a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ReadMsr64.S

+#

+# Abstract:

+#

+#   AsmReadMsr64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(AsmReadMsr64)

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmReadMsr64 (

+#   IN UINT32  Index

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(AsmReadMsr64):

+    movl    4(%esp), %ecx

+    rdmsr

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.asm
new file mode 100644
index 0000000..da6f45f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMsr64.Asm

+;

+; Abstract:

+;

+;   AsmReadMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMsr64 (

+;   IN UINT64  Index

+;   );

+;------------------------------------------------------------------------------

+AsmReadMsr64    PROC

+    mov     ecx, [esp + 4]

+    rdmsr

+    ret

+AsmReadMsr64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c
new file mode 100644
index 0000000..88ba49d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c
@@ -0,0 +1,43 @@
+/** @file

+  AsmReadMsr64 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    mov     ecx, Index

+    rdmsr

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.asm
new file mode 100644
index 0000000..59ea36b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadPmc.Asm

+;

+; Abstract:

+;

+;   AsmReadPmc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadPmc (

+;   IN UINT32   PmcIndex

+;   );

+;------------------------------------------------------------------------------

+AsmReadPmc  PROC

+    mov     ecx, [esp + 4]

+    rdpmc

+    ret

+AsmReadPmc  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.c
new file mode 100644
index 0000000..6c6cdd8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadPmc.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmReadPmc function

+

+  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.

+

+**/

+

+/**

+  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

+  )

+{

+  _asm {

+    mov     ecx, Index

+    rdpmc

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.S
new file mode 100644
index 0000000..c87fa61
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ReadSs.S

+#

+# Abstract:

+#

+#   AsmReadSs function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(AsmReadSs)

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadSs (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(AsmReadSs):

+    movl    %ss, %eax

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.asm
new file mode 100644
index 0000000..bfba7c0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadSs.Asm

+;

+; Abstract:

+;

+;   AsmReadSs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadSs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadSs   PROC

+    mov     eax, ss

+    ret

+AsmReadSs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.c
new file mode 100644
index 0000000..6ce4cd0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadSs.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmReadSs function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  __asm {

+    xor     eax, eax

+    mov     ax, ss

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.S
new file mode 100644
index 0000000..20dd7b3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ReadTr.S

+#

+# Abstract:

+#

+#   AsmReadTr function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(AsmReadTr)

+

+#------------------------------------------------------------------------------

+# UINT16

+# EFIAPI

+# AsmReadTr (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(AsmReadTr):

+    str     %ax

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.asm
new file mode 100644
index 0000000..7fca070
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadTr.Asm

+;

+; Abstract:

+;

+;   AsmReadTr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadTr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadTr   PROC

+    str     ax

+    ret

+AsmReadTr   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.c
new file mode 100644
index 0000000..dcb899b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTr.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmReadTr function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    str     ax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.asm
new file mode 100644
index 0000000..ad02adb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadTsc.Asm

+;

+; Abstract:

+;

+;   AsmReadTsc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadTsc (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadTsc  PROC

+    rdtsc

+    ret

+AsmReadTsc  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.c
new file mode 100644
index 0000000..11a5095
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/ReadTsc.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmReadTsc function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    rdtsc

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.S
new file mode 100644
index 0000000..459224e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.S
@@ -0,0 +1,44 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetJump.S

+#

+# Abstract:

+#

+#   Implementation of SetJump() on IA-32.

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(SetJump), ASM_PFX(InternalAssertJumpBuffer)

+

+#------------------------------------------------------------------------------

+# UINTN

+# EFIAPI

+# SetJump (

+#   OUT     BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(SetJump):

+    pushl   0x4(%esp)

+    call    ASM_PFX(InternalAssertJumpBuffer)               # To validate JumpBuffer

+    pop     %ecx

+    pop     %ecx                                            # ecx <- return address

+    movl    (%esp), %edx

+    movl    %ebx, (%edx)

+    movl    %esi, 4(%edx)

+    movl    %edi, 8(%edx)

+    movl    %ebp, 12(%edx)

+    movl    %esp, 16(%edx)

+    movl    %ecx, 20(%edx)                                  # eip value to restore in LongJump

+    xorl    %eax, %eax

+    jmp     *%ecx

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm
new file mode 100644
index 0000000..8486b9f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm
@@ -0,0 +1,51 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetJump.Asm

+;

+; Abstract:

+;

+;   Implementation of SetJump() on IA-32.

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+InternalAssertJumpBuffer    PROTO   C

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; SetJump (

+;   OUT     BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+;   );

+;------------------------------------------------------------------------------

+SetJump     PROC

+    push    [esp + 4]

+    call    InternalAssertJumpBuffer    ; To validate JumpBuffer

+    pop     ecx

+    pop     ecx                         ; ecx <- return address

+    mov     edx, [esp]

+    mov     [edx], ebx

+    mov     [edx + 4], esi

+    mov     [edx + 8], edi

+    mov     [edx + 12], ebp

+    mov     [edx + 16], esp

+    mov     [edx + 20], ecx             ; eip value to restore in LongJump

+    xor     eax, eax

+    jmp     ecx

+SetJump     ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.c
new file mode 100644
index 0000000..304f383
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SetJump.c
@@ -0,0 +1,74 @@
+/** @file

+  Implementation of SetJump() on IA-32.

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Worker function that checks ASSERT condition for JumpBuffer

+

+  Checks ASSERT condition for JumpBuffer.

+

+  If JumpBuffer is NULL, then ASSERT().

+  For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+

+**/

+VOID

+EFIAPI

+InternalAssertJumpBuffer (

+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+  );

+

+/**

+  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 IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  JumpBuffer  A pointer to CPU context buffer.

+

+  @retval 0 Indicates a return from SetJump().

+

+**/

+_declspec (naked)

+UINTN

+EFIAPI

+SetJump (

+  OUT     BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+  )

+{

+  _asm {

+    push    [esp + 4]

+    call    InternalAssertJumpBuffer

+    pop     ecx

+    pop     ecx

+    mov     edx, [esp]

+    mov     [edx], ebx

+    mov     [edx + 4], esi

+    mov     [edx + 8], edi

+    mov     [edx + 12], ebp

+    mov     [edx + 16], esp

+    mov     [edx + 20], ecx

+    xor     eax, eax

+    jmp     ecx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.S
new file mode 100644
index 0000000..ce4ebc8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CpuId.S

+#

+# Abstract:

+#

+#   AsmCpuid function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# InternalMathSwapBytes64 (

+#   IN      UINT64                    Operand

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMathSwapBytes64)

+ASM_PFX(InternalMathSwapBytes64):

+    movl    8(%esp), %eax               # eax <- upper 32 bits

+    movl    4(%esp), %edx               # edx <- lower 32 bits

+    bswapl  %eax

+    bswapl  %edx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm
new file mode 100644
index 0000000..7020753
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuId.Asm

+;

+; Abstract:

+;

+;   AsmCpuid function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalMathSwapBytes64 (

+;   IN      UINT64                    Operand

+;   );

+;------------------------------------------------------------------------------

+InternalMathSwapBytes64 PROC

+    mov     eax, [esp + 8]              ; eax <- upper 32 bits

+    mov     edx, [esp + 4]              ; edx <- lower 32 bits

+    bswap   eax

+    bswap   edx

+    ret

+InternalMathSwapBytes64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.c
new file mode 100644
index 0000000..41cbed9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.c
@@ -0,0 +1,43 @@
+/** @file

+  Implementation of 64-bit swap bytes

+

+  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.

+

+**/

+

+

+

+

+/**

+  Switches the endianess 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  Operand A 64-bit unsigned value.

+

+  @return The byte swaped Operand.

+

+**/

+UINT64

+EFIAPI

+InternalMathSwapBytes64 (

+  IN      UINT64                    Operand

+  )

+{

+  _asm {

+    mov     eax, dword ptr [Operand + 4]

+    mov     edx, dword ptr [Operand + 0]

+    bswap   eax

+    bswap   edx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.S
new file mode 100644
index 0000000..185655e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.S
@@ -0,0 +1,222 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   Thunk16.S

+#

+# Abstract:

+#

+#   Real mode thunk

+#

+#------------------------------------------------------------------------------

+

+#include <Library/BaseLib.h>

+

+ASM_GLOBAL ASM_PFX(m16Start), ASM_PFX(m16Size), ASM_PFX(mThunk16Attr), ASM_PFX(m16Gdt), ASM_PFX(m16GdtrBase), ASM_PFX(mTransition)

+ASM_GLOBAL ASM_PFX(InternalAsmThunk16)

+

+# define the structure of IA32_REGS

+.set  _EDI, 0       #size 4

+.set  _ESI, 4       #size 4

+.set  _EBP, 8       #size 4

+.set  _ESP, 12      #size 4

+.set  _EBX, 16      #size 4

+.set  _EDX, 20      #size 4

+.set  _ECX, 24      #size 4

+.set  _EAX, 28      #size 4

+.set  _DS,  32      #size 2

+.set  _ES,  34      #size 2

+.set  _FS,  36      #size 2

+.set  _GS,  38      #size 2

+.set  _EFLAGS, 40   #size 4

+.set  _EIP, 44      #size 4

+.set  _CS, 48       #size 2

+.set  _SS, 50       #size 2

+.set  IA32_REGS_SIZE, 52

+

+    .text

+    .code16

+

+ASM_PFX(m16Start):

+

+SavedGdt:     .space  6

+

+ASM_PFX(BackFromUserCode):

+    push    %ss

+    push    %cs

+

+    calll   L_Base1                     # push eip

+L_Base1:

+    pushfl

+    cli                                 # disable interrupts

+    push    %gs

+    push    %fs

+    push    %es

+    push    %ds

+    pushal

+    .byte   0x66, 0xba                  # mov edx, imm32

+ASM_PFX(ThunkAttr): .space  4

+    testb   $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl

+    jz      1f

+    movw    $0x2401, %ax

+    int     $0x15

+    cli                                 # disable interrupts

+    jnc     2f

+1:

+    testb   $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl

+    jz      2f

+    inb     $0x92, %al

+    orb     $2, %al

+    outb    %al, $0x92                  # deactivate A20M#

+2:

+    xorl    %eax, %eax

+    movw    %ss, %ax

+    leal    IA32_REGS_SIZE(%esp), %ebp

+    mov     %ebp, (_ESP - IA32_REGS_SIZE)(%bp)

+    mov     (_EIP - IA32_REGS_SIZE)(%bp), %bx

+    shll    $4, %eax

+    addl    %eax, %ebp

+    .byte   0x66, 0xb8                  # mov eax, imm32

+SavedCr4:   .space  4

+    movl    %eax, %cr4

+    lgdtl   %cs:(SavedGdt - L_Base1)(%bx)

+    .byte   0x66, 0xb8                  # mov eax, imm32

+SavedCr0:   .space  4

+    movl    %eax, %cr0

+    .byte   0xb8                        # mov ax, imm16

+SavedSs:    .space  2

+    movl    %eax, %ss

+    .byte   0x66, 0xbc                  # mov esp, imm32

+SavedEsp:   .space  4

+    lretl                               # return to protected mode

+

+_EntryPoint:    .long      ASM_PFX(ToUserCode) - ASM_PFX(m16Start)

+                .word      0x8

+_16Idtr:        .word      0x3ff

+                .long      0

+_16Gdtr:        .word      GdtEnd - _NullSegDesc - 1

+_16GdtrBase:    .long      _NullSegDesc

+

+ASM_PFX(ToUserCode):

+    movw    %ss, %dx

+    movw    %cx, %ss                    # set new segment selectors

+    movw    %cx, %ds

+    movw    %cx, %es

+    movw    %cx, %fs

+    movw    %cx, %gs

+    movl    %eax, %cr0                  # real mode starts at next instruction

+                                        #  which (per SDM) *must* be a far JMP.

+    ljmpw   $0,$0                       # will be filled in by InternalAsmThunk16

+L_Base:                                 #  to point here.

+    movl    %ebp, %cr4

+    movw    %si, %ss                    # set up 16-bit stack segment

+    xchgl   %ebx, %esp                  # set up 16-bit stack pointer

+

+    movw    IA32_REGS_SIZE(%esp), %bp   # get BackToUserCode address from stack

+    mov     %dx, %cs:(SavedSs - ASM_PFX(BackFromUserCode))(%bp)

+    mov     %ebx, %cs:(SavedEsp - ASM_PFX(BackFromUserCode))(%bp)

+    lidtl   %cs:(_16Idtr - ASM_PFX(BackFromUserCode))(%bp)

+    popal

+    pop     %ds

+    pop     %es

+    pop     %fs

+    pop     %gs

+    popfl

+    lretl                               # transfer control to user code

+

+_NullSegDesc:   .quad   0

+_16CsDesc:

+                .word   -1

+                .word   0

+                .byte   0

+                .byte   0x9b

+                .byte   0x8f            # 16-bit segment, 4GB limit

+                .byte   0

+_16DsDesc:

+                .word   -1

+                .word   0

+                .byte   0

+                .byte   0x93

+                .byte   0x8f            # 16-bit segment, 4GB limit

+                .byte   0

+GdtEnd:

+

+    .code32

+#

+#   @param  RegSet  The pointer to a IA32_DWORD_REGS structure

+#   @param  Transition  The pointer to the transition code

+#   @return The address of the 16-bit stack after returning from user code

+#

+ASM_PFX(InternalAsmThunk16):

+    push    %ebp

+    push    %ebx

+    push    %esi

+    push    %edi

+    push    %ds

+    push    %es

+    push    %fs

+    push    %gs

+    movl    36(%esp), %esi              # esi <- RegSet

+    movzwl  _SS(%esi), %edx

+    mov     _ESP(%esi), %edi

+    add     $(-(IA32_REGS_SIZE + 4)), %edi

+    movl    %edi, %ebx                  # ebx <- stack offset

+    imul    $0x10, %edx, %eax

+    push    $(IA32_REGS_SIZE / 4)

+    addl    %eax, %edi                  # edi <- linear address of 16-bit stack

+    pop     %ecx

+    rep

+    movsl                               # copy RegSet

+    movl    40(%esp), %eax              # eax <- address of transition code

+    movl    %edx, %esi                  # esi <- 16-bit stack segment

+    lea     (SavedCr0 - ASM_PFX(m16Start))(%eax), %edx

+    movl    %eax, %ecx

+    andl    $0xf, %ecx

+    shll    $12, %eax

+    lea     (ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start))(%ecx), %ecx

+    movw    %cx, %ax

+    stosl                               # [edi] <- return address of user code

+    addl    $(L_Base - ASM_PFX(BackFromUserCode)), %eax

+    movl    %eax, (L_Base - SavedCr0 - 4)(%edx)

+    sgdtl   (SavedGdt - SavedCr0)(%edx)

+    sidtl   0x24(%esp)

+    movl    %cr0, %eax

+    movl    %eax, (%edx)                # save CR0 in SavedCr0

+    andl    $0x7ffffffe, %eax           # clear PE, PG bits

+    movl    %cr4, %ebp

+    mov     %ebp, (SavedCr4 - SavedCr0)(%edx)

+    andl    $0xffffffcf, %ebp           # clear PAE, PSE bits

+    pushl   $0x10

+    pop     %ecx                        # ecx <- selector for data segments

+    lgdtl   (_16Gdtr - SavedCr0)(%edx)

+    pushfl

+    lcall   *(_EntryPoint - SavedCr0)(%edx)

+    popfl

+    lidtl   0x24(%esp)

+    lea     -IA32_REGS_SIZE(%ebp), %eax

+    pop     %gs

+    pop     %fs

+    pop     %es

+    pop     %ds

+    pop     %edi

+    pop     %esi

+    pop     %ebx

+    pop     %ebp

+    ret

+

+    .const:

+

+ASM_PFX(m16Size):        .word      ASM_PFX(InternalAsmThunk16)  - ASM_PFX(m16Start)

+ASM_PFX(mThunk16Attr):   .word      ASM_PFX(ThunkAttr)          - ASM_PFX(m16Start)

+ASM_PFX(m16Gdt):         .word      _NullSegDesc        - ASM_PFX(m16Start)

+ASM_PFX(m16GdtrBase):    .word      _16GdtrBase         - ASM_PFX(m16Start)

+ASM_PFX(mTransition):    .word      _EntryPoint         - ASM_PFX(m16Start)

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm
new file mode 100644
index 0000000..08955d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm
@@ -0,0 +1,260 @@
+

+#include "BaseLibInternals.h"

+

+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   Thunk.asm

+;

+; Abstract:

+;

+;   Real mode thunk

+;

+;------------------------------------------------------------------------------

+

+    .686p

+    .model  flat,C

+

+EXTERNDEF   C   m16Start:BYTE

+EXTERNDEF   C   m16Size:WORD

+EXTERNDEF   C   mThunk16Attr:WORD

+EXTERNDEF   C   m16Gdt:WORD

+EXTERNDEF   C   m16GdtrBase:WORD

+EXTERNDEF   C   mTransition:WORD

+

+;

+; Here is the layout of the real mode stack. _ToUserCode() is responsible for

+; loading all these registers from real mode stack.

+;

+IA32_REGS   STRUC   4t

+_EDI        DD      ?

+_ESI        DD      ?

+_EBP        DD      ?

+_ESP        DD      ?

+_EBX        DD      ?

+_EDX        DD      ?

+_ECX        DD      ?

+_EAX        DD      ?

+_DS         DW      ?

+_ES         DW      ?

+_FS         DW      ?

+_GS         DW      ?

+_EFLAGS     DD      ?

+_EIP        DD      ?

+_CS         DW      ?

+_SS         DW      ?

+IA32_REGS   ENDS

+

+    .const

+

+;

+; These are global constant to convey information to C code.

+;

+m16Size         DW      InternalAsmThunk16 - m16Start

+mThunk16Attr    DW      _ThunkAttr - m16Start

+m16Gdt          DW      _NullSegDesc - m16Start

+m16GdtrBase     DW      _16GdtrBase - m16Start

+mTransition     DW      _EntryPoint - m16Start

+

+    .code

+

+m16Start    LABEL   BYTE

+

+SavedGdt    LABEL   FWORD

+            DW      ?

+            DD      ?

+;------------------------------------------------------------------------------

+; _BackFromUserCode() takes control in real mode after 'retf' has been executed

+; by user code. It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_BackFromUserCode   PROC

+    ;

+    ; The order of saved registers on the stack matches the order they appears

+    ; in IA32_REGS structure. This facilitates wrapper function to extract them

+    ; into that structure.

+    ;

+    push    ss

+    push    cs

+    DB      66h

+    call    @Base                       ; push eip

+@Base:

+    pushf                               ; pushfd actually

+    cli                                 ; disable interrupts

+    push    gs

+    push    fs

+    push    es

+    push    ds

+    pushaw                              ; pushad actually

+    DB      66h, 0bah                   ; mov edx, imm32

+_ThunkAttr  DD      ?

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15

+    jz      @1

+    mov     eax, 15cd2401h              ; mov ax, 2401h & int 15h

+    cli                                 ; disable interrupts

+    jnc     @2

+@1:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL

+    jz      @2

+    in      al, 92h

+    or      al, 2

+    out     92h, al                     ; deactivate A20M#

+@2:

+    xor     ax, ax                      ; xor eax, eax

+    mov     eax, ss                     ; mov ax, ss

+    DB      67h

+    lea     bp, [esp + sizeof (IA32_REGS)]

+    ;

+    ; esi's in the following 2 instructions are indeed bp in 16-bit code. Fact

+    ; is "esi" in 32-bit addressing mode has the same encoding of "bp" in 16-

+    ; bit addressing mode.

+    ;

+    mov     word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp

+    mov     ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP

+    shl     ax, 4                       ; shl eax, 4

+    add     bp, ax                      ; add ebp, eax

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr4    DD      ?

+    mov     cr4, eax

+    DB      66h

+    lgdt    fword ptr cs:[edi + (SavedGdt - @Base)]

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr0    DD      ?

+    mov     cr0, eax

+    DB      0b8h                        ; mov ax, imm16

+SavedSs     DW      ?

+    mov     ss, eax

+    DB      66h, 0bch                   ; mov esp, imm32

+SavedEsp    DD      ?

+    DB      66h

+    retf                                ; return to protected mode

+_BackFromUserCode   ENDP

+

+_EntryPoint DD      _ToUserCode - m16Start

+            DW      8h

+_16Idtr     FWORD   (1 SHL 10) - 1

+_16Gdtr     LABEL   FWORD

+            DW      GdtEnd - _NullSegDesc - 1

+_16GdtrBase DD      _NullSegDesc

+

+;------------------------------------------------------------------------------

+; _ToUserCode() takes control in real mode before passing control to user code.

+; It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_ToUserCode PROC

+    mov     edx, ss

+    mov     ss, ecx                     ; set new segment selectors

+    mov     ds, ecx

+    mov     es, ecx

+    mov     fs, ecx

+    mov     gs, ecx

+    mov     cr0, eax                    ; real mode starts at next instruction

+                                        ;  which (per SDM) *must* be a far JMP.

+    DB      0eah

+_RealAddr DW 0,0                       ; filled in by InternalAsmThunk16

+

+    mov     cr4, ebp

+    mov     ss, esi                     ; set up 16-bit stack segment

+    xchg    sp, bx                      ; set up 16-bit stack pointer

+

+;   mov     bp, [esp + sizeof(IA32_REGS)

+    DB      67h

+    mov     ebp, [esp + sizeof(IA32_REGS)] ; BackFromUserCode address from stack

+

+;   mov     cs:[bp + (SavedSs - _BackFromUserCode)], dx

+    mov     cs:[esi + (SavedSs - _BackFromUserCode)], edx

+

+;   mov     cs:[bp + (SavedEsp - _BackFromUserCode)], ebx

+    DB      2eh, 66h, 89h, 9eh

+    DW      SavedEsp - _BackFromUserCode

+

+;   lidt    cs:[bp + (_16Idtr - _BackFromUserCode)]

+    DB      2eh, 66h, 0fh, 01h, 9eh

+    DW      _16Idtr - _BackFromUserCode

+

+    popaw                               ; popad actually

+    pop     ds

+    pop     es

+    pop     fs

+    pop     gs

+    popf                                ; popfd

+    DB      66h                         ; Use 32-bit addressing for "retf" below

+    retf                                ; transfer control to user code

+_ToUserCode ENDP

+

+_NullSegDesc    DQ      0

+_16CsDesc       LABEL   QWORD

+                DW      -1

+                DW      0

+                DB      0

+                DB      9bh

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+_16DsDesc       LABEL   QWORD

+                DW      -1

+                DW      0

+                DB      0

+                DB      93h

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+GdtEnd          LABEL   QWORD

+

+;------------------------------------------------------------------------------

+; IA32_REGISTER_SET *

+; EFIAPI

+; InternalAsmThunk16 (

+;   IN      IA32_REGISTER_SET         *RegisterSet,

+;   IN OUT  VOID                      *Transition

+;   );

+;------------------------------------------------------------------------------

+InternalAsmThunk16  PROC    USES    ebp ebx esi edi ds  es  fs  gs

+    mov     esi, [esp + 36]             ; esi <- RegSet, the 1st parameter

+    movzx   edx, (IA32_REGS ptr [esi])._SS

+    mov     edi, (IA32_REGS ptr [esi])._ESP

+    add     edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space

+    mov     ebx, edi                    ; ebx <- stack offset

+    imul    eax, edx, 16                ; eax <- edx * 16

+    push    sizeof (IA32_REGS) / 4

+    add     edi, eax                    ; edi <- linear address of 16-bit stack

+    pop     ecx

+    rep     movsd                       ; copy RegSet

+    mov     eax, [esp + 40]             ; eax <- address of transition code

+    mov     esi, edx                    ; esi <- 16-bit stack segment

+    lea     edx, [eax + (SavedCr0 - m16Start)]

+    mov     ecx, eax

+    and     ecx, 0fh

+    shl     eax, 12

+    lea     ecx, [ecx + (_BackFromUserCode - m16Start)]

+    mov     ax, cx

+    stosd                               ; [edi] <- return address of user code

+    add     eax, _RealAddr + 4 - _BackFromUserCode

+    mov     dword ptr [edx + (_RealAddr - SavedCr0)], eax

+    sgdt    fword ptr [edx + (SavedGdt - SavedCr0)]

+    sidt    fword ptr [esp + 36]        ; save IDT stack in argument space

+    mov     eax, cr0

+    mov     [edx], eax                  ; save CR0 in SavedCr0

+    and     eax, 7ffffffeh              ; clear PE, PG bits

+    mov     ebp, cr4

+    mov     [edx + (SavedCr4 - SavedCr0)], ebp

+    and     ebp, NOT 30h                ; clear PAE, PSE bits

+    push    10h

+    pop     ecx                         ; ecx <- selector for data segments

+    lgdt    fword ptr [edx + (_16Gdtr - SavedCr0)]

+    pushfd                              ; Save df/if indeed

+    call    fword ptr [edx + (_EntryPoint - SavedCr0)]

+    popfd

+    lidt    fword ptr [esp + 36]        ; restore protected mode IDTR

+    lea     eax, [ebp - sizeof (IA32_REGS)] ; eax <- the address of IA32_REGS

+    ret

+InternalAsmThunk16  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm
new file mode 100644
index 0000000..794d831
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm
@@ -0,0 +1,263 @@
+

+#include "BaseLibInternals.h"

+

+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   Thunk.asm

+;

+; Abstract:

+;

+;   Real mode thunk

+;

+;------------------------------------------------------------------------------

+

+global ASM_PFX(m16Size)

+global ASM_PFX(mThunk16Attr)

+global ASM_PFX(m16Gdt)

+global ASM_PFX(m16GdtrBase)

+global ASM_PFX(mTransition)

+global ASM_PFX(m16Start)

+

+struc IA32_REGS

+

+  ._EDI:       resd      1

+  ._ESI:       resd      1

+  ._EBP:       resd      1

+  ._ESP:       resd      1

+  ._EBX:       resd      1

+  ._EDX:       resd      1

+  ._ECX:       resd      1

+  ._EAX:       resd      1

+  ._DS:        resw      1

+  ._ES:        resw      1

+  ._FS:        resw      1

+  ._GS:        resw      1

+  ._EFLAGS:    resd      1

+  ._EIP:       resd      1

+  ._CS:        resw      1

+  ._SS:        resw      1

+  .size:

+

+endstruc

+

+;; .const

+

+SECTION .data

+

+;

+; These are global constant to convey information to C code.

+;

+ASM_PFX(m16Size)         DW      ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)

+ASM_PFX(mThunk16Attr)    DW      _BackFromUserCode.ThunkAttrEnd - 4 - ASM_PFX(m16Start)

+ASM_PFX(m16Gdt)          DW      _NullSegDesc - ASM_PFX(m16Start)

+ASM_PFX(m16GdtrBase)     DW      _16GdtrBase - ASM_PFX(m16Start)

+ASM_PFX(mTransition)     DW      _EntryPoint - ASM_PFX(m16Start)

+

+SECTION .text

+

+ASM_PFX(m16Start):

+

+SavedGdt:

+            dw  0

+            dd  0

+

+;------------------------------------------------------------------------------

+; _BackFromUserCode() takes control in real mode after 'retf' has been executed

+; by user code. It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_BackFromUserCode:

+    ;

+    ; The order of saved registers on the stack matches the order they appears

+    ; in IA32_REGS structure. This facilitates wrapper function to extract them

+    ; into that structure.

+    ;

+BITS    16

+    push    ss

+    push    cs

+    ;

+    ; Note: We can't use o32 on the next instruction because of a bug

+    ; in NASM 2.09.04 through 2.10rc1.

+    ;

+    call    dword .Base                 ; push eip

+.Base:

+    pushfd

+    cli                                 ; disable interrupts

+    push    gs

+    push    fs

+    push    es

+    push    ds

+    pushad

+    mov     edx, strict dword 0

+.ThunkAttrEnd:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15

+    jz      .1

+    mov     ax, 2401h

+    int     15h

+    cli                                 ; disable interrupts

+    jnc     .2

+.1:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL

+    jz      .2

+    in      al, 92h

+    or      al, 2

+    out     92h, al                     ; deactivate A20M#

+.2:

+    xor     eax, eax

+    mov     ax, ss

+    lea     ebp, [esp + IA32_REGS.size]

+    mov     [bp - IA32_REGS.size + IA32_REGS._ESP], ebp

+    mov     bx, [bp - IA32_REGS.size + IA32_REGS._EIP]

+    shl     eax, 4                      ; shl eax, 4

+    add     ebp, eax                    ; add ebp, eax

+    mov     eax, strict dword 0

+.SavedCr4End:

+    mov     cr4, eax

+o32 lgdt [cs:bx + (SavedGdt - .Base)]

+    mov     eax, strict dword 0

+.SavedCr0End:

+    mov     cr0, eax

+    mov     ax, strict word 0

+.SavedSsEnd:

+    mov     ss, eax

+    mov     esp, strict dword 0

+.SavedEspEnd:

+o32 retf                                ; return to protected mode

+

+_EntryPoint:

+        DD      _ToUserCode - ASM_PFX(m16Start)

+        DW      8h

+_16Idtr:

+        DW      (1 << 10) - 1

+        DD      0

+_16Gdtr:

+        DW      GdtEnd - _NullSegDesc - 1

+_16GdtrBase:

+        DD      0

+

+;------------------------------------------------------------------------------

+; _ToUserCode() takes control in real mode before passing control to user code.

+; It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_ToUserCode:

+BITS    16

+    mov     dx, ss

+    mov     ss, cx                      ; set new segment selectors

+    mov     ds, cx

+    mov     es, cx

+    mov     fs, cx

+    mov     gs, cx

+    mov     cr0, eax                    ; real mode starts at next instruction

+                                        ;  which (per SDM) *must* be a far JMP.

+    jmp     0:strict word 0

+.RealAddrEnd:

+    mov     cr4, ebp

+    mov     ss, si                      ; set up 16-bit stack segment

+    xchg    esp, ebx                    ; set up 16-bit stack pointer

+    mov     bp, [esp + IA32_REGS.size]

+    mov     [cs:bp + (_BackFromUserCode.SavedSsEnd - 2 - _BackFromUserCode)], dx

+    mov     [cs:bp + (_BackFromUserCode.SavedEspEnd - 4 - _BackFromUserCode)], ebx

+    lidt    [cs:bp + (_16Idtr - _BackFromUserCode)]

+

+    popad

+    pop     ds

+    pop     es

+    pop     fs

+    pop     gs

+    popfd

+

+o32 retf                                ; transfer control to user code

+

+ALIGN   16

+_NullSegDesc    DQ      0

+_16CsDesc:

+                DW      -1

+                DW      0

+                DB      0

+                DB      9bh

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+_16DsDesc:

+                DW      -1

+                DW      0

+                DB      0

+                DB      93h

+                DB      8fh             ; 16-bit segment, 4GB limit

+                DB      0

+GdtEnd:

+

+;------------------------------------------------------------------------------

+; IA32_REGISTER_SET *

+; EFIAPI

+; InternalAsmThunk16 (

+;   IN      IA32_REGISTER_SET         *RegisterSet,

+;   IN OUT  VOID                      *Transition

+;   );

+;------------------------------------------------------------------------------

+global ASM_PFX(InternalAsmThunk16)

+ASM_PFX(InternalAsmThunk16):

+BITS    32

+    push    ebp

+    push    ebx

+    push    esi

+    push    edi

+    push    ds

+    push    es

+    push    fs

+    push    gs

+    mov     esi, [esp + 36]             ; esi <- RegSet, the 1st parameter

+    movzx   edx, word [esi + IA32_REGS._SS]

+    mov     edi, [esi + IA32_REGS._ESP]

+    add     edi, - (IA32_REGS.size + 4) ; reserve stack space

+    mov     ebx, edi                    ; ebx <- stack offset

+    imul    eax, edx, 16                ; eax <- edx * 16

+    push    IA32_REGS.size / 4

+    add     edi, eax                    ; edi <- linear address of 16-bit stack

+    pop     ecx

+    rep     movsd                       ; copy RegSet

+    mov     eax, [esp + 40]             ; eax <- address of transition code

+    mov     esi, edx                    ; esi <- 16-bit stack segment

+    lea     edx, [eax + (_BackFromUserCode.SavedCr0End - ASM_PFX(m16Start))]

+    mov     ecx, eax

+    and     ecx, 0fh

+    shl     eax, 12

+    lea     ecx, [ecx + (_BackFromUserCode - ASM_PFX(m16Start))]

+    mov     ax, cx

+    stosd                               ; [edi] <- return address of user code

+    add     eax, _ToUserCode.RealAddrEnd - _BackFromUserCode

+    mov     [edx + (_ToUserCode.RealAddrEnd - 4 - _BackFromUserCode.SavedCr0End)], eax

+    sgdt    [edx + (SavedGdt - _BackFromUserCode.SavedCr0End)]

+    sidt    [esp + 36]        ; save IDT stack in argument space

+    mov     eax, cr0

+    mov     [edx - 4], eax                  ; save CR0 in _BackFromUserCode.SavedCr0End - 4

+    and     eax, 7ffffffeh              ; clear PE, PG bits

+    mov     ebp, cr4

+    mov     [edx + (_BackFromUserCode.SavedCr4End - 4 - _BackFromUserCode.SavedCr0End)], ebp

+    and     ebp, ~30h                ; clear PAE, PSE bits

+    push    10h

+    pop     ecx                         ; ecx <- selector for data segments

+    lgdt    [edx + (_16Gdtr - _BackFromUserCode.SavedCr0End)]

+    pushfd                              ; Save df/if indeed

+    call    dword far [edx + (_EntryPoint - _BackFromUserCode.SavedCr0End)]

+    popfd

+    lidt    [esp + 36]        ; restore protected mode IDTR

+    lea     eax, [ebp - IA32_REGS.size] ; eax <- the address of IA32_REGS

+    pop     gs

+    pop     fs

+    pop     es

+    pop     ds

+    pop     edi

+    pop     esi

+    pop     ebx

+    pop     ebp

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.asm
new file mode 100644
index 0000000..06db1c8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Wbinvd.Asm

+;

+; Abstract:

+;

+;   AsmWbinvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWbinvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWbinvd   PROC

+    wbinvd

+    ret

+AsmWbinvd   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.c
new file mode 100644
index 0000000..f9a3858
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/Wbinvd.c
@@ -0,0 +1,35 @@
+/** @file

+  AsmWbinvd function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Executes a WBINVD instruction.

+

+  Executes a WBINVD instruction. This function is only available on IA-32 and

+  x64.

+

+**/

+VOID

+EFIAPI

+AsmWbinvd (

+  VOID

+  )

+{

+  _asm {

+    wbinvd

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.asm
new file mode 100644
index 0000000..edcf710
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr0 (

+;   UINTN  Cr0

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr0 PROC

+    mov     eax, [esp + 4]

+    mov     cr0, eax

+    ret

+AsmWriteCr0 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.c
new file mode 100644
index 0000000..29bd348
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr0.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteCr0 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to CR0.

+

+  @return The value written to CR0.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr0 (

+  UINTN  Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     cr0, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.asm
new file mode 100644
index 0000000..06c54b0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr2 (

+;   UINTN  Cr2

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr2 PROC

+    mov     eax, [esp + 4]

+    mov     cr2, eax

+    ret

+AsmWriteCr2 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.c
new file mode 100644
index 0000000..38ff792
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr2.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteCr2 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to CR2.

+

+  @return The value written to CR2.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr2 (

+  UINTN  Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     cr2, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.asm
new file mode 100644
index 0000000..69e87ba
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr3 (

+;   UINTN  Cr3

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr3 PROC

+    mov     eax, [esp + 4]

+    mov     cr3, eax

+    ret

+AsmWriteCr3 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.c
new file mode 100644
index 0000000..8839c7c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr3.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteCr3 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to CR3.

+

+  @return The value written to CR3.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr3 (

+  UINTN  Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     cr3, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.asm
new file mode 100644
index 0000000..ad45348
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr4 (

+;   UINTN  Cr4

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr4 PROC

+    mov     eax, [esp + 4]

+    mov     cr4, eax

+    ret

+AsmWriteCr4 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.c
new file mode 100644
index 0000000..868bed4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteCr4.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmWriteCr4 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to CR4.

+

+  @return The value written to CR4.

+

+**/

+UINTN

+EFIAPI

+AsmWriteCr4 (

+  UINTN  Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    _emit  0x0f  // mov  cr4, eax

+    _emit  0x22

+    _emit  0xE0

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.asm
new file mode 100644
index 0000000..5528134
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr0 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr0 PROC

+    mov     eax, [esp + 4]

+    mov     dr0, eax

+    ret

+AsmWriteDr0 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.c
new file mode 100644
index 0000000..082646d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr0.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteDr0 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr0.

+

+  @return The value written to Debug Register 0 (DR0).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr0 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     dr0, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.asm
new file mode 100644
index 0000000..ad9f885
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr1.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr1 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr1 PROC

+    mov     eax, [esp + 4]

+    mov     dr1, eax

+    ret

+AsmWriteDr1 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.c
new file mode 100644
index 0000000..bdb0b70
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr1.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteDr1 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr1.

+

+  @return The value written to Debug Register 1 (DR1).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr1 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     dr1, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.asm
new file mode 100644
index 0000000..266ff7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr2 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr2 PROC

+    mov     eax, [esp + 4]

+    mov     dr2, eax

+    ret

+AsmWriteDr2 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.c
new file mode 100644
index 0000000..0dd0e11
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr2.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteDr2 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr2.

+

+  @return The value written to Debug Register 2 (DR2).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr2 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     dr2, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.asm
new file mode 100644
index 0000000..b24d105
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr3 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr3 PROC

+    mov     eax, [esp + 4]

+    mov     dr3, eax

+    ret

+AsmWriteDr3 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.c
new file mode 100644
index 0000000..0333681
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr3.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteDr3 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr3.

+

+  @return The value written to Debug Register 3 (DR3).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr3 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     dr3, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm
new file mode 100644
index 0000000..bc8eef1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm
@@ -0,0 +1,48 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr4 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr4 PROC

+    mov     eax, [esp + 4]

+    ;

+    ; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, writing to

+    ; this register will cause a #UD exception.

+    ;

+    ; MS assembler doesn't support this instruction since no one would use it

+    ; under normal circustances. Here opcode is used.

+    ;

+    DB      0fh, 23h, 0e0h

+    ret

+AsmWriteDr4 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.c
new file mode 100644
index 0000000..45b3271
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmWriteDr4 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr4.

+

+  @return The value written to Debug Register 4 (DR4).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr4 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    _emit   0x0f         // mov dr4, eax

+    _emit   0x23

+    _emit   0xe0

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm
new file mode 100644
index 0000000..0df8175
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm
@@ -0,0 +1,48 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr5.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr5 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr5 PROC

+    mov     eax, [esp + 4]

+    ;

+    ; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, writing to

+    ; this register will cause a #UD exception.

+    ;

+    ; MS assembler doesn't support this instruction since no one would use it

+    ; under normal circustances. Here opcode is used.

+    ;

+    DB      0fh, 23h, 0e8h

+    ret

+AsmWriteDr5 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.c
new file mode 100644
index 0000000..2cb528f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmWriteDr5 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr5.

+

+  @return The value written to Debug Register 5 (DR5).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr5 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    _emit   0x0f         // mov dr5, eax

+    _emit   0x23

+    _emit   0xe8

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.asm
new file mode 100644
index 0000000..dc399ea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr6.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr6 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr6 PROC

+    mov     eax, [esp + 4]

+    mov     dr6, eax

+    ret

+AsmWriteDr6 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.c
new file mode 100644
index 0000000..33b0bd4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr6.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteDr6 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr6.

+

+  @return The value written to Debug Register 6 (DR6).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr6 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     dr6, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.asm
new file mode 100644
index 0000000..ace8822
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr7.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr7 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr7 PROC

+    mov     eax, [esp + 4]

+    mov     dr7, eax

+    ret

+AsmWriteDr7 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.c
new file mode 100644
index 0000000..d465dc2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteDr7.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteDr7 function

+

+  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.

+

+**/

+

+/**

+  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  Value The value to write to Dr7.

+

+  @return The value written to Debug Register 7 (DR7).

+

+**/

+UINTN

+EFIAPI

+AsmWriteDr7 (

+  IN UINTN Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    mov     dr7, eax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.asm
new file mode 100644
index 0000000..d95ef31
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteGdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86WriteGdtr (

+;   IN      CONST IA32_DESCRIPTOR     *Idtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86WriteGdtr  PROC

+    mov     eax, [esp + 4]

+    lgdt    fword ptr [eax]

+    ret

+InternalX86WriteGdtr  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.c
new file mode 100644
index 0000000..cc7a066
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteGdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmWriteGdtr function

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  )

+{

+  _asm {

+    mov     eax, Gdtr

+    lgdt    fword ptr [eax]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.asm
new file mode 100644
index 0000000..da15433
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   WriteIdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86WriteIdtr (

+;   IN      CONST IA32_DESCRIPTOR     *Idtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86WriteIdtr  PROC

+    mov     eax, [esp + 4]

+    pushfd

+    cli

+    lidt    fword ptr [eax]

+    popfd

+    ret

+InternalX86WriteIdtr  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.c
new file mode 100644
index 0000000..72005cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteIdtr.c
@@ -0,0 +1,41 @@
+/** @file

+  AsmWriteIdtr function

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Writes the current IDTR descriptor and returns it in Idtr. This function is

+  only available on IA-32 and x64.

+

+  @param  Idtr  The pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  )

+{

+  _asm {

+    mov     eax, Idtr

+    pushfd

+    cli

+    lidt    fword ptr [eax]

+    popfd

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.asm
new file mode 100644
index 0000000..abcd74d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteLdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386p

+    .model  flat

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteLdtr (

+;   IN UINT16 Ldtr

+;   );

+;------------------------------------------------------------------------------

+_AsmWriteLdtr   PROC

+    mov     eax, [esp + 4]

+    lldt    ax

+    ret

+_AsmWriteLdtr   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.c
new file mode 100644
index 0000000..ba70fd9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteLdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  AsmWriteLdtr function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Writes the current Local Descriptor Table Register (GDTR) 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

+  )

+{

+  _asm {

+    xor     eax, eax

+    mov     ax, Ldtr

+    lldt    ax

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.asm
new file mode 100644
index 0000000..de89a86
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm0.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm0 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm0 PROC

+    movq    mm0, [esp + 4]

+    ret

+AsmWriteMm0 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.c
new file mode 100644
index 0000000..fe04f2f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm0.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmWriteMm0 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm0, qword ptr [Value]

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.asm
new file mode 100644
index 0000000..2bb255f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm1.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm1 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm1 PROC

+    movq    mm1, [esp + 4]

+    ret

+AsmWriteMm1 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.c
new file mode 100644
index 0000000..1eb449a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm1.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmWriteMm1 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm1, qword ptr [Value]

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.asm
new file mode 100644
index 0000000..99a9fc8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm2.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm2 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm2 PROC

+    movq    mm2, [esp + 4]

+    ret

+AsmWriteMm2 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.c
new file mode 100644
index 0000000..64e2672
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm2.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmWriteMm2 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm2, qword ptr [Value]

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.asm
new file mode 100644
index 0000000..7ae32ed
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm3.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm3 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm3 PROC

+    movq    mm3, [esp + 4]

+    ret

+AsmWriteMm3 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.c
new file mode 100644
index 0000000..6a16493
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm3.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmWriteMm3 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm3, qword ptr [Value]

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.asm
new file mode 100644
index 0000000..0ede40e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm4.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm4 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm4 PROC

+    movq    mm4, [esp + 4]

+    ret

+AsmWriteMm4 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.c
new file mode 100644
index 0000000..c3a6d1e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm4.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteMm4 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm4, qword ptr [Value]

+    emms

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.asm
new file mode 100644
index 0000000..1438a88
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm5.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm5 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm5 PROC

+    movq    mm5, [esp + 4]

+    ret

+AsmWriteMm5 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.c
new file mode 100644
index 0000000..489ec2d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm5.c
@@ -0,0 +1,37 @@
+/** @file

+  AsmWriteMm5 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm5, qword ptr [Value]

+    emms

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.asm
new file mode 100644
index 0000000..d7bce97
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm6.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm6 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm6 PROC

+    movq    mm6, [esp + 4]

+    ret

+AsmWriteMm6 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.c
new file mode 100644
index 0000000..5ada5f0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm6.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmWriteMm6 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm6, qword ptr [Value]

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.asm
new file mode 100644
index 0000000..c6920b4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm7.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm7 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm7 PROC

+    movq    mm7, [esp + 4]

+    ret

+AsmWriteMm7 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.c
new file mode 100644
index 0000000..f6b9d1c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMm7.c
@@ -0,0 +1,38 @@
+/** @file

+  AsmWriteMm7 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    movq    mm7, qword ptr [Value]

+    emms

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.S
new file mode 100644
index 0000000..658de19
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.S
@@ -0,0 +1,38 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   WriteMsr64.S

+#

+# Abstract:

+#

+#   AsmWriteMsr64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+# UINT64

+# EFIAPI

+# AsmWriteMsr64 (

+#   IN UINT32  Index,

+#   IN UINT64  Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmWriteMsr64)

+ASM_PFX(AsmWriteMsr64):

+    movl    12(%esp), %edx

+    movl    8(%esp), %eax

+    movl    4(%esp), %ecx

+    wrmsr

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.asm
new file mode 100644
index 0000000..109adc8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMsr64.Asm

+;

+; Abstract:

+;

+;   AsmWriteMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586p

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMsr64 (

+;   IN UINT32  Index,

+;   IN UINT64  Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMsr64   PROC

+    mov     edx, [esp + 12]

+    mov     eax, [esp + 8]

+    mov     ecx, [esp + 4]

+    wrmsr

+    ret

+AsmWriteMsr64   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c
new file mode 100644
index 0000000..2f22f49
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c
@@ -0,0 +1,49 @@
+/** @file

+  AsmWriteMsr64 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  _asm {

+    mov     edx, dword ptr [Value + 4]

+    mov     eax, dword ptr [Value + 0]

+    mov     ecx, Index

+    wrmsr

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessDbr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessDbr.s
new file mode 100644
index 0000000..c74737b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessDbr.s
@@ -0,0 +1,118 @@
+/// @file

+///  IPF specific Debug Breakpoint Registers accessing functions

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name: AccessDbr.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadDbr

+//

+// This routine is used to Reads the current value of Data Breakpoint Register (DBR).

+//

+// Arguments :

+//

+// On Entry : The 8-bit DBR index to read.

+//

+// Return Value: The current value of DBR by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadDbr, @function

+.proc   AsmReadDbr

+.regstk 1, 0, 0, 0

+

+AsmReadDbr::

+        mov             r8 = dbr[in0];;

+        br.ret.dpnt     b0;;

+.endp   AsmReadDbr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteDbr

+//

+// This routine is used to write the current value to Data Breakpoint Register (DBR).

+//

+// Arguments :

+//

+// On Entry : The 8-bit DBR index to read.

+//            The value should be written to DBR

+//

+// Return Value: The value written to DBR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteDbr, @function

+.proc   AsmWriteDbr

+.regstk 2, 0, 0, 0

+

+AsmWriteDbr::

+        mov             dbr[in0] = in1

+        mov             r8 = in1;;

+        srlz.d;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteDbr

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIbr

+//

+// This routine is used to Reads the current value of Instruction Breakpoint Register (IBR).

+//

+// Arguments :

+//

+// On Entry : The 8-bit IBR index.

+//

+// Return Value: The current value of IBR by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIbr, @function

+.proc   AsmReadIbr

+.regstk 1, 0, 0, 0

+

+AsmReadIbr::

+        mov             r8 = ibr[in0];;

+        br.ret.dpnt     b0;;

+.endp   AsmReadIbr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteIbr

+//

+// This routine is used to write the current value to Instruction Breakpoint Register (IBR).

+//

+// Arguments :

+//

+// On Entry : The 8-bit IBR index.

+//            The value should be written to IBR

+//

+// Return Value: The value written to IBR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteIbr, @function

+.proc   AsmWriteIbr

+.regstk 2, 0, 0, 0

+

+AsmWriteIbr::

+        mov             ibr[in0] = in1

+        mov             r8 = in1;;

+        srlz.i;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteIbr

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessEicr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessEicr.s
new file mode 100644
index 0000000..c2f977e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessEicr.s
@@ -0,0 +1,512 @@
+/// @file

+///  IPF specific External Interrupt Control Registers accessing functions

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name: AccessEicr.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadLid

+//

+// This routine is used to read the value of Local Interrupt ID Register (LID).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of LID.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadLid, @function

+.proc   AsmReadLid

+

+AsmReadLid::

+         mov            r8 = cr.lid;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadLid

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteLid

+//

+// This routine is used to write the value to Local Interrupt ID Register (LID).

+//

+// Arguments :

+//

+// On Entry :  The value need to be written to LID.

+//

+// Return Value: The value written to LID.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteLid, @function

+.proc   AsmWriteLid

+.regstk 1, 0, 0, 0

+

+AsmWriteLid::

+         mov            cr.lid = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteLid

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIvr

+//

+// This routine is used to read the value of External Interrupt Vector Register (IVR).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of IVR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIvr, @function

+.proc   AsmReadIvr

+

+AsmReadIvr::

+         mov            r8 = cr.ivr;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadIvr

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadTpr

+//

+// This routine is used to read the value of Task Priority Register (TPR).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of TPR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadTpr, @function

+.proc   AsmReadTpr

+

+AsmReadTpr::

+         mov            r8 = cr.tpr;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadTpr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteTpr

+//

+// This routine is used to write the value to Task Priority Register (TPR).

+//

+// Arguments :

+//

+// On Entry :  The value need to be written to TPR.

+//

+// Return Value: The value written to TPR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteTpr, @function

+.proc   AsmWriteTpr

+.regstk 1, 0, 0, 0

+

+AsmWriteTpr::

+         mov            cr.tpr = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteTpr

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteEoi

+//

+// This routine is used to write the value to End of External Interrupt Register (EOI).

+//

+// Arguments :

+//

+// On Entry :  The value need to be written to EOI.

+//

+// Return Value: The value written to EOI.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteEoi, @function

+.proc   AsmWriteEoi

+

+AsmWriteEoi::

+         mov            cr.eoi = r0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteEoi

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIrr0

+//

+// This routine is used to Read the value of External Interrupt Request Register 0 (IRR0).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of IRR0.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIrr0, @function

+.proc   AsmReadIrr0

+

+AsmReadIrr0::

+         mov            r8 = cr.irr0;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadIrr0

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIrr1

+//

+// This routine is used to Read the value of External Interrupt Request Register 1 (IRR1).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of IRR1.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIrr1, @function

+.proc   AsmReadIrr1

+

+AsmReadIrr1::

+         mov            r8 = cr.irr1;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadIrr1

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIrr2

+//

+// This routine is used to Read the value of External Interrupt Request Register 2 (IRR2).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of IRR2.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIrr2, @function

+.proc   AsmReadIrr2

+

+AsmReadIrr2::

+         mov            r8 = cr.irr2;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadIrr2

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIrr3

+//

+// This routine is used to Read the value of External Interrupt Request Register 3 (IRR3).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of IRR3.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIrr3, @function

+.proc   AsmReadIrr3

+

+AsmReadIrr3::

+         mov            r8 = cr.irr3;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadIrr3

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadItv

+//

+// This routine is used to Read the value of Interval Timer Vector Register (ITV).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of ITV.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadItv, @function

+.proc   AsmReadItv

+

+AsmReadItv::

+         mov            r8 = cr.itv;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadItv

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteItv

+//

+// This routine is used to write the value to Interval Timer Vector Register (ITV).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to ITV

+//

+// Return Value: The value written to ITV.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteItv, @function

+.proc   AsmWriteItv

+.regstk 1, 0, 0, 0

+

+AsmWriteItv::

+         mov            cr.itv = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteItv

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadPmv

+//

+// This routine is used to Read the value of Performance Monitoring Vector Register (PMV).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of PMV.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadPmv, @function

+.proc   AsmReadPmv

+

+AsmReadPmv::

+         mov            r8 = cr.pmv;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadPmv

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWritePmv

+//

+// This routine is used to write the value to Performance Monitoring Vector Register (PMV).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to PMV

+//

+// Return Value: The value written to PMV.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWritePmv, @function

+.proc   AsmWritePmv

+.regstk 1, 0, 0, 0

+

+AsmWritePmv::

+         mov            cr.pmv = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWritePmv

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadCmcv

+//

+// This routine is used to Read the value of Corrected Machine Check Vector Register (CMCV).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of CMCV.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadCmcv, @function

+.proc   AsmReadCmcv

+

+AsmReadCmcv::

+         mov            r8 = cr.cmcv;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadCmcv

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteCmcv

+//

+// This routine is used to write the value to Corrected Machine Check Vector Register (CMCV).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to CMCV

+//

+// Return Value: The value written to CMCV.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteCmcv, @function

+.proc   AsmWriteCmcv

+.regstk 1, 0, 0, 0

+

+AsmWriteCmcv::

+         mov            cr.cmcv = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteCmcv

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadLrr0

+//

+// This routine is used to read the value of Local Redirection Register 0 (LRR0).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of LRR0.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadLrr0, @function

+.proc   AsmReadLrr0

+

+AsmReadLrr0::

+         mov            r8 = cr.lrr0;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadLrr0

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteLrr0

+//

+// This routine is used to write the value to Local Redirection Register 0 (LRR0).

+//

+// Arguments :

+//

+// On Entry :  The value need to be written to LRR0.

+//

+// Return Value: The value written to LRR0.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteLrr0, @function

+.proc   AsmWriteLrr0

+.regstk 1, 0, 0, 0

+

+AsmWriteLrr0::

+         mov            cr.lrr0 = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteLrr0

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadLrr1

+//

+// This routine is used to read the value of Local Redirection Register 1 (LRR1).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of LRR1.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadLrr1, @function

+.proc   AsmReadLrr1

+

+AsmReadLrr1::

+         mov            r8 = cr.lrr1;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadLrr1

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteLrr1

+//

+// This routine is used to write the value to Local Redirection Register 1 (LRR1).

+//

+// Arguments :

+//

+// On Entry :  The value need to be written to LRR1.

+//

+// Return Value: The value written to LRR1.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteLrr1, @function

+.proc   AsmWriteLrr1

+.regstk 1, 0, 0, 0

+

+AsmWriteLrr1::

+         mov            cr.lrr1 = in0

+         mov            r8 = in0;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteLrr1

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessGcr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessGcr.s
new file mode 100644
index 0000000..d519e7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessGcr.s
@@ -0,0 +1,274 @@
+/// @file

+///  IPF specific Global Control Registers accessing functions

+///

+/// 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.

+///

+/// Module Name: AccessGcr.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadDcr

+//

+// This routine is used to Read the value of Default Control Register (DCR).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of DCR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadDcr, @function

+.proc   AsmReadDcr

+

+AsmReadDcr::

+         mov            r8 = cr.dcr;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadDcr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteDcr

+//

+// This routine is used to write the value to Default Control Register (DCR).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to DCR

+//

+// Return Value: The value written to DCR.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteDcr, @function

+.proc   AsmWriteDcr

+.regstk 1, 0, 0, 0

+

+AsmWriteDcr::

+         mov            cr.dcr = in0

+         mov            r8 = in0;;

+         srlz.i;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteDcr

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadItc

+//

+// This routine is used to Read the value of Interval Timer Counter Register (ITC).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of ITC.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadItc, @function

+.proc   AsmReadItc

+

+AsmReadItc::

+         mov            r8 = ar.itc;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadItc

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteItc

+//

+// This routine is used to write the value to Interval Timer Counter Register (ITC).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to the ITC

+//

+// Return Value: The value written to the ITC.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteItc, @function

+.proc   AsmWriteItc

+.regstk 1, 0, 0, 0

+

+AsmWriteItc::

+         mov            ar.itc = in0

+         mov            r8 = in0;;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteItc

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadItm

+//

+// This routine is used to Read the value of Interval Timer Match Register (ITM).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of ITM.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadItm, @function

+.proc   AsmReadItm

+

+AsmReadItm::

+         mov            r8 = cr.itm;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadItm

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteItm

+//

+// This routine is used to write the value to Interval Timer Match Register (ITM).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to ITM

+//

+// Return Value: The value written to ITM.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteItm, @function

+.proc   AsmWriteItm

+.regstk 1, 0, 0, 0

+

+AsmWriteItm::

+         mov            cr.itm = in0

+         mov            r8 = in0;;

+         srlz.d;

+         br.ret.dpnt    b0;;

+.endp    AsmWriteItm

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadIva

+//

+// This routine is used to read the value of Interruption Vector Address Register (IVA).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of IVA.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadIva, @function

+.proc   AsmReadIva

+

+AsmReadIva::

+         mov            r8 = cr.iva;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadIva

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteIva

+//

+// This routine is used to write the value to Interruption Vector Address Register (IVA).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to IVA

+//

+// Return Value: The value written to IVA.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteIva, @function

+.proc   AsmWriteIva

+.regstk 1, 3, 0, 0

+

+AsmWriteIva::

+        alloc loc1=ar.pfs,1,4,0,0 ;;

+

+        mov         loc2 = psr

+        rsm         0x6000                      // Make sure interrupts are masked

+

+        mov            cr.iva = in0

+        srlz.i;;

+        mov         psr.l = loc2;;

+        srlz.i;;

+        srlz.d;;

+        mov ar.pfs=loc1 ;;

+        mov            r8 = in0;;

+        br.ret.dpnt    b0;;

+.endp   AsmWriteIva

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadPta

+//

+// This routine is used to read the value of Page Table Address Register (PTA).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current value of PTA.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadPta, @function

+.proc   AsmReadPta

+

+AsmReadPta::

+         mov            r8 = cr.pta;;

+         br.ret.dpnt    b0;;

+.endp    AsmReadPta

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWritePta

+//

+// This routine is used to write the value to Page Table Address Register (PTA)).

+//

+// Arguments :

+//

+// On Entry : The value need to be written to PTA

+//

+// Return Value: The value written to PTA.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWritePta, @function

+.proc   AsmWritePta

+.regstk 1, 0, 0, 0

+

+AsmWritePta::

+         mov            cr.pta = in0

+         mov            r8 = in0;;

+         srlz.i;;

+         srlz.d;;

+         br.ret.dpnt    b0;;

+.endp    AsmWritePta

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessGp.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessGp.s
new file mode 100644
index 0000000..a0e3d3f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessGp.s
@@ -0,0 +1,86 @@
+/// @file

+///  IPF specific Global Pointer and Stack Pointer accessing functions

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name: AccessGp.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadGp

+//

+// This routine is used to read the current value of 64-bit Global Pointer (GP).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current GP value.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadGp, @function

+.proc   AsmReadGp

+

+AsmReadGp::

+        mov             r8 = gp;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadGp

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteGp

+//

+// This routine is used to write the current value of 64-bit Global Pointer (GP).

+//

+// Arguments :

+//

+// On Entry : The value need to be written.

+//

+// Return Value: The value have been written.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteGp, @function

+.proc   AsmWriteGp

+.regstk 1, 0, 0, 0

+

+AsmWriteGp::

+        mov             gp = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteGp

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadSp

+//

+// This routine is used to read the current value of 64-bit Stack Pointer (SP).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current SP value.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadSp, @function

+.proc   AsmReadSp

+

+AsmReadSp::

+        mov             r8 = sp;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadSp

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessKr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessKr.s
new file mode 100644
index 0000000..4d4798d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessKr.s
@@ -0,0 +1,360 @@
+/// @file

+///  IPF specific AsmReadKrX() and AsmWriteKrX() functions, 'X' is from '0' to '6'

+///

+/// Copyright (c) 2006 - 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.

+///

+/// Module Name: AccessKr.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr0

+//

+// This routine is used to get KR0.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR0.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr0, @function

+.proc   AsmReadKr0

+

+AsmReadKr0::

+        mov             r8 = ar.k0;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr0

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr0

+//

+// This routine is used to Write KR0.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR0.

+//

+//--

+//----------------------------------------------------------------------------------

+

+.text

+.type   AsmWriteKr0, @function

+.proc   AsmWriteKr0

+.regstk 1, 3, 0, 0

+

+AsmWriteKr0::

+        alloc loc1=ar.pfs,1,4,0,0 ;;

+        mov             loc2 = psr;;

+        rsm             0x6000;;                      // Masking interrupts

+        mov             ar.k0 = in0

+        srlz.i;;

+        mov             psr.l = loc2;;

+        srlz.i;;

+        srlz.d;;

+        mov             r8 = in0;;

+        mov ar.pfs=loc1 ;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr0

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr1

+//

+// This routine is used to get KR1.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR1.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr1, @function

+.proc   AsmReadKr1

+

+AsmReadKr1::

+        mov             r8 = ar.k1;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr1

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr1

+//

+// This routine is used to Write KR1.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR1.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr1, @function

+.proc   AsmWriteKr1

+

+AsmWriteKr1::

+        mov             ar.k1 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr1

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr2

+//

+// This routine is used to get KR2.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR2.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr2, @function

+.proc   AsmReadKr2

+

+AsmReadKr2::

+        mov             r8 = ar.k2;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr2

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr2

+//

+// This routine is used to Write KR2.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR2.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr2, @function

+.proc   AsmWriteKr2

+

+AsmWriteKr2::

+        mov             ar.k2 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr2

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr3

+//

+// This routine is used to get KR3.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR3.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr3, @function

+.proc   AsmReadKr3

+

+AsmReadKr3::

+        mov             r8 = ar.k3;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr3

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr3

+//

+// This routine is used to Write KR3.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR3.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr3, @function

+.proc   AsmWriteKr3

+

+AsmWriteKr3::

+        mov             ar.k3 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr3

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr4

+//

+// This routine is used to get KR4.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR4.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr4, @function

+.proc   AsmReadKr4

+

+AsmReadKr4::

+        mov             r8 = ar.k4;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr4

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr4

+//

+// This routine is used to Write KR4.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR4.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr4, @function

+.proc   AsmWriteKr4

+

+AsmWriteKr4::

+        mov             ar.k4 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr4

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr5

+//

+// This routine is used to get KR5.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR5.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr5, @function

+.proc   AsmReadKr5

+

+AsmReadKr5::

+        mov             r8 = ar.k5;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr5

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr5

+//

+// This routine is used to Write KR5.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR5.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr5, @function

+.proc   AsmWriteKr5

+

+AsmWriteKr5::

+        mov             ar.k5 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr5

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr6

+//

+// This routine is used to get KR6.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR6.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr6, @function

+.proc   AsmReadKr6

+

+AsmReadKr6::

+        mov             r8 = ar.k6;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr6

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr6

+//

+// This routine is used to write KR6.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR6.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr6, @function

+.proc   AsmWriteKr6

+

+AsmWriteKr6::

+        mov             ar.k6 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr6

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessKr7.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessKr7.s
new file mode 100644
index 0000000..66a3dbf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessKr7.s
@@ -0,0 +1,63 @@
+/// @file

+///  IPF specific AsmReadKr7() and AsmWriteKr7()

+///

+/// Copyright (c) 2006 - 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.

+///

+/// Module Name: AccessKr7.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadKr7

+//

+// This routine is used to get KR7.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value store in KR7.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadKr7, @function

+.proc   AsmReadKr7

+

+AsmReadKr7::

+        mov             r8 = ar.k7;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadKr7

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteKr7

+//

+// This routine is used to write KR7.

+//

+// Arguments :

+//

+// On Entry :  None.

+//

+// Return Value: The value written to the KR7.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteKr7, @function

+.proc   AsmWriteKr7

+.regstk 1, 3, 0, 0

+

+AsmWriteKr7::

+        mov             ar.k7 = in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmWriteKr7

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessMsr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessMsr.s
new file mode 100644
index 0000000..11b3f1e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessMsr.s
@@ -0,0 +1,79 @@
+/// @file

+///  IPF specific Machine Specific Registers accessing functions.

+///

+/// Copyright (c) 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.

+///

+///

+///

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadMsr

+//

+// 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 IPF.

+//

+// Arguments :

+//

+// On Entry : The 8-bit Machine Specific Register index to read.

+//

+// Return Value: The current value of the Machine Specific Register specified by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadMsr, @function

+.proc   AsmReadMsr

+.regstk 1, 0, 0, 0

+

+AsmReadMsr::

+  mov    r8=msr[in0];;

+  br.ret.sptk  b0;;

+.endp   AsmReadMsr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteMsr

+//

+// 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 IPF.

+//

+// Arguments :

+//

+// On Entry : The 8-bit Machine Specific Register index to write.

+//            The 64-bit value to write to the Machine Specific Register.

+//

+// Return Value: The 64-bit value to write to the Machine Specific Register.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteMsr, @function

+.proc   AsmWriteMsr

+.regstk 2, 0, 0, 0

+

+AsmWriteMsr::

+  mov             msr[in0] = in1

+  mov             r8 = in1;;

+  srlz.d;;

+  br.ret.sptk     b0;;

+.endp   AsmWriteMsr

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessMsrDb.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessMsrDb.s
new file mode 100644
index 0000000..79468e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessMsrDb.s
@@ -0,0 +1,121 @@
+/// @file

+///  IPF specific Machine Specific Registers accessing functions. 

+///  This implementation uses raw data to prepresent the assembly instruction of 

+/// mov msr[]= and mov =msr[].

+///

+/// Copyright (c) 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.

+///

+///

+///

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadMsr

+//

+// 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 IPF.

+//

+// Arguments :

+//

+// On Entry : The 8-bit Machine Specific Register index to read.

+//

+// Return Value: The current value of the Machine Specific Register specified by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadMsr, @function

+.proc   AsmReadMsr

+.regstk 1, 0, 0, 0

+

+AsmReadMsr::

+//

+// The follow 16 bytes stand for the bundle of 

+//   mov    r8=msr[in0];;

+// since MSFT tool chain does not support mov =msr[] instruction

+//

+  data1 0x0D

+  data1 0x40

+  data1 0x00

+  data1 0x40

+  data1 0x16

+  data1 0x04

+  data1 0x00

+  data1 0x00

+  data1 0x00

+  data1 0x02

+  data1 0x00

+  data1 0x00

+  data1 0x00

+  data1 0x00

+  data1 0x04

+  data1 0x00

+  br.ret.sptk  b0;;

+.endp   AsmReadMsr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWriteMsr

+//

+// 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 IPF.

+//

+// Arguments :

+//

+// On Entry : The 8-bit Machine Specific Register index to write.

+//            The 64-bit value to write to the Machine Specific Register.

+//

+// Return Value: The 64-bit value to write to the Machine Specific Register.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWriteMsr, @function

+.proc   AsmWriteMsr

+.regstk 2, 0, 0, 0

+

+AsmWriteMsr::

+//

+// The follow 16 bytes stand for the bundle of 

+//  mov             msr[in0] = in1

+//  mov             r8 = in1;;

+// since MSFT tool chain does not support mov msr[]= instruction

+//

+  data1 0x0D

+  data1 0x00

+  data1 0x84

+  data1 0x40

+  data1 0x06

+  data1 0x04

+  data1 0x00

+  data1 0x00

+  data1 0x00

+  data1 0x02

+  data1 0x00

+  data1 0x00

+  data1 0x01

+  data1 0x08

+  data1 0x01

+  data1 0x84

+  srlz.d;;

+  br.ret.sptk     b0;;

+.endp   AsmWriteMsr

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessPmr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessPmr.s
new file mode 100644
index 0000000..cc75b4f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessPmr.s
@@ -0,0 +1,124 @@
+/// @file

+///  IPF specific Performance Monitor Configuration/Data Registers accessing functions

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name: AccessPmr.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadPmc

+//

+// This routine is used to Reads the current value of Performance Monitor Configuration Register (PMC).

+//

+// Arguments :

+//

+// On Entry : The 8-bit PMC index.

+//

+// Return Value: The current value of PMC by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadPmc, @function

+.proc   AsmReadPmc

+.regstk 1, 0, 0, 0

+

+AsmReadPmc::

+        srlz.i;;

+        srlz.d;;

+        mov             r8 = pmc[in0];;

+        br.ret.dpnt     b0;;

+.endp   AsmReadPmc

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWritePmc

+//

+// This routine is used to write the current value to a Performance Monitor Configuration Register (PMC).

+//

+// Arguments :

+//

+// On Entry : The 8-bit PMC index.

+//            The value should be written to PMC

+//

+// Return Value: The value written to PMC.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWritePmc, @function

+.proc   AsmWritePmc

+.regstk 2, 0, 0, 0

+

+AsmWritePmc::

+        mov             pmc[in0] = in1

+        mov             r8 = in1;;

+        srlz.i;;

+        srlz.d;;

+        br.ret.dpnt     b0;;

+.endp   AsmWritePmc

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadPmd

+//

+// This routine is used to Reads the current value of Performance Monitor Data Register (PMD).

+//

+// Arguments :

+//

+// On Entry : The 8-bit PMD index.

+//

+// Return Value: The current value of PMD by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadPmd, @function

+.proc   AsmReadPmd

+.regstk 1, 0, 0, 0

+

+AsmReadPmd::

+        srlz.i;;

+        srlz.d;;

+        mov             r8 = pmd[in0];;

+        br.ret.dpnt     b0;;

+.endp   AsmReadPmd

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWritePmd

+//

+// This routine is used to write the current value to Performance Monitor Data Register (PMD).

+//

+// Arguments :

+//

+// On Entry : The 8-bit PMD index.

+//            The value should be written to PMD

+//

+// Return Value: The value written to PMD.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWritePmd, @function

+.proc   AsmWritePmd

+.regstk 2, 0, 0, 0

+

+AsmWritePmd::

+        mov             pmd[in0] = in1

+        mov             r8 = in1;;

+        srlz.i;;

+        srlz.d;;

+        br.ret.dpnt     b0;;

+.endp   AsmWritePmd

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessPsr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessPsr.s
new file mode 100644
index 0000000..b183ba0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AccessPsr.s
@@ -0,0 +1,111 @@
+/// @file

+///  IPF specific Processor Status Register accessing functions

+///

+/// 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.

+///

+/// Module Name: AccessPsr.s

+///

+///

+

+#define CpuModeMask           0x0000001008020000

+

+#define CpuInVirtualMode             0x1

+#define CpuInPhysicalMode            0x0

+#define CpuInMixMode                 (0x0 - 0x1)

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadPsr

+//

+// This routine is used to read the current value of Processor Status Register (PSR).

+//

+// Arguments :

+//

+// On Entry :

+//

+// Return Value: The current PSR value.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadPsr, @function

+.proc   AsmReadPsr

+

+AsmReadPsr::

+        mov             r8 = psr;;

+        br.ret.dpnt     b0;;

+.endp   AsmReadPsr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmWritePsr

+//

+// This routine is used to write the value of Processor Status Register (PSR).

+//

+// Arguments :

+//

+// On Entry : The value need to be written.

+//

+// Return Value: The value have been written.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmWritePsr, @function

+.proc   AsmWritePsr

+.regstk 1, 0, 0, 0

+

+AsmWritePsr::

+        mov             psr.l = in0

+        mov             r8 = in0;;

+        srlz.d;;

+        srlz.i;;

+        br.ret.dpnt     b0;;

+.endp   AsmWritePsr

+

+//---------------------------------------------------------------------------------

+//++

+// AsmCpuVirtual

+//

+// This routine is used to determines if the CPU is currently executing

+// in virtual, physical, or mixed mode.

+//

+// 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.

+//

+// Arguments:

+//

+// On Entry: None

+//

+// Return Value: The CPU mode flag

+//               return  1  The CPU is in virtual mode.

+//               return  0  The CPU is in physical mode.

+//               return -1  The CPU is in mixed mode.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmCpuVirtual, @function

+.proc   AsmCpuVirtual

+

+AsmCpuVirtual::

+        mov            r29 = psr

+        movl           r30 = CpuModeMask;;

+        and            r28 = r30, r29;;

+        cmp.eq         p6, p7 = r30, r28;;

+(p6)    mov            r8 = CpuInVirtualMode;;

+(p6)    br.ret.dpnt    b0;;

+(p7)    cmp.eq         p6, p7 = 0x0, r28;;

+(p6)    mov            r8 = CpuInPhysicalMode;;

+(p7)    mov            r8 = CpuInMixMode;;

+        br.ret.dpnt    b0;;

+.endp   AsmCpuVirtual

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Asm.h b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Asm.h
new file mode 100644
index 0000000..5434573
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Asm.h
@@ -0,0 +1,27 @@
+/** @file 

+

+    This module contains generic macros for an assembly writer.

+

+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 _ASM_H_

+#define _ASM_H_

+

+#define TRUE  1

+#define FALSE 0

+#define PROCEDURE_ENTRY(name)   .##text;            \

+  .##type name, @function; \

+  .##proc name; \

+  name::

+

+#define PROCEDURE_EXIT(name)  .##endp name

+

+#endif // _ASM_H

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AsmCpuMisc.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AsmCpuMisc.s
new file mode 100644
index 0000000..91075bf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AsmCpuMisc.s
@@ -0,0 +1,79 @@
+/// @file

+///   Contains an implementation of CallPalProcStacked on Itanium-based

+///   architecture.

+///

+/// Copyright (c) 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.

+///

+/// Module Name:  AsmCpuMisc.s

+///

+///

+

+

+.text

+.proc CpuBreakpoint

+.type CpuBreakpoint, @function

+

+CpuBreakpoint::

+        break.i 0;;

+        br.ret.dpnt    b0;;

+

+.endp CpuBreakpoint

+

+.proc MemoryFence

+.type MemoryFence, @function

+

+MemoryFence::

+        mf;;    // memory access ordering

+

+        // do we need the mf.a also here?

+        mf.a    // wait for any IO to complete?

+        

+        // not sure if we need serialization here, just put it, in case...

+        

+        srlz.d;;

+        srlz.i;;

+        

+        br.ret.dpnt    b0;;

+.endp MemoryFence

+

+.proc DisableInterrupts

+.type DisableInterrupts, @function

+

+DisableInterrupts::

+         rsm      0x4000

+         srlz.d;;

+         br.ret.dpnt    b0;;

+

+.endp DisableInterrupts

+

+.proc EnableInterrupts

+.type EnableInterrupts, @function

+

+EnableInterrupts::

+      ssm     0x4000

+      srlz.d;;

+      br.ret.dpnt    b0;;

+

+.endp EnableInterrupts

+

+.proc EnableDisableInterrupts

+.type EnableDisableInterrupts, @function

+

+EnableDisableInterrupts::

+         ssm      0x4000

+         srlz.d;;

+         srlz.i;;

+         rsm      0x4000

+         srlz.d;;

+

+         br.ret.dpnt    b0;;

+

+.endp EnableDisableInterrupts

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AsmPalCall.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AsmPalCall.s
new file mode 100644
index 0000000..7fd40aa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/AsmPalCall.s
@@ -0,0 +1,158 @@
+/// @file

+///   Contains an implementation of CallPalProcStacked on Itanium-based

+///   architecture.

+///

+/// 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.

+///

+/// Module Name:  AsmPalCall.s

+///

+///

+

+

+//-----------------------------------------------------------------------------

+//++

+//  AsmPalCall

+//

+//  Makes a PAL procedure call.

+//  This is 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 IPF.

+//

+//  On Entry :

+//           in0:  PAL_PROC entrypoint

+//           in1-in4 : PAL_PROC arguments

+//

+//  Return Value:

+//

+//  As per stacked calling conventions.

+//

+//--

+//---------------------------------------------------------------------------

+

+//

+// PAL function calls

+//

+#define PAL_MC_CLEAR_LOG               0x0015

+#define PAL_MC_DYNAMIC_STATE           0x0018

+#define PAL_MC_ERROR_INFO              0x0019

+#define PAL_MC_RESUME                  0x001a

+

+

+.text

+.proc AsmPalCall

+.type AsmPalCall, @function

+

+AsmPalCall::

+         alloc          loc1 = ar.pfs,5,8,4,0

+         mov            loc0 = b0

+         mov            loc3 = b5

+         mov            loc4 = r2

+         mov            loc7 = r1

+         mov            r2 = psr;;

+         mov            r28 = in1

+         mov            loc5 = r2;;

+

+         movl           loc6 = 0x100;;

+         cmp.ge         p6,p7 = r28,loc6;;

+

+(p6)     movl           loc6 = 0x1FF;;

+(p7)     br.dpnt.few PalCallStatic;;                  // 0 ~ 255 make a static Pal Call

+(p6)     cmp.le         p6,p7 = r28,loc6;;

+(p6)     br.dpnt.few PalCallStacked;;                 // 256 ~ 511 make a stacked Pal Call

+(p7)     movl           loc6 = 0x300;;

+(p7)     cmp.ge         p6,p7 = r28,loc6;;

+(p7)     br.dpnt.few PalCallStatic;;                  // 512 ~ 767 make a static Pal Call

+(p6)     movl           loc6 = 0x3FF;;

+(p6)     cmp.le         p6,p7 = r28,loc6;;

+(p6)     br.dpnt.few PalCallStacked;;                 // 768 ~ 1023 make a stacked Pal Call

+

+(p7)     mov            r8 = 0xFFFFFFFFFFFFFFFF;;     // > 1024 return invalid

+(p7)     br.dpnt.few    ComeBackFromPALCall;;

+

+PalCallStatic:

+         movl           loc6 = PAL_MC_CLEAR_LOG;;

+         cmp.eq         p6,p7 = r28,loc6;;

+

+(p7)     movl           loc6 = PAL_MC_DYNAMIC_STATE;;

+(p7)     cmp.eq         p6,p7 = r28,loc6;;

+

+(p7)     movl           loc6 = PAL_MC_ERROR_INFO;;

+(p7)     cmp.eq         p6,p7 = r28,loc6;;

+

+(p7)     movl           loc6 = PAL_MC_RESUME;;

+(p7)     cmp.eq         p6,p7 = r28,loc6 ;;

+

+         mov            loc6 = 0x1;;

+(p7)     dep            r2 = loc6,r2,13,1;;           // psr.ic = 1

+

+// p6 will be true, if it is one of the MCHK calls. There has been lots of debate

+// on psr.ic for these values. For now, do not do any thing to psr.ic

+

+         dep            r2 = r0,r2,14,1;;             // psr.i = 0

+

+         mov            psr.l = r2

+         srlz.d                                       // Needs data serailization.

+         srlz.i                                       // Needs instruction serailization.

+

+StaticGetPALLocalIP:

+         mov            loc2 = ip;;

+         add            loc2 = ComeBackFromPALCall - StaticGetPALLocalIP,loc2;;

+         mov            b0 = loc2                     // return address after Pal call

+

+         mov            r29 = in2

+         mov            r30 = in3

+         mov            r31 = in4

+         mov            b5 = in0;;                    // get the PalProcEntrypt from input

+         br.sptk        b5;;                          // Take the plunge.

+

+PalCallStacked:

+         dep            r2 = r0,r2,14,1;;             // psr.i = 0

+         mov            psr.l = r2;;

+         srlz.d                                       // Needs data serailization.

+         srlz.i                                       // Needs instruction serailization.

+

+StackedGetPALLocalIP:

+         mov            out0 = in1

+         mov            out1 = in2

+         mov            out2 = in3

+         mov            out3 = in4

+         mov            b5 =  in0 ;;                  // get the PalProcEntrypt from input

+         br.call.dpnt   b0 = b5 ;;                    // Take the plunge.

+

+ComeBackFromPALCall:

+         mov            psr.l = loc5 ;;

+         srlz.d                                       // Needs data serailization.

+         srlz.i                                       // Needs instruction serailization.

+

+         mov            b5 = loc3

+         mov            r2 = loc4

+         mov            r1 = loc7

+

+         mov            b0 = loc0

+         mov            ar.pfs = loc1;;

+         br.ret.dpnt    b0;;

+

+.endp AsmPalCall

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c
new file mode 100644
index 0000000..302974b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpoint.c
@@ -0,0 +1,96 @@
+/** @file

+  Base Library CPU functions for Itanium

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  __break (0);

+}

+

+/**

+  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

+  )

+{

+  __mfa ();

+}

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{

+  _disable ();

+}

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  _enable ();

+}

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  )

+{

+  EnableInterrupts ();

+  DisableInterrupts ();

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpointMsc.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpointMsc.c
new file mode 100644
index 0000000..89b0acf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuBreakpointMsc.c
@@ -0,0 +1,102 @@
+/** @file

+  Base Library CPU functions for Itanium

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+#pragma intrinsic (_enable)

+#pragma intrinsic (_disable)

+#pragma intrinsic (__break)

+#pragma intrinsic (__mfa)

+

+/**

+  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

+  )

+{

+  __break (0);

+}

+

+/**

+  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

+  )

+{

+  __mfa ();

+}

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{

+  _disable ();

+}

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  _enable ();

+}

+

+/**

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+  Enables CPU interrupts for the smallest window required to capture any

+  pending interrupts.

+

+**/

+VOID

+EFIAPI

+EnableDisableInterrupts (

+  VOID

+  )

+{

+  EnableInterrupts ();

+  DisableInterrupts ();

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuPause.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuPause.s
new file mode 100644
index 0000000..d881aaa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/CpuPause.s
@@ -0,0 +1,25 @@
+/// @file

+///   CpuPause() function for Itanium-based architecture.

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name:  CpuPause.s

+///

+///

+

+.auto

+.text

+

+.proc   CpuPause

+.type   CpuPause, @function

+CpuPause::

+        hint.i              @pause

+        br.ret.sptk.many    b0

+.endp

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ExecFc.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ExecFc.s
new file mode 100644
index 0000000..a7c4e30
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ExecFc.s
@@ -0,0 +1,66 @@
+/// @file

+///  IPF specific AsmFc() and AsmFci () functions

+///

+/// 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.

+///

+/// Module Name: ExecFc.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmFc

+//

+// This routine is used to execute a FC instruction on the specific address.

+//

+// Arguments :

+//

+// On Entry :  The specific address need to execute FC instruction.

+//

+// Return Value: The specific address have been execute FC instruction.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmFc, @function

+.proc   AsmFc

+.regstk 1, 0, 0, 0

+

+AsmFc::

+        fc              in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmFc

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmFci

+//

+// This routine is used to execute a FC.i instruction on the specific address.

+//

+// Arguments :

+//

+// On Entry :  The specific address need to execute FC.i instruction.

+//

+// Return Value: The specific address have been execute FC.i instruction.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmFci, @function

+.proc   AsmFci

+.regstk 1, 0, 0, 0

+

+AsmFci::

+        fc.i            in0

+        mov             r8 = in0;;

+        br.ret.dpnt     b0;;

+.endp   AsmFci

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.c
new file mode 100644
index 0000000..5286beb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.c
@@ -0,0 +1,51 @@
+/** @file

+  AsmFlushCacheRange() function for IPF.

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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 IPF.

+

+  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

+  )

+{

+  ASSERT (Length <= MAX_ADDRESS - (UINTN)Address + 1);

+  return InternalFlushCacheRange (Address, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/GetInterruptState.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/GetInterruptState.s
new file mode 100644
index 0000000..eed6794
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/GetInterruptState.s
@@ -0,0 +1,27 @@
+/// @file

+///   Retrieve of the interrupt state of the running processor for the Itanium

+///   architecture.

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name:  GetInterruptState.s

+///

+///

+

+.auto

+.text

+

+.proc   GetInterruptState

+.type   GetInterruptState, @function

+GetInterruptState::

+        mov                 r8  = psr

+        extr.u              r8  = r8, 14, 1

+        br.ret.sptk.many    b0

+.endp   GetInterruptState

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Ia64gen.h b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Ia64gen.h
new file mode 100644
index 0000000..3439f9e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Ia64gen.h
@@ -0,0 +1,205 @@
+/** @file 

+

+    Register Definition for IPF.

+ 

+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 _IA64GEN_H_

+#define _IA64GEN_H_

+

+#define TT_UNAT           0

+#define C_PSR             0

+#define J_UNAT            0

+#define T_TYPE            0

+#define T_IPSR            0x8

+#define T_ISR             0x10

+#define T_IIP             0x18

+#define T_IFA             0x20

+#define T_IIPA            0x28

+#define T_IFS             0x30

+#define T_IIM             0x38

+#define T_RSC             0x40

+#define T_BSP             0x48

+#define T_BSPSTORE        0x50

+#define T_RNAT            0x58

+#define T_PFS             0x60

+#define T_KBSPSTORE       0x68

+#define T_UNAT            0x70

+#define T_CCV             0x78

+#define T_DCR             0x80

+#define T_PREDS           0x88

+#define T_NATS            0x90

+#define T_R1              0x98

+#define T_GP              0x98

+#define T_R2              0xa0

+#define T_R3              0xa8

+#define T_R4              0xb0

+#define T_R5              0xb8

+#define T_R6              0xc0

+#define T_R7              0xc8

+#define T_R8              0xd0

+#define T_R9              0xd8

+#define T_R10             0xe0

+#define T_R11             0xe8

+#define T_R12             0xf0

+#define T_SP              0xf0

+#define T_R13             0xf8

+#define T_R14             0x100

+#define T_R15             0x108

+#define T_R16             0x110

+#define T_R17             0x118

+#define T_R18             0x120

+#define T_R19             0x128

+#define T_R20             0x130

+#define T_R21             0x138

+#define T_R22             0x140

+#define T_R23             0x148

+#define T_R24             0x150

+#define T_R25             0x158

+#define T_R26             0x160

+#define T_R27             0x168

+#define T_R28             0x170

+#define T_R29             0x178

+#define T_R30             0x180

+#define T_R31             0x188

+#define T_F2              0x1f0

+#define T_F3              0x200

+#define T_F4              0x210

+#define T_F5              0x220

+#define T_F6              0x230

+#define T_F7              0x240

+#define T_F8              0x250

+#define T_F9              0x260

+#define T_F10             0x270

+#define T_F11             0x280

+#define T_F12             0x290

+#define T_F13             0x2a0

+#define T_F14             0x2b0

+#define T_F15             0x2c0

+#define T_F16             0x2d0

+#define T_F17             0x2e0

+#define T_F18             0x2f0

+#define T_F19             0x300

+#define T_F20             0x310

+#define T_F21             0x320

+#define T_F22             0x330

+#define T_F23             0x340

+#define T_F24             0x350

+#define T_F25             0x360

+#define T_F26             0x370

+#define T_F27             0x380

+#define T_F28             0x390

+#define T_F29             0x3a0

+#define T_F30             0x3b0

+#define T_F31             0x3c0

+#define T_FPSR            0x1e0

+#define T_B0              0x190

+#define T_B1              0x198

+#define T_B2              0x1a0

+#define T_B3              0x1a8

+#define T_B4              0x1b0

+#define T_B5              0x1b8

+#define T_B6              0x1c0

+#define T_B7              0x1c8

+#define T_EC              0x1d0

+#define T_LC              0x1d8

+#define J_NATS            0x8

+#define J_PFS             0x10

+#define J_BSP             0x18

+#define J_RNAT            0x20

+#define J_PREDS           0x28

+#define J_LC              0x30

+#define J_R4              0x38

+#define J_R5              0x40

+#define J_R6              0x48

+#define J_R7              0x50

+#define J_SP              0x58

+#define J_F2              0x60

+#define J_F3              0x70

+#define J_F4              0x80

+#define J_F5              0x90

+#define J_F16             0xa0

+#define J_F17             0xb0

+#define J_F18             0xc0

+#define J_F19             0xd0

+#define J_F20             0xe0

+#define J_F21             0xf0

+#define J_F22             0x100

+#define J_F23             0x110

+#define J_F24             0x120

+#define J_F25             0x130

+#define J_F26             0x140

+#define J_F27             0x150

+#define J_F28             0x160

+#define J_F29             0x170

+#define J_F30             0x180

+#define J_F31             0x190

+#define J_FPSR            0x1a0

+#define J_B0              0x1a8

+#define J_B1              0x1b0

+#define J_B2              0x1b8

+#define J_B3              0x1c0

+#define J_B4              0x1c8

+#define J_B5              0x1d0

+#define TRAP_FRAME_LENGTH 0x3d0

+#define C_UNAT            0x28

+#define C_NATS            0x30

+#define C_PFS             0x8

+#define C_BSPSTORE        0x10

+#define C_RNAT            0x18

+#define C_RSC             0x20

+#define C_PREDS           0x38

+#define C_LC              0x40

+#define C_DCR             0x48

+#define C_R1              0x50

+#define C_GP              0x50

+#define C_R4              0x58

+#define C_R5              0x60

+#define C_R6              0x68

+#define C_R7              0x70

+#define C_SP              0x78

+#define C_R13             0x80

+#define C_F2              0x90

+#define C_F3              0xa0

+#define C_F4              0xb0

+#define C_F5              0xc0

+#define C_F16             0xd0

+#define C_F17             0xe0

+#define C_F18             0xf0

+#define C_F19             0x100

+#define C_F20             0x110

+#define C_F21             0x120

+#define C_F22             0x130

+#define C_F23             0x140

+#define C_F24             0x150

+#define C_F25             0x160

+#define C_F26             0x170

+#define C_F27             0x180

+#define C_F28             0x190

+#define C_F29             0x1a0

+#define C_F30             0x1b0

+#define C_F31             0x1c0

+#define C_FPSR            0x1d0

+#define C_B0              0x1d8

+#define C_B1              0x1e0

+#define C_B2              0x1e8

+#define C_B3              0x1f0

+#define C_B4              0x1f8

+#define C_B5              0x200

+#define TT_R2             0x8

+#define TT_R3             0x10

+#define TT_R8             0x18

+#define TT_R9             0x20

+#define TT_R10            0x28

+#define TT_R11            0x30

+#define TT_R14            0x38

+

+#endif _IA64GEN_H

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/InternalFlushCacheRange.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/InternalFlushCacheRange.s
new file mode 100644
index 0000000..7a0b747
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/InternalFlushCacheRange.s
@@ -0,0 +1,94 @@
+//++

+// Copyright (c) 2006 - 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.             

+// 

+//  Module Name:

+//    InternalFlushCacheRange.s 

+//

+//  Abstract:

+//    Assemble routine to flush cache lines 

+//

+// Revision History:

+//

+//--

+.file  "IpfCpuCache.s"

+

+#include <IpfMacro.i>

+

+//

+//  Internal worker function to invalidate a range of instruction cache lines

+//  in the cache coherency domain of the calling CPU.

+//

+//  Internal worker function to invalidate the instruction cache lines specified

+//  by Address and Length. If Address is not aligned on a cache line boundary,

+//  then entire instruction cache line containing Address is invalidated. If

+//  Address + Length is not aligned on a cache line boundary, then the entire

+//  instruction cache line containing Address + Length -1 is invalidated. This

+//  function may choose to invalidate the entire instruction cache if that is more

+//  efficient than invalidating the specified range. If Length is 0, the no instruction

+//  cache lines are invalidated. Address is returned.

+//  This function is only available on IPF.

+//

+//  @param  Address The base address of the instruction cache 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

+//  InternalFlushCacheRange (

+//    IN      VOID                      *Address,

+//    IN      UINTN                     Length

+//    );

+//

+PROCEDURE_ENTRY (InternalFlushCacheRange)

+

+      NESTED_SETUP (5,8,0,0)

+            

+      mov         loc2 = ar.lc

+      

+      mov         loc3 = in0                  // Start address.

+      mov         loc4 = in1;;                // Length in bytes.

+      

+      cmp.eq  p6,p7 = loc4, r0;;               // If Length is zero then don't flush any cache

+      (p6)  br.spnt.many DoneFlushingC;;         

+      

+      add         loc4 = loc4,loc3 

+      mov         loc5 = 1;;

+      sub         loc4 = loc4, loc5 ;; // the End address to flush

+                                         

+      dep         loc3 = r0,loc3,0,5          

+      dep         loc4 = r0,loc4,0,5;;         

+      shr         loc3 = loc3,5             

+      shr         loc4 = loc4,5;;    // 32 byte cache line

+      

+      sub         loc4 = loc4,loc3;; // total flush count, It should be add 1 but 

+                                     // the br.cloop will first execute one time 

+      mov         loc3 = in0                  

+      mov         loc5 = 32      

+      mov         ar.lc = loc4;;

+

+StillFlushingC:

+      fc          loc3;; 

+      sync.i;;

+      srlz.i;;

+      add         loc3 = loc5,loc3;;

+      br.cloop.sptk.few StillFlushingC;;

+

+DoneFlushingC:      

+      mov         ar.lc = loc2     

+      mov          r8   = in0       // return *Address

+      NESTED_RETURN

+

+PROCEDURE_EXIT (InternalFlushCacheRange)

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/InternalSwitchStack.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/InternalSwitchStack.c
new file mode 100644
index 0000000..35a0905
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/InternalSwitchStack.c
@@ -0,0 +1,64 @@
+/** @file

+  SwitchStack() function for IPF.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+  Marker will be ignored on IA-32, x64, and EBC.

+  IPF CPUs 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  Marker      VA_LIST marker for the variable argument list.

+

+**/

+VOID

+EFIAPI

+InternalSwitchStack (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,   OPTIONAL

+  IN      VOID                      *Context2,   OPTIONAL

+  IN      VOID                      *NewStack,

+  IN      VA_LIST                   Marker

+  )

+{

+  VOID                      *NewBsp;

+

+  //

+  // Get new backing store pointer from variable list

+  //

+  NewBsp   = VA_ARG (Marker, VOID *);

+

+  //

+  // New backing store pointer should be aligned with CPU_STACK_ALIGNMENT

+  //

+  ASSERT (((UINTN)NewBsp & (CPU_STACK_ALIGNMENT - 1)) == 0);

+

+  AsmSwitchStackAndBackingStore (EntryPoint, Context1, Context2, NewStack, NewBsp);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/LongJmp.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/LongJmp.s
new file mode 100644
index 0000000..8b5eb64
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/LongJmp.s
@@ -0,0 +1,121 @@
+/// @file

+///  Contains an implementation of longjmp for the Itanium-based architecture.

+///

+/// 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.

+///

+/// Module Name: longjmp.s

+///

+///

+

+.auto

+.text

+

+.proc   InternalLongJump

+.type   InternalLongJump, @function

+.regstk 2, 0, 0, 0

+InternalLongJump::

+        add                 r10 = 0x10*20 + 8*14, in0

+        movl                r2  = ~((((1 << 14) - 1) << 16) | 3)

+

+        ld8.nt1             r14 = [r10], -8*2       // BSP, skip PFS

+        mov                 r15 = ar.bspstore       // BSPSTORE

+

+        ld8.nt1             r17 = [r10], -8         // UNAT after spill

+        mov                 r16 = ar.rsc            // RSC

+        cmp.leu             p6  = r14, r15

+

+        ld8.nt1             r18 = [r10], -8         // UNAT

+        ld8.nt1             r25 = [r10], -8         // b5

+        and                 r2  = r16, r2

+

+        ldf.fill.nt1        f2  = [in0], 0x10

+        ld8.nt1             r24 = [r10], -8         // b4

+        mov                 b5  = r25

+

+        mov                 ar.rsc = r2

+        ld8.nt1             r23 = [r10], -8         // b3

+        mov                 b4  = r24

+

+        ldf.fill.nt1        f3  = [in0], 0x10

+        mov                 ar.unat = r17

+(p6)    br.spnt.many        _skip_flushrs

+

+        flushrs

+        mov                 r15 = ar.bsp            // New BSPSTORE

+

+_skip_flushrs:

+        mov                 r31 = ar.rnat           // RNAT

+        loadrs

+

+        ldf.fill.nt1        f4  = [in0], 0x10

+        ld8.nt1             r22 = [r10], -8

+        dep                 r2  = -1, r14, 3, 6

+

+        ldf.fill.nt1        f5  = [in0], 0x10

+        ld8.nt1             r21 = [r10], -8

+        cmp.ltu             p6  = r2, r15

+

+        ld8.nt1             r20 = [r10], -0x10      // skip sp

+(p6)    ld8.nta             r31 = [r2]

+        mov                 b3  = r23

+

+        ldf.fill.nt1        f16 = [in0], 0x10

+        ld8.fill.nt1        r7  = [r10], -8

+        mov                 b2  = r22

+

+        ldf.fill.nt1        f17 = [in0], 0x10

+        ld8.fill.nt1        r6  = [r10], -8

+        mov                 b1  = r21

+

+        ldf.fill.nt1        f18 = [in0], 0x10

+        ld8.fill.nt1        r5  = [r10], -8

+        mov                 b0  = r20

+

+        ldf.fill.nt1        f19 = [in0], 0x10

+        ld8.fill.nt1        r4  = [r10], 8*13

+

+        ldf.fill.nt1        f20 = [in0], 0x10

+        ld8.nt1             r19 = [r10], 0x10       // PFS

+

+        ldf.fill.nt1        f21 = [in0], 0x10

+        ld8.nt1             r26 = [r10], 8          // Predicate

+        mov                 ar.pfs = r19

+

+        ldf.fill.nt1        f22 = [in0], 0x10

+        ld8.nt1             r27 = [r10], 8          // LC

+        mov                 pr  = r26, -1

+

+        ldf.fill.nt1        f23 = [in0], 0x10

+        ld8.nt1             r28 = [r10], -17*8 - 0x10

+        mov                 ar.lc = r27

+

+        ldf.fill.nt1        f24 = [in0], 0x10

+        ldf.fill.nt1        f25 = [in0], 0x10

+        mov                 r8  = in1

+

+        ldf.fill.nt1        f26 = [in0], 0x10

+        ldf.fill.nt1        f31 = [r10], -0x10

+

+        ldf.fill.nt1        f27 = [in0], 0x10

+        ldf.fill.nt1        f30 = [r10], -0x10

+

+        ldf.fill.nt1        f28 = [in0]

+        ldf.fill.nt1        f29 = [r10], 0x10*3 + 8*4

+

+        ld8.fill.nt1        sp  = [r10]

+        mov                 ar.unat = r18

+

+        mov                 ar.bspstore = r14

+        mov                 ar.rnat = r31

+

+        invala

+        mov                 ar.rsc = r16

+        br.ret.sptk         b0

+.endp

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadAr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadAr.s
new file mode 100644
index 0000000..36efe8b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadAr.s
@@ -0,0 +1,109 @@
+/// @file

+///  IPF specific application register reading functions

+///

+/// Copyright (c) 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.

+///

+///

+///

+

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadApplicationRegister

+//

+// Reads a 64-bit application register.

+//

+// Reads and returns the application register specified by Index.

+// If Index is invalid then 0xFFFFFFFFFFFFFFFF is returned.  This function is only available on IPF.

+//

+// Arguments :

+//

+// On Entry : The index of the application register to read.

+//

+// Return Value: The application register specified by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadApplicationRegister, @function

+.proc   AsmReadApplicationRegister

+.regstk 1, 0, 0, 0

+

+AsmReadApplicationRegister::

+  //

+  // ARs are defined in the ranges 0-44 and 64-66 (with some holes).

+  // Compact this list by subtracting 16 from the top range.

+  // 0-44, 64-66 -> 0-44, 48-50

+  //

+  mov  r15=2

+  mov  r14=pr                   // save predicates

+  cmp.leu  p6,p7=64,in0         // p6 = AR# >= 64

+  ;;

+  (p7)  cmp.leu  p7,p0=48,in0   // p7 = 32 <= AR# < 64

+  (p6)  add  in0=-16,in0        // if (AR >= 64) AR# -= 16

+  ;;

+  (p7)  mov  r15=0              // if bad range (48-63)

+  ;;

+  mov  ret0=-1                  // in case of illegal AR #

+  shl  r15=r15,in0              // r15 = 0x2 << AR#

+  ;;

+  mov  pr=r15,-1

+  ;;

+  //

+  // At this point the predicates contain a bit field of the

+  // AR desired.  (The bit is the AR+1, since pr0 is always 1.)

+  //

+  .pred.rel "mutex",p1,p2,p3,p4,p5,p6,p7,p8,p17,p18,p19,p20,p22,p25,\

+        p26,p27,p28,p29,p30,p31,p33,p37,p41,p45,p49,p50,p51

+  (p1)  mov  ret0=ar.k0         // ar0

+  (p2)  mov  ret0=ar.k1         // ar1

+  (p3)  mov  ret0=ar.k2         // ar2

+  (p4)  mov  ret0=ar.k3         // ar3

+  (p5)  mov  ret0=ar.k4         // ar4

+  (p6)  mov  ret0=ar.k5         // ar5

+  (p7)  mov  ret0=ar.k6         // ar6

+  (p8)  mov  ret0=ar.k7         // ar7

+

+  (p17)  mov  ret0=ar.rsc       // ar16

+  (p18)  mov  ret0=ar.bsp       // ar17

+  (p19)  mov  ret0=ar.bspstore  // ar18

+  (p20)  mov  ret0=ar.rnat      // ar19

+

+  (p22)  mov  ret0=ar.fcr       // ar21 [iA32]

+

+  (p25)  mov  ret0=ar.eflag     // ar24 [iA32]

+  (p26)  mov  ret0=ar.csd       // ar25 [iA32]

+  (p27)  mov  ret0=ar.ssd       // ar26 [iA32]

+  (p28)  mov  ret0=ar.cflg      // ar27 [iA32]

+  (p29)  mov  ret0=ar.fsr       // ar28 [iA32]

+  (p30)  mov  ret0=ar.fir       // ar29 [iA32]

+  (p31)  mov  ret0=ar.fdr       // ar30 [iA32]

+

+  (p33)  mov  ret0=ar.ccv       // ar32

+

+  (p37)  mov  ret0=ar.unat      // ar36

+

+  (p41)  mov  ret0=ar.fpsr      // ar40

+

+  (p45)  mov  ret0=ar.itc       // ar44

+

+  //

+  // This is the translated (-16) range.

+  //

+  (p49)  mov  ret0=ar.pfs       // ar64

+  (p50)  mov  ret0=ar.lc        // ar65

+  (p51)  mov  ret0=ar.ec        // ar66

+

+  // Restore predicates and return.

+

+  mov  pr=r14,-1

+  br.ret.sptk  b0

+  .endp

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadCpuid.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadCpuid.s
new file mode 100644
index 0000000..3102384
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadCpuid.s
@@ -0,0 +1,40 @@
+/// @file

+///  IPF specific AsmReadCpuid()function

+///

+/// Copyright (c) 2006, 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.

+///

+/// Module Name: ReadCpuid.s

+///

+///

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadCpuid

+//

+// This routine is used to Reads the current value of Processor Identifier Register (CPUID).

+//

+// Arguments :

+//

+// On Entry : The 8-bit Processor Identifier Register index to read.

+//

+// Return Value: The current value of Processor Identifier Register specified by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadCpuid, @function

+.proc   AsmReadCpuid

+.regstk 1, 0, 0, 0

+

+AsmReadCpuid::

+        mov             r8 = cpuid[in0];;

+        br.ret.dpnt     b0;;

+.endp    AsmReadCpuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadCr.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadCr.s
new file mode 100644
index 0000000..ef52964
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/ReadCr.s
@@ -0,0 +1,102 @@
+/// @file

+///  IPF specific control register reading functions

+///

+/// Copyright (c) 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.

+///

+///

+///

+

+

+

+//---------------------------------------------------------------------------------

+//++

+// AsmReadControlRegister

+//

+// Reads a 64-bit control register.

+//

+// Reads and returns the control register specified by Index.

+// If Index is invalid then 0xFFFFFFFFFFFFFFFF is returned.  This function is only available on IPF.

+//

+// Arguments :

+//

+// On Entry : The index of the control register to read.

+//

+// Return Value: The control register specified by Index.

+//

+//--

+//----------------------------------------------------------------------------------

+.text

+.type   AsmReadControlRegister, @function

+.proc   AsmReadControlRegister

+.regstk 1, 0, 0, 0

+

+AsmReadControlRegister::

+  //

+  // CRs are defined in the ranges 0-25 and 64-81 (with some holes).

+  // Compact this list by subtracting 32 from the top range.

+  // 0-25, 64-81 -> 0-25, 32-49

+  //

+  mov  r15=2

+  mov  r14=pr                    // save predicates

+  cmp.leu  p6,p7=64,in0          // p6 = CR# >= 64

+  ;;

+  (p7)  cmp.leu  p7,p0=32,in0    // p7 = 32 <= CR# < 64

+  (p6)  add  in0=-32,in0         // if (CR >= 64) CR# -= 32

+  ;;

+  (p7)  mov  r15=0               // if bad range (32-63)

+  ;;

+  mov  ret0=-1                   // in case of illegal CR #

+  shl  r15=r15,in0               // r15 = 0x2 << CR#

+  ;;

+  mov  pr=r15,-1

+  ;;

+

+  //

+  // At this point the predicates contain a bit field of the

+  // CR desired.  (The bit is the CR+1, since pr0 is always 1.)

+  //

+  .pred.rel "mutex",p1,p2,p3,p9,p17,p18,p20,p21,p22,p23,p24,p25,p26,\

+    p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p49,p50

+  (p1)  mov  ret0=cr.dcr        // cr0

+  (p2)  mov  ret0=cr.itm        // cr1

+  (p3)  mov  ret0=cr.iva        // cr2

+  (p9)  mov  ret0=cr.pta        // cr8

+  (p17)  mov  ret0=cr.ipsr      // cr16

+  (p18)  mov  ret0=cr.isr       // cr17

+  (p20)  mov  ret0=cr.iip       // cr19

+  (p21)  mov  ret0=cr.ifa       // cr20

+  (p22)  mov  ret0=cr.itir      // cr21

+  (p23)  mov  ret0=cr.iipa      // cr22

+  (p24)  mov  ret0=cr.ifs       // cr23

+  (p25)  mov  ret0=cr.iim       // cr24

+  (p26)  mov  ret0=cr.iha       // cr25

+

+  // This is the translated (-32) range.

+

+  (p33)  mov  ret0=cr.lid       // cr64

+  (p34)  mov  ret0=cr.ivr       // cr65

+  (p35)  mov  ret0=cr.tpr       // cr66

+  (p36)  mov  ret0=cr.eoi       // cr67

+  (p37)  mov  ret0=cr.irr0      // cr68

+  (p38)  mov  ret0=cr.irr1      // cr69

+  (p39)  mov  ret0=cr.irr2      // cr70

+  (p40)  mov  ret0=cr.irr3      // cr71

+  (p41)  mov  ret0=cr.itv       // cr72

+  (p42)  mov  ret0=cr.pmv       // cr73

+  (p43)  mov  ret0=cr.cmcv      // cr74

+  (p49)  mov  ret0=cr.lrr0      // cr80

+  (p50)  mov  ret0=cr.lrr1      // cr81

+  

+  //

+  // Restore predicates and return.

+  //

+  mov  pr=r14,-1

+  br.ret.sptk  b0

+  .endp

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/SetJmp.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/SetJmp.s
new file mode 100644
index 0000000..71467f5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/SetJmp.s
@@ -0,0 +1,108 @@
+/// @file

+///  Contains an implementation of longjmp for the Itanium-based architecture.

+///

+/// 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.

+///

+/// Module Name: longjmp.s

+///

+///

+

+.auto

+.text

+

+ASM_GLOBAL InternalAssertJumpBuffer

+.type   InternalAssertJumpBuffer, @function

+

+.proc   SetJump

+.type   SetJump, @function

+SetJump::

+        alloc               loc0 = ar.pfs, 1, 2, 1, 0

+        mov                 loc1 = b0

+        mov                 out0 = in0

+

+        brl.call.sptk.many  b0  = InternalAssertJumpBuffer

+

+        mov                 r14 = ar.unat

+        mov                 r15 = ar.bsp

+        add                 r10 = 0x10*20, in0

+

+        stf.spill.nta       [in0] = f2, 0x10

+        st8.spill.nta       [r10] = r4, 8

+        mov                 r21 = b1

+

+        stf.spill.nta       [in0] = f3, 0x10

+        st8.spill.nta       [r10] = r5, 8

+        mov                 r22 = b2

+

+        stf.spill.nta       [in0] = f4, 0x10

+        st8.spill.nta       [r10] = r6, 8

+        mov                 r23 = b3

+

+        stf.spill.nta       [in0] = f5, 0x10

+        st8.spill.nta       [r10] = r7, 8

+        mov                 r24 = b4

+

+        stf.spill.nta       [in0] = f16, 0x10

+        st8.spill.nta       [r10] = sp, 8

+        mov                 r25 = b5

+

+        stf.spill.nta       [in0] = f17, 0x10

+        st8.nta             [r10] = loc1, 8

+        mov                 r16 = pr

+

+        stf.spill.nta       [in0] = f18, 0x10

+        st8.nta             [r10] = r21, 8

+        mov                 r17 = ar.lc

+

+        stf.spill.nta       [in0] = f19, 0x10

+        st8.nta             [r10] = r22, 8

+

+        stf.spill.nta       [in0] = f20, 0x10

+        st8.nta             [r10] = r23, 8

+

+        stf.spill.nta       [in0] = f21, 0x10

+        st8.nta             [r10] = r24, 8

+

+        stf.spill.nta       [in0] = f22, 0x10

+        st8.nta             [r10] = r25, 8

+

+        stf.spill.nta       [in0] = f23, 0x10

+        mov                 r18 = ar.unat

+

+        stf.spill.nta       [in0] = f24, 0x10

+        st8.nta             [r10] = r14, 8          // UNAT

+

+        stf.spill.nta       [in0] = f25, 0x10

+        st8.nta             [r10] = r18, 8          // UNAT after spill

+

+        stf.spill.nta       [in0] = f26, 0x10

+        st8.nta             [r10] = loc0, 8         // PFS

+

+        stf.spill.nta       [in0] = f27, 0x10

+        st8.nta             [r10] = r15, 8          // BSP

+        mov                 r8  = 0

+

+        stf.spill.nta       [in0] = f28, 0x10

+        mov                 r19 = ar.fpsr

+

+        stf.spill.nta       [in0] = f29, 0x10

+        st8.nta             [r10] = r16, 8          // PR

+        mov                 ar.pfs = loc0

+

+        stf.spill.nta       [in0] = f30, 0x10

+        st8.nta             [r10] = r17, 8          // LC

+        mov                 b0  = loc1

+

+        stf.spill.nta       [in0] = f31, 0x10

+        st8.nta             [r10] = r19             // FPSR

+

+        mov                 ar.unat = r14

+        br.ret.sptk         b0

+.endp   SetJump

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/SwitchStack.s b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/SwitchStack.s
new file mode 100644
index 0000000..1236bbe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/SwitchStack.s
@@ -0,0 +1,52 @@
+/// @file

+///  IPF specific SwitchStack() function

+///

+/// 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.

+///

+/// Module Name: SwitchStack.s

+///

+///

+

+.auto

+.text

+

+.proc   AsmSwitchStackAndBackingStore

+.type   AsmSwitchStackAndBackingStore, @function

+.regstk 5, 0, 0, 0

+AsmSwitchStackAndBackingStore::

+        mov                 r14 = ar.rsc

+        movl                r2  = ~((((1 << 14) - 1) << 16) | 3)

+

+        mov                 r17 = in1

+        mov                 r18 = in2

+        and                 r2  = r14, r2

+        

+        flushrs

+        

+        mov                 ar.rsc = r2

+        mov                 sp  = in3

+        mov                 r19 = in4

+

+        ld8.nt1             r16 = [in0], 8

+        ld8.nta             gp  = [in0]

+        mov                 r3  = -1

+

+        loadrs

+        mov                 ar.bspstore = r19

+        mov                 b7  = r16

+

+        alloc               r2  = ar.pfs, 0, 0, 2, 0

+        mov                 out0 = r17

+        mov                 out1 = r18

+

+        mov                 ar.rnat = r3

+        mov                 ar.rsc = r14

+        br.call.sptk.many   b0  = b7

+.endp   AsmSwitchStackAndBackingStore

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Unaligned.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Unaligned.c
new file mode 100644
index 0000000..7d0d8dd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Ipf/Unaligned.c
@@ -0,0 +1,243 @@
+/** @file

+  Unaligned access functions of BaseLib for IPF.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT16)(((UINT8*)Buffer)[0] | (((UINT8*)Buffer)[1] << 8));

+}

+

+/**

+  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   The 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  ((UINT8*)Buffer)[0] = (UINT8)Value;

+  ((UINT8*)Buffer)[1] = (UINT8)(Value >> 8);

+

+  return 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return (UINT32)(

+            ReadUnaligned16 ((UINT16*)Buffer) |

+            (((UINT8*)Buffer)[2] << 16)

+            );

+}

+

+/**

+  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   The 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);

+  *(UINT8*)((UINT16*)Buffer + 1) = (UINT8)(Value >> 16);

+  return 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

+  )

+{

+  UINT16  LowerBytes;

+  UINT16  HigherBytes;

+

+  ASSERT (Buffer != NULL);

+

+  LowerBytes  = ReadUnaligned16 ((UINT16*) Buffer);

+  HigherBytes = ReadUnaligned16 ((UINT16*) Buffer + 1);

+

+  return (UINT32) (LowerBytes | (HigherBytes << 16));

+}

+

+/**

+  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   The 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);

+  WriteUnaligned16 ((UINT16*)Buffer + 1, (UINT16)(Value >> 16));

+  return 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

+  )

+{

+  UINT32  LowerBytes;

+  UINT32  HigherBytes;

+

+  ASSERT (Buffer != NULL);

+

+  LowerBytes  = ReadUnaligned32 ((UINT32*) Buffer);

+  HigherBytes = ReadUnaligned32 ((UINT32*) Buffer + 1);

+

+  return (UINT64) (LowerBytes | LShiftU64 (HigherBytes, 32));

+}

+

+/**

+  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   The 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  WriteUnaligned32 ((UINT32*)Buffer, (UINT32)Value);

+  WriteUnaligned32 ((UINT32*)Buffer + 1, (UINT32)RShiftU64 (Value, 32));

+  return Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LRotU32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LRotU32.c
new file mode 100644
index 0000000..d9bde78
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LRotU32.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Count < 32);

+  return (Operand << Count) | (Operand >> (32 - Count));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LRotU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LRotU64.c
new file mode 100644
index 0000000..66b982a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LRotU64.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Count < 64);

+  return InternalMathLRotU64 (Operand, Count);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LShiftU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LShiftU64.c
new file mode 100644
index 0000000..d13fd21
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LShiftU64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Count < 64);

+  return InternalMathLShiftU64 (Operand, Count);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LinkedList.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LinkedList.c
new file mode 100644
index 0000000..ba373f4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LinkedList.c
@@ -0,0 +1,550 @@
+/** @file

+  Linked List Library Functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  Worker function that locates the Node in the List.

+

+  By searching the List, finds the location of the Node in List. At the same time,

+  verifies the validity of this list.

+

+  If List is NULL, then ASSERT().

+  If List->ForwardLink is NULL, then ASSERT().

+  If List->backLink is NULL, then ASSERT().

+  If Node is NULL, then ASSERT().

+  If PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node 

+  is in not a member of List, then return FALSE

+  If PcdMaximumLinkedListLength is not zero, and List contains more than

+  PcdMaximumLinkedListLength nodes, then ASSERT().

+

+  @param  List              A pointer to a node in a linked list.

+  @param  Node              A pointer to a node in a linked list.

+  @param  VerifyNodeInList  TRUE if a check should be made to see if Node is a 

+                            member of List.  FALSE if no membership test should 

+                            be performed.

+

+  @retval   TRUE if PcdVerifyNodeInList is FALSE

+  @retval   TRUE if DoMembershipCheck is FALSE

+  @retval   TRUE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE 

+            and Node is a member of List.

+  @retval   FALSE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE 

+            and Node is in not a member of List.

+

+**/

+BOOLEAN

+EFIAPI

+InternalBaseLibIsNodeInList (

+  IN CONST LIST_ENTRY  *List,

+  IN CONST LIST_ENTRY  *Node,

+  IN BOOLEAN           VerifyNodeInList

+  )

+{

+  UINTN             Count;

+  CONST LIST_ENTRY  *Ptr;

+

+  //

+  // Test the validity of List and Node

+  //

+  ASSERT (List != NULL);

+  ASSERT (List->ForwardLink != NULL);

+  ASSERT (List->BackLink != NULL);

+  ASSERT (Node != NULL);

+

+  Count = 0;

+  Ptr   = List;

+

+  if (FeaturePcdGet (PcdVerifyNodeInList) && VerifyNodeInList) {

+    //

+    // Check to see if Node is a member of List.  

+    // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength

+    //

+    do {

+      Ptr = Ptr->ForwardLink;

+      if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {

+        Count++;

+        //

+        // ASSERT() if the linked list is too long

+        //

+        ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength));

+

+        //

+        // Return if the linked list is too long

+        //

+        if (Count >= PcdGet32 (PcdMaximumLinkedListLength)) {

+          return (BOOLEAN)(Ptr == Node);

+        }

+      }

+    } while ((Ptr != List) && (Ptr != Node)); 

+

+    if (Ptr != Node) {

+      return FALSE;

+    }

+  }

+

+  if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {

+    //

+    // Count the total number of nodes in List.

+    // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength

+    //

+    do {

+      Ptr = Ptr->ForwardLink;

+      Count++;

+    } while ((Ptr != List) && (Count < PcdGet32 (PcdMaximumLinkedListLength)));

+

+    //

+    // ASSERT() if the linked list is too long

+    //

+    ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength));

+  }

+

+  return TRUE;

+}

+

+/**

+  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

+  )

+

+{

+  ASSERT (ListHead != NULL);

+

+  ListHead->ForwardLink = ListHead;

+  ListHead->BackLink = ListHead;

+  return 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

+  )

+{

+  //

+  // ASSERT List not too long and Entry is not one of the nodes of List

+  //

+  ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE));

+  

+  Entry->ForwardLink = ListHead->ForwardLink;

+  Entry->BackLink = ListHead;

+  Entry->ForwardLink->BackLink = Entry;

+  ListHead->ForwardLink = Entry;

+  return ListHead;

+}

+

+/**

+  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

+  )

+{

+  //

+  // ASSERT List not too long and Entry is not one of the nodes of List

+  //

+  ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE));

+  

+  Entry->ForwardLink = ListHead;

+  Entry->BackLink = ListHead->BackLink;

+  Entry->BackLink->ForwardLink = Entry;

+  ListHead->BackLink = Entry;

+  return ListHead;

+}

+

+/**

+  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

+  )

+{

+  //

+  // ASSERT List not too long

+  //

+  ASSERT (InternalBaseLibIsNodeInList (List, List, FALSE));

+

+  return List->ForwardLink;

+}

+

+/**

+  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 A 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

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));

+

+  return Node->ForwardLink;

+}

+

+/**

+  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 A 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

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));

+ 

+  return Node->BackLink;

+}

+

+/**

+  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

+  )

+{

+  //

+  // ASSERT List not too long

+  //

+  ASSERT (InternalBaseLibIsNodeInList (ListHead, ListHead, FALSE));

+  

+  return (BOOLEAN)(ListHead->ForwardLink == 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 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

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));

+  

+  return (BOOLEAN)(Node == List);

+}

+

+/**

+  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

+  )

+{

+  //

+  // ASSERT List not too long and Node is one of the nodes of List

+  //

+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));

+  

+  return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == 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

+  )

+{

+  LIST_ENTRY                    *Ptr;

+

+  if (FirstEntry == SecondEntry) {

+    return SecondEntry;

+  }

+

+  //

+  // ASSERT Entry1 and Entry2 are in the same linked list

+  //

+  ASSERT (InternalBaseLibIsNodeInList (FirstEntry, SecondEntry, TRUE));

+  

+  //

+  // Ptr is the node pointed to by FirstEntry->ForwardLink

+  //

+  Ptr = RemoveEntryList (FirstEntry);

+

+  //

+  // If FirstEntry immediately follows SecondEntry, FirstEntry will be placed

+  // immediately in front of SecondEntry

+  //

+  if (Ptr->BackLink == SecondEntry) {

+    return InsertTailList (SecondEntry, FirstEntry);

+  }

+

+  //

+  // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry,

+  // then there are no further steps necessary

+  //

+  if (Ptr == InsertHeadList (SecondEntry, FirstEntry)) {

+    return Ptr;

+  }

+

+  //

+  // Move SecondEntry to the front of Ptr

+  //

+  RemoveEntryList (SecondEntry);

+  InsertTailList (Ptr, SecondEntry);

+  return 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

+  )

+{

+  ASSERT (!IsListEmpty (Entry));

+  

+  Entry->ForwardLink->BackLink = Entry->BackLink;

+  Entry->BackLink->ForwardLink = Entry->ForwardLink;

+  return Entry->ForwardLink;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LongJump.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LongJump.c
new file mode 100644
index 0000000..062be8f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LongJump.c
@@ -0,0 +1,47 @@
+/** @file

+  Long Jump functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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 IPF CPUs, 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

+  )

+{

+  InternalAssertJumpBuffer (JumpBuffer);

+  ASSERT (Value != 0);

+

+  InternalLongJump (JumpBuffer, Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LowBitSet32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LowBitSet32.c
new file mode 100644
index 0000000..6430036
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LowBitSet32.c
@@ -0,0 +1,47 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  INTN                              BitIndex;

+

+  if (Operand == 0) {

+    return -1;

+  }

+

+  for (BitIndex = 0; 0 == (Operand & 1); BitIndex++, Operand >>= 1);

+  return BitIndex;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/LowBitSet64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LowBitSet64.c
new file mode 100644
index 0000000..2bc8bc3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/LowBitSet64.c
@@ -0,0 +1,50 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  INTN                              BitIndex;

+

+  if (Operand == 0) {

+    return -1;

+  }

+

+  for (BitIndex = 0;

+       (Operand & 1) == 0;

+       BitIndex++, Operand = RShiftU64 (Operand, 1));

+  return BitIndex;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Math64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Math64.c
new file mode 100644
index 0000000..83d7684
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Math64.c
@@ -0,0 +1,368 @@
+/** @file

+  Leaf math worker functions that require 64-bit arithmetic support from the

+  compiler.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to shift left.

+  @param  Count   The number of bits to shift left.

+

+  @return Operand << Count.

+

+**/

+UINT64

+EFIAPI

+InternalMathLShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return Operand << 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.

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand >> Count.

+

+**/

+UINT64

+EFIAPI

+InternalMathRShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return Operand >> 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.

+

+  @param  Operand The 64-bit operand to shift right.

+  @param  Count   The number of bits to shift right.

+

+  @return Operand arithmetically shifted right by Count.

+

+**/

+UINT64

+EFIAPI

+InternalMathARShiftU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  INTN  TestValue;

+

+  //

+  // Test if this compiler supports arithmetic shift

+  //

+  TestValue = (((-1) << (sizeof (-1) * 8 - 1)) >> (sizeof (-1) * 8 - 1));

+  if (TestValue == -1) {

+    //

+    // Arithmetic shift is supported

+    //

+    return (UINT64)((INT64)Operand >> Count);

+  }

+

+  //

+  // Arithmetic is not supported

+  //

+  return (Operand >> Count) |

+         ((INTN)Operand < 0 ? ~((UINTN)-1 >> Count) : 0);

+}

+

+

+/**

+  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.

+

+  @param  Operand The 64-bit operand to rotate left.

+  @param  Count   The number of bits to rotate left.

+

+  @return Operand <<< Count.

+

+**/

+UINT64

+EFIAPI

+InternalMathLRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return (Operand << Count) | (Operand >> (64 - 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.

+

+  @param  Operand The 64-bit operand to rotate right.

+  @param  Count   The number of bits to rotate right.

+

+  @return Operand >>> Count.

+

+**/

+UINT64

+EFIAPI

+InternalMathRRotU64 (

+  IN      UINT64                    Operand,

+  IN      UINTN                     Count

+  )

+{

+  return (Operand >> Count) | (Operand << (64 - Count));

+}

+

+/**

+  Switches the endianess 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  Operand A 64-bit unsigned value.

+

+  @return The byte swapped Operand.

+

+**/

+UINT64

+EFIAPI

+InternalMathSwapBytes64 (

+  IN      UINT64                    Operand

+  )

+{

+  UINT64  LowerBytes;

+  UINT64  HigherBytes;

+

+  LowerBytes  = (UINT64) SwapBytes32 ((UINT32) Operand);

+  HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));

+

+  return (LowerBytes << 32 | HigherBytes);

+}

+

+/**

+  Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer

+  and generates a 64-bit unsigned result.

+

+  This function multiplies 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

+InternalMathMultU64x32 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT32                    Multiplier

+  )

+{

+  return Multiplicand * Multiplier;

+}

+

+

+/**

+  Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer

+  and generates a 64-bit unsigned result.

+

+  This function multiplies 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

+InternalMathMultU64x64 (

+  IN      UINT64                    Multiplicand,

+  IN      UINT64                    Multiplier

+  )

+{

+  return Multiplicand * 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.

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend / Divisor.

+

+**/

+UINT64

+EFIAPI

+InternalMathDivU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  return Dividend / 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.

+

+  @param  Dividend  A 64-bit unsigned value.

+  @param  Divisor   A 32-bit unsigned value.

+

+  @return Dividend % Divisor.

+

+**/

+UINT32

+EFIAPI

+InternalMathModU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor

+  )

+{

+  return (UINT32)(Dividend % 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.

+

+  @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

+InternalMathDivRemU64x32 (

+  IN      UINT64                    Dividend,

+  IN      UINT32                    Divisor,

+  OUT     UINT32                    *Remainder OPTIONAL

+  )

+{

+  if (Remainder != NULL) {

+    *Remainder = (UINT32)(Dividend % Divisor);

+  }

+  return Dividend / Divisor;

+}

+

+/**

+  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.

+

+  @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

+InternalMathDivRemU64x64 (

+  IN      UINT64                    Dividend,

+  IN      UINT64                    Divisor,

+  OUT     UINT64                    *Remainder OPTIONAL

+  )

+{

+  if (Remainder != NULL) {

+    *Remainder = Dividend % Divisor;

+  }

+  return Dividend / Divisor;

+}

+

+/**

+  Divides a 64-bit signed integer by a 64-bit signed integer and

+  generates a 64-bit signed result and an 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.

+

+  @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

+InternalMathDivRemS64x64 (

+  IN      INT64                     Dividend,

+  IN      INT64                     Divisor,

+  OUT     INT64                     *Remainder  OPTIONAL

+  )

+{

+  if (Remainder != NULL) {

+    *Remainder = Dividend % Divisor;

+  }

+  return Dividend / Divisor;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/ModU64x32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/ModU64x32.c
new file mode 100644
index 0000000..29d7b77
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/ModU64x32.c
@@ -0,0 +1,45 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Divisor != 0);

+  return InternalMathModU64x32 (Dividend, Divisor);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultS64x64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultS64x64.c
new file mode 100644
index 0000000..229c76c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultS64x64.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Multiplies a 64-bit signed integer by a 64-bit signed integer and generates a

+  64-bit signed result.

+

+  This function multiplies 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

+  )

+{

+  return (INT64)MultU64x64 ((UINT64) Multiplicand, (UINT64) Multiplier);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultU64x32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultU64x32.c
new file mode 100644
index 0000000..a2c2436
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultU64x32.c
@@ -0,0 +1,46 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and

+  generates a 64-bit unsigned result.

+

+  This function multiplies 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

+  )

+{

+  UINT64                            Result;

+

+  Result = InternalMathMultU64x32 (Multiplicand, Multiplier);

+

+  return Result;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultU64x64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultU64x64.c
new file mode 100644
index 0000000..a1a7629
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/MultU64x64.c
@@ -0,0 +1,46 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer and

+  generates a 64-bit unsigned result.

+

+  This function multiplies 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

+  )

+{

+  UINT64                            Result;

+

+  Result = InternalMathMultU64x64 (Multiplicand, Multiplier);

+

+  return Result;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/RRotU32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/RRotU32.c
new file mode 100644
index 0000000..f4779f5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/RRotU32.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Count < 32);

+  return (Operand >> Count) | (Operand << (32 - Count));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/RRotU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/RRotU64.c
new file mode 100644
index 0000000..45be7ef
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/RRotU64.c
@@ -0,0 +1,42 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Count < 64);

+  return InternalMathRRotU64 (Operand, Count);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/RShiftU64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/RShiftU64.c
new file mode 100644
index 0000000..8a4834b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/RShiftU64.c
@@ -0,0 +1,41 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Count < 64);

+  return InternalMathRShiftU64 (Operand, Count);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/SafeString.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SafeString.c
new file mode 100644
index 0000000..7d7765b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SafeString.c
@@ -0,0 +1,896 @@
+/** @file

+  Safe String functions.

+

+  Copyright (c) 2014, 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 <Base.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+

+#define RSIZE_MAX  (PcdGet32 (PcdMaximumUnicodeStringLength))

+

+#define ASCII_RSIZE_MAX  (PcdGet32 (PcdMaximumAsciiStringLength))

+

+#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status)  \

+  do { \

+    ASSERT (Expression); \

+    if (!(Expression)) { \

+      return Status; \

+    } \

+  } while (FALSE)

+

+/**

+  Returns if 2 memory blocks are overlapped.

+

+  @param  Base1  Base address of 1st memory block.

+  @param  Size1  Size of 1st memory block.

+  @param  Base2  Base address of 2nd memory block.

+  @param  Size2  Size of 2nd memory block.

+

+  @retval TRUE  2 memory blocks are overlapped.

+  @retval FALSE 2 memory blocks are not overlapped.

+**/

+BOOLEAN

+InternalSafeStringIsOverlap (

+  IN VOID    *Base1,

+  IN UINTN   Size1,

+  IN VOID    *Base2,

+  IN UINTN   Size2

+  )

+{

+  if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||

+      (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {

+    return TRUE;

+  }

+  return FALSE;

+}

+

+/**

+  Returns if 2 Unicode strings are not overlapped.

+

+  @param  Str1   Start address of 1st Unicode string.

+  @param  Size1  The number of char in 1st Unicode string,

+                 including terminating null char.

+  @param  Str2   Start address of 2nd Unicode string.

+  @param  Size2  The number of char in 2nd Unicode string,

+                 including terminating null char.

+

+  @retval TRUE  2 Unicode strings are NOT overlapped.

+  @retval FALSE 2 Unicode strings are overlapped.

+**/

+BOOLEAN

+InternalSafeStringNoStrOverlap (

+  IN CHAR16  *Str1,

+  IN UINTN   Size1,

+  IN CHAR16  *Str2,

+  IN UINTN   Size2

+  )

+{

+  return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));

+}

+

+/**

+  Returns if 2 Ascii strings are not overlapped.

+

+  @param  Str1   Start address of 1st Ascii string.

+  @param  Size1  The number of char in 1st Ascii string,

+                 including terminating null char.

+  @param  Str2   Start address of 2nd Ascii string.

+  @param  Size2  The number of char in 2nd Ascii string,

+                 including terminating null char.

+

+  @retval TRUE  2 Ascii strings are NOT overlapped.

+  @retval FALSE 2 Ascii strings are overlapped.

+**/

+BOOLEAN

+InternalSafeStringNoAsciiStrOverlap (

+  IN CHAR8   *Str1,

+  IN UINTN   Size1,

+  IN CHAR8   *Str2,

+  IN UINTN   Size2

+  )

+{

+  return !InternalSafeStringIsOverlap (Str1, Size1, Str2, Size2);

+}

+

+/**

+  Returns the length of a Null-terminated Unicode string.

+

+  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

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (((UINTN) String & BIT0) == 0);

+

+  //

+  // If String is a null pointer, then the StrnLenS function returns zero.

+  //

+  if (String == NULL) {

+    return 0;

+  }

+

+  //

+  // Otherwise, the StrnLenS function returns the number of characters that precede the

+  // terminating null character. If there is no null character in the first MaxSize characters of

+  // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall

+  // be accessed by StrnLenS.

+  //

+  for (Length = 0; (*String != 0) && (Length < MaxSize); String++, Length++) {

+    ;

+  }

+  return Length;

+}

+

+/**

+  Copies the string pointed to by Source (including the terminating null char)

+  to the array pointed to by Destination.

+

+  If Destination is not aligned on a 16-bit boundary, then ASSERT().

+  If Source is not aligned on a 16-bit boundary, then ASSERT().

+

+  @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

+  )

+{

+  UINTN            SourceLen;

+  

+  ASSERT (((UINTN) Destination & BIT0) == 0);

+  ASSERT (((UINTN) Source & BIT0) == 0);

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. DestMax shall not be greater than RSIZE_MAX.

+  //

+  if (RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. DestMax shall be greater than StrnLenS(Source, DestMax).

+  //

+  SourceLen = StrnLenS (Source, DestMax);

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);

+

+  //

+  // 5. Copying shall not take place between objects that overlap.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The StrCpyS function copies the string pointed to by Source (including the terminating

+  // null character) into the array pointed to by Destination.

+  //

+  while (*Source != 0) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  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.

+

+  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().

+

+  @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

+  )

+{

+  UINTN            SourceLen;

+

+  ASSERT (((UINTN) Destination & BIT0) == 0);

+  ASSERT (((UINTN) Source & BIT0) == 0);

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX

+  //

+  if (RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);

+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).

+  //

+  SourceLen = StrnLenS (Source, DestMax);

+  if (Length >= DestMax) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);

+  }

+

+  //

+  // 5. Copying shall not take place between objects that overlap.

+  //

+  if (SourceLen > Length) {

+    SourceLen = Length;

+  }

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The StrnCpyS function copies not more than Length successive characters (characters that

+  // follow a null character are not copied) from the array pointed to by Source to the array

+  // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null

+  // character.

+  //

+  while ((*Source != 0) && (SourceLen > 0)) {

+    *(Destination++) = *(Source++);

+    SourceLen--;

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  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.

+

+  If Destination is not aligned on a 16-bit boundary, then ASSERT().

+  If Source is not aligned on a 16-bit boundary, then ASSERT().

+

+  @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

+  )

+{

+  UINTN               DestLen;

+  UINTN               CopyLen;

+  UINTN               SourceLen;

+  

+  ASSERT (((UINTN) Destination & BIT0) == 0);

+  ASSERT (((UINTN) Source & BIT0) == 0);

+

+  //

+  // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.

+  //

+  DestLen = StrnLenS (Destination, DestMax);

+  CopyLen = DestMax - DestLen;

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. DestMax shall not be greater than RSIZE_MAX.

+  //

+  if (RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. CopyLen shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);

+

+  //

+  // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).

+  //

+  SourceLen = StrnLenS (Source, CopyLen);

+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);

+

+  //

+  // 6. Copying shall not take place between objects that overlap.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The StrCatS function appends a copy of the string pointed to by Source (including the

+  // terminating null character) to the end of the string pointed to by Destination. The initial character

+  // from Source overwrites the null character at the end of Destination.

+  //

+  Destination = Destination + DestLen;

+  while (*Source != 0) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  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.

+

+  If Destination is not aligned on a 16-bit boundary, then ASSERT().

+  If and Source is not aligned on a 16-bit boundary, then ASSERT().

+

+  @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

+  )

+{

+  UINTN               DestLen;

+  UINTN               CopyLen;

+  UINTN               SourceLen;

+  

+  ASSERT (((UINTN) Destination & BIT0) == 0);

+  ASSERT (((UINTN) Source & BIT0) == 0);

+

+  //

+  // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.

+  //

+  DestLen = StrnLenS (Destination, DestMax);

+  CopyLen = DestMax - DestLen;

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.

+  //

+  if (RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);

+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. CopyLen shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);

+

+  //

+  // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).

+  //

+  SourceLen = StrnLenS (Source, CopyLen);

+  if (Length >= CopyLen) {

+    SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);

+  }

+

+  //

+  // 6. Copying shall not take place between objects that overlap.

+  //

+  if (SourceLen > Length) {

+    SourceLen = Length;

+  }

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The StrnCatS function appends not more than Length successive characters (characters

+  // that follow a null character are not copied) from the array pointed to by Source to the end of

+  // the string pointed to by Destination. The initial character from Source overwrites the null character at

+  // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to

+  // a null character.

+  //

+  Destination = Destination + DestLen;

+  while ((*Source != 0) && (SourceLen > 0)) {

+    *(Destination++) = *(Source++);

+    SourceLen--;

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Returns the length of a Null-terminated Ascii string.

+

+  @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

+  )

+{

+  UINTN                             Length;

+

+  //

+  // If String is a null pointer, then the AsciiStrnLenS function returns zero.

+  //

+  if (String == NULL) {

+    return 0;

+  }

+

+  //

+  // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the

+  // terminating null character. If there is no null character in the first MaxSize characters of

+  // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall

+  // be accessed by AsciiStrnLenS.

+  //

+  for (Length = 0; (*String != 0) && (Length < MaxSize); String++, Length++) {

+    ;

+  }

+  return Length;

+}

+

+/**

+  Copies the string pointed to by Source (including the terminating null char)

+  to the array pointed to by Destination.

+

+  @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

+  )

+{

+  UINTN            SourceLen;

+  

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.

+  //

+  if (ASCII_RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).

+  //

+  SourceLen = AsciiStrnLenS (Source, DestMax);

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);

+

+  //

+  // 5. Copying shall not take place between objects that overlap.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating

+  // null character) into the array pointed to by Destination.

+  //

+  while (*Source != 0) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  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.

+

+  @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

+  )

+{

+  UINTN            SourceLen;

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX

+  //

+  if (ASCII_RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);

+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).

+  //

+  SourceLen = AsciiStrnLenS (Source, DestMax);

+  if (Length >= DestMax) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);

+  }

+

+  //

+  // 5. Copying shall not take place between objects that overlap.

+  //

+  if (SourceLen > Length) {

+    SourceLen = Length;

+  }

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The AsciiStrnCpyS function copies not more than Length successive characters (characters that

+  // follow a null character are not copied) from the array pointed to by Source to the array

+  // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null

+  // character.

+  //

+  while ((*Source != 0) && (SourceLen > 0)) {

+    *(Destination++) = *(Source++);

+    SourceLen--;

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  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.

+

+  @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

+  )

+{

+  UINTN               DestLen;

+  UINTN               CopyLen;

+  UINTN               SourceLen;

+  

+  //

+  // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.

+  //

+  DestLen = AsciiStrnLenS (Destination, DestMax);

+  CopyLen = DestMax - DestLen;

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.

+  //

+  if (ASCII_RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. CopyLen shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);

+

+  //

+  // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).

+  //

+  SourceLen = AsciiStrnLenS (Source, CopyLen);

+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);

+

+  //

+  // 6. Copying shall not take place between objects that overlap.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the

+  // terminating null character) to the end of the string pointed to by Destination. The initial character

+  // from Source overwrites the null character at the end of Destination.

+  //

+  Destination = Destination + DestLen;

+  while (*Source != 0) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  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.

+

+  @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

+  )

+{

+  UINTN               DestLen;

+  UINTN               CopyLen;

+  UINTN               SourceLen;

+  

+  //

+  // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.

+  //

+  DestLen = AsciiStrnLenS (Destination, DestMax);

+  CopyLen = DestMax - DestLen;

+

+  //

+  // 1. Neither Destination nor Source shall be a null pointer.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);

+  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

+

+  //

+  // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.

+  //

+  if (ASCII_RSIZE_MAX != 0) {

+    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);

+    SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);

+  }

+

+  //

+  // 3. DestMax shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

+

+  //

+  // 4. CopyLen shall not equal zero.

+  //

+  SAFE_STRING_CONSTRAINT_CHECK ((CopyLen != 0), RETURN_BAD_BUFFER_SIZE);

+

+  //

+  // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).

+  //

+  SourceLen = AsciiStrnLenS (Source, CopyLen);

+  if (Length >= CopyLen) {

+    SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL);

+  }

+

+  //

+  // 6. Copying shall not take place between objects that overlap.

+  //

+  if (SourceLen > Length) {

+    SourceLen = Length;

+  }

+  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

+

+  //

+  // The AsciiStrnCatS function appends not more than Length successive characters (characters

+  // that follow a null character are not copied) from the array pointed to by Source to the end of

+  // the string pointed to by Destination. The initial character from Source overwrites the null character at

+  // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to

+  // a null character.

+  //

+  Destination = Destination + DestLen;

+  while ((*Source != 0) && (SourceLen > 0)) {

+    *(Destination++) = *(Source++);

+    SourceLen--;

+  }

+  *Destination = 0;

+

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/SetJump.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SetJump.c
new file mode 100644
index 0000000..b8fb35b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SetJump.c
@@ -0,0 +1,40 @@
+/** @file

+  Internal ASSERT () functions for SetJump.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Worker function that checks ASSERT condition for JumpBuffer

+

+  Checks ASSERT condition for JumpBuffer.

+

+  If JumpBuffer is NULL, then ASSERT().

+  For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().

+

+  @param  JumpBuffer    A pointer to CPU context buffer.

+

+**/

+VOID

+EFIAPI

+InternalAssertJumpBuffer (

+  IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+  )

+{

+  ASSERT (JumpBuffer != NULL);

+

+  ASSERT (((UINTN)JumpBuffer & (BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT - 1)) == 0);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/String.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/String.c
new file mode 100644
index 0000000..92992a5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/String.c
@@ -0,0 +1,2103 @@
+/** @file

+  Unicode and ASCII string primatives.

+

+  Copyright (c) 2006 - 2014, 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 "BaseLibInternals.h"

+

+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated Unicode string.

+  @param  Source      A pointer to a Null-terminated Unicode string.

+

+  @return Destination.

+

+**/

+CHAR16 *

+EFIAPI

+StrCpy (

+  OUT     CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+  ASSERT (((UINTN) Destination & BIT0) == 0);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) > StrLen (Source));

+

+  ReturnValue = Destination;

+  while (*Source != 0) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+  return ReturnValue;

+}

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated Unicode string.

+  @param  Source      A 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

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  if (Length == 0) {

+    return Destination;

+  }

+

+  //

+  // Destination cannot be NULL if Length is not zero

+  //

+  ASSERT (Destination != NULL);

+  ASSERT (((UINTN) Destination & BIT0) == 0);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > StrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) >= Length);

+

+  if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {

+    ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));

+  }

+

+  ReturnValue = Destination;

+

+  while ((*Source != L'\0') && (Length > 0)) {

+    *(Destination++) = *(Source++);

+    Length--;

+  }

+

+  ZeroMem (Destination, Length * sizeof (*Destination));

+  return ReturnValue;

+}

+#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  A pointer to a Null-terminated Unicode string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+StrLen (

+  IN      CONST CHAR16              *String

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (String != NULL);

+  ASSERT (((UINTN) String & BIT0) == 0);

+

+  for (Length = 0; *String != L'\0'; String++, Length++) {

+    //

+    // If PcdMaximumUnicodeStringLength is not zero,

+    // length should not more than PcdMaximumUnicodeStringLength

+    //

+    if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {

+      ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));

+    }

+  }

+  return Length;

+}

+

+/**

+  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  A pointer to a Null-terminated Unicode string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+StrSize (

+  IN      CONST CHAR16              *String

+  )

+{

+  return (StrLen (String) + 1) * sizeof (*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   A pointer to a Null-terminated Unicode string.

+  @param  SecondString  A 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

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength

+  //

+  ASSERT (StrSize (FirstString) != 0);

+  ASSERT (StrSize (SecondString) != 0);

+

+  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {

+    FirstString++;

+    SecondString++;

+  }

+  return *FirstString - *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   A pointer to a Null-terminated Unicode string.

+  @param  SecondString  A 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

+  )

+{

+  if (Length == 0) {

+    return 0;

+  }

+

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (FirstString) != 0);

+  ASSERT (StrSize (SecondString) != 0);

+

+  if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {

+    ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));

+  }

+

+  while ((*FirstString != L'\0') &&

+         (*FirstString == *SecondString) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+

+  return *FirstString - *SecondString;

+}

+

+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated Unicode string.

+  @param  Source      A pointer to a Null-terminated Unicode string.

+

+  @return Destination.

+

+**/

+CHAR16 *

+EFIAPI

+StrCat (

+  IN OUT  CHAR16                    *Destination,

+  IN      CONST CHAR16              *Source

+  )

+{

+  StrCpy (Destination + StrLen (Destination), Source);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (StrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated Unicode string.

+  @param  Source      A 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

+  )

+{

+  UINTN   DestinationLen;

+

+  DestinationLen = StrLen (Destination);

+  StrnCpy (Destination + DestinationLen, Source, Length);

+  Destination[DestinationLen + Length] = L'\0';

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (StrSize (Destination) != 0);

+  return Destination;

+}

+#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          A pointer to a Null-terminated Unicode string.

+  @param  SearchString    A 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

+  )

+{

+  CONST CHAR16 *FirstMatch;

+  CONST CHAR16 *SearchStringTmp;

+

+  //

+  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (String) != 0);

+  ASSERT (StrSize (SearchString) != 0);

+

+  if (*SearchString == L'\0') {

+    return (CHAR16 *) String;

+  }

+

+  while (*String != L'\0') {

+    SearchStringTmp = SearchString;

+    FirstMatch = String;

+    

+    while ((*String == *SearchStringTmp) 

+            && (*String != L'\0')) {

+      String++;

+      SearchStringTmp++;

+    } 

+    

+    if (*SearchStringTmp == L'\0') {

+      return (CHAR16 *) FirstMatch;

+    }

+

+    if (*String == L'\0') {

+      return NULL;

+    }

+

+    String = FirstMatch + 1;

+  }

+

+  return NULL;

+}

+

+/**

+  Check if a Unicode character is a decimal character.

+

+  This internal function checks if a Unicode character is a 

+  decimal character. The valid decimal character is from

+  L'0' to L'9'.

+

+  @param  Char  The character to check against.

+

+  @retval TRUE  If the Char is a decmial character.

+  @retval FALSE If the Char is not a decmial character.

+

+**/

+BOOLEAN

+EFIAPI

+InternalIsDecimalDigitCharacter (

+  IN      CHAR16                    Char

+  )

+{

+  return (BOOLEAN) (Char >= L'0' && Char <= L'9');

+}

+

+/**

+  Convert a Unicode character to upper case only if 

+  it maps to a valid small-case ASCII character.

+

+  This internal function only deal with Unicode character

+  which maps to a valid small-case ASCII character, i.e.

+  L'a' to L'z'. For other Unicode character, the input character

+  is returned directly.

+

+  @param  Char  The character to convert.

+

+  @retval LowerCharacter   If the Char is with range L'a' to L'z'.

+  @retval Unchanged        Otherwise.

+

+**/

+CHAR16

+EFIAPI

+InternalCharToUpper (

+  IN      CHAR16                    Char

+  )

+{

+  if (Char >= L'a' && Char <= L'z') {

+    return (CHAR16) (Char - (L'a' - L'A'));

+  }

+

+  return Char;

+}

+

+/**

+  Convert a Unicode character to numerical value.

+

+  This internal function only deal with Unicode character

+  which maps to a valid hexadecimal ASII character, i.e.

+  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other 

+  Unicode character, the value returned does not make sense.

+

+  @param  Char  The character to convert.

+

+  @return The numerical value converted.

+

+**/

+UINTN

+EFIAPI

+InternalHexCharToUintn (

+  IN      CHAR16                    Char

+  )

+{

+  if (InternalIsDecimalDigitCharacter (Char)) {

+    return Char - L'0';

+  }

+

+  return (UINTN) (10 + InternalCharToUpper (Char) - L'A');

+}

+

+/**

+  Check if a Unicode character is a hexadecimal character.

+

+  This internal function checks if a Unicode character is a 

+  decimal character.  The valid hexadecimal character is 

+  L'0' to L'9', L'a' to L'f', or L'A' to L'F'.

+

+

+  @param  Char  The character to check against.

+

+  @retval TRUE  If the Char is a hexadecmial character.

+  @retval FALSE If the Char is not a hexadecmial character.

+

+**/

+BOOLEAN

+EFIAPI

+InternalIsHexaDecimalDigitCharacter (

+  IN      CHAR16                    Char

+  )

+{

+

+  return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||

+    (Char >= L'A' && Char <= L'F') ||

+    (Char >= L'a' && Char <= L'f'));

+}

+

+/**

+  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 ASSERT().

+

+  If PcdMaximumUnicodeStringLength is not zero, and String contains

+  more than PcdMaximumUnicodeStringLength Unicode characters, not including

+  the Null-terminator, then ASSERT().

+

+  @param  String      A pointer to a Null-terminated Unicode string.

+

+  @retval Value translated from String.

+

+**/

+UINTN

+EFIAPI

+StrDecimalToUintn (

+  IN      CONST CHAR16              *String

+  )

+{

+  UINTN     Result;

+  

+  //

+  // ASSERT String is less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (String) != 0);

+

+  //

+  // Ignore the pad spaces (space or tab)

+  //

+  while ((*String == L' ') || (*String == L'\t')) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == L'0') {

+    String++;

+  }

+

+  Result = 0;

+

+  while (InternalIsDecimalDigitCharacter (*String)) {

+    //

+    // If the number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= ((((UINTN) ~0) - (*String - L'0')) / 10));

+

+    Result = Result * 10 + (*String - L'0');

+    String++;

+  }

+  

+  return Result;

+}

+

+

+/**

+  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 ASSERT().

+

+  If PcdMaximumUnicodeStringLength is not zero, and String contains

+  more than PcdMaximumUnicodeStringLength Unicode characters, not including

+  the Null-terminator, then ASSERT().

+

+  @param  String          A pointer to a Null-terminated Unicode string.

+

+  @retval Value translated from String.

+

+**/

+UINT64

+EFIAPI

+StrDecimalToUint64 (

+  IN      CONST CHAR16              *String

+  )

+{

+  UINT64     Result;

+  

+  //

+  // ASSERT String is less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (String) != 0);

+

+  //

+  // Ignore the pad spaces (space or tab)

+  //

+  while ((*String == L' ') || (*String == L'\t')) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == L'0') {

+    String++;

+  }

+

+  Result = 0;

+

+  while (InternalIsDecimalDigitCharacter (*String)) {

+    //

+    // If the number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));

+

+    Result = MultU64x32 (Result, 10) + (*String - L'0');

+    String++;

+  }

+  

+  return Result;

+}

+

+/**

+  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 ASSERT().

+

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,

+  then ASSERT().

+

+  @param  String          A pointer to a Null-terminated Unicode string.

+

+  @retval Value translated from String.

+

+**/

+UINTN

+EFIAPI

+StrHexToUintn (

+  IN      CONST CHAR16              *String

+  )

+{

+  UINTN     Result;

+

+  //

+  // ASSERT String is less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (String) != 0);

+  

+  //

+  // Ignore the pad spaces (space or tab) 

+  //

+  while ((*String == L' ') || (*String == L'\t')) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == L'0') {

+    String++;

+  }

+

+  if (InternalCharToUpper (*String) == L'X') {

+    if (*(String - 1) != L'0') {

+      return 0;

+    }

+    //

+    // Skip the 'X'

+    //

+    String++;

+  }

+

+  Result = 0;

+  

+  while (InternalIsHexaDecimalDigitCharacter (*String)) {

+    //

+    // If the Hex Number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= ((((UINTN) ~0) - InternalHexCharToUintn (*String)) >> 4));

+

+    Result = (Result << 4) + InternalHexCharToUintn (*String);

+    String++;

+  }

+

+  return Result;

+}

+

+

+/**

+  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 ASSERT().

+

+  If PcdMaximumUnicodeStringLength is not zero, and String contains more than

+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,

+  then ASSERT().

+

+  @param  String          A pointer to a Null-terminated Unicode string.

+

+  @retval Value translated from String.

+

+**/

+UINT64

+EFIAPI

+StrHexToUint64 (

+  IN      CONST CHAR16             *String

+  )

+{

+  UINT64    Result;

+

+  //

+  // ASSERT String is less long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (String) != 0);

+  

+  //

+  // Ignore the pad spaces (space or tab) 

+  //

+  while ((*String == L' ') || (*String == L'\t')) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == L'0') {

+    String++;

+  }

+

+  if (InternalCharToUpper (*String) == L'X') {

+    ASSERT (*(String - 1) == L'0');

+    if (*(String - 1) != L'0') {

+      return 0;

+    }

+    //

+    // Skip the 'X'

+    //

+    String++;

+  }

+

+  Result = 0;

+  

+  while (InternalIsHexaDecimalDigitCharacter (*String)) {

+    //

+    // If the Hex Number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));

+

+    Result = LShiftU64 (Result, 4);

+    Result = Result + InternalHexCharToUintn (*String);

+    String++;

+  }

+

+  return Result;

+}

+

+/**

+  Check if a ASCII character is a decimal character.

+

+  This internal function checks if a Unicode character is a 

+  decimal character. The valid decimal character is from

+  '0' to '9'.

+

+  @param  Char  The character to check against.

+

+  @retval TRUE  If the Char is a decmial character.

+  @retval FALSE If the Char is not a decmial character.

+

+**/

+BOOLEAN

+EFIAPI

+InternalAsciiIsDecimalDigitCharacter (

+  IN      CHAR8                     Char

+  )

+{

+  return (BOOLEAN) (Char >= '0' && Char <= '9');

+}

+

+/**

+  Check if a ASCII character is a hexadecimal character.

+

+  This internal function checks if a ASCII character is a 

+  decimal character.  The valid hexadecimal character is 

+  L'0' to L'9', L'a' to L'f', or L'A' to L'F'.

+

+

+  @param  Char  The character to check against.

+

+  @retval TRUE  If the Char is a hexadecmial character.

+  @retval FALSE If the Char is not a hexadecmial character.

+

+**/

+BOOLEAN

+EFIAPI

+InternalAsciiIsHexaDecimalDigitCharacter (

+  IN      CHAR8                    Char

+  )

+{

+

+  return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||

+    (Char >= 'A' && Char <= 'F') ||

+    (Char >= 'a' && Char <= 'f'));

+}

+

+/**

+  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        A pointer to a Null-terminated Unicode string.

+  @param  Destination   A pointer to a Null-terminated ASCII string.

+

+  @return Destination.

+

+**/

+CHAR8 *

+EFIAPI

+UnicodeStrToAsciiStr (

+  IN      CONST CHAR16              *Source,

+  OUT     CHAR8                     *Destination

+  )

+{

+  CHAR8                               *ReturnValue;

+

+  ASSERT (Destination != NULL);

+

+  //

+  // ASSERT if Source is long than PcdMaximumUnicodeStringLength.

+  // Length tests are performed inside StrLen().

+  //

+  ASSERT (StrSize (Source) != 0);

+

+  //

+  // Source and Destination should not overlap

+  //

+  ASSERT ((UINTN) (Destination - (CHAR8 *) Source) >= StrSize (Source));

+  ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));

+

+

+  ReturnValue = Destination;

+  while (*Source != '\0') {

+    //

+    // If any Unicode characters in Source contain 

+    // non-zero value in the upper 8 bits, then ASSERT().

+    //

+    ASSERT (*Source < 0x100);

+    *(Destination++) = (CHAR8) *(Source++);

+  }

+

+  *Destination = '\0';

+

+  //

+  // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.

+  // Length tests are performed inside AsciiStrLen().

+  //

+  ASSERT (AsciiStrSize (ReturnValue) != 0);

+

+  return ReturnValue;

+}

+

+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated ASCII string.

+  @param  Source      A pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCpy (

+  OUT     CHAR8                     *Destination,

+  IN      CONST CHAR8               *Source

+  )

+{

+  CHAR8                             *ReturnValue;

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));

+

+  ReturnValue = Destination;

+  while (*Source != 0) {

+    *(Destination++) = *(Source++);

+  }

+  *Destination = 0;

+  return ReturnValue;

+}

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated ASCII string.

+  @param  Source      A 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

+  )

+{

+  CHAR8                             *ReturnValue;

+

+  if (Length == 0) {

+    return Destination;

+  }

+

+  //

+  // Destination cannot be NULL

+  //

+  ASSERT (Destination != NULL);

+

+  //

+  // Destination and source cannot overlap

+  //

+  ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN)(Source - Destination) >= Length);

+

+  if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {

+    ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));

+  }

+

+  ReturnValue = Destination;

+

+  while (*Source != 0 && Length > 0) {

+    *(Destination++) = *(Source++);

+    Length--;

+  }

+

+  ZeroMem (Destination, Length * sizeof (*Destination));

+  return ReturnValue;

+}

+#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  A pointer to a Null-terminated ASCII string.

+

+  @return The length of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrLen (

+  IN      CONST CHAR8               *String

+  )

+{

+  UINTN                             Length;

+

+  ASSERT (String != NULL);

+

+  for (Length = 0; *String != '\0'; String++, Length++) {

+    //

+    // If PcdMaximumUnicodeStringLength is not zero,

+    // length should not more than PcdMaximumUnicodeStringLength

+    //

+    if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {

+      ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));

+    }

+  }

+  return Length;

+}

+

+/**

+  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  A pointer to a Null-terminated ASCII string.

+

+  @return The size of String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrSize (

+  IN      CONST CHAR8               *String

+  )

+{

+  return (AsciiStrLen (String) + 1) * sizeof (*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   A pointer to a Null-terminated ASCII string.

+  @param  SecondString  A 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

+  )

+{

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  while ((*FirstString != '\0') && (*FirstString == *SecondString)) {

+    FirstString++;

+    SecondString++;

+  }

+

+  return *FirstString - *SecondString;

+}

+

+/**

+  Converts a lowercase Ascii character to upper one.

+

+  If Chr is lowercase Ascii character, then converts it to upper one.

+

+  If Value >= 0xA0, then ASSERT().

+  If (Value & 0x0F) >= 0x0A, then ASSERT().

+

+  @param  Chr   one Ascii character

+

+  @return The uppercase value of Ascii character 

+

+**/

+CHAR8

+EFIAPI

+InternalBaseLibAsciiToUpper (

+  IN      CHAR8                     Chr

+  )

+{

+  return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);

+}

+

+/**

+  Convert a ASCII character to numerical value.

+

+  This internal function only deal with Unicode character

+  which maps to a valid hexadecimal ASII character, i.e.

+  '0' to '9', 'a' to 'f' or 'A' to 'F'. For other 

+  ASCII character, the value returned does not make sense.

+

+  @param  Char  The character to convert.

+

+  @return The numerical value converted.

+

+**/

+UINTN

+EFIAPI

+InternalAsciiHexCharToUintn (

+  IN      CHAR8                    Char

+  )

+{

+  if (InternalIsDecimalDigitCharacter (Char)) {

+    return Char - '0';

+  }

+

+  return (UINTN) (10 + InternalBaseLibAsciiToUpper (Char) - 'A');

+}

+

+

+/**

+  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   A pointer to a Null-terminated ASCII string.

+  @param  SecondString  A 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

+  )

+{

+  CHAR8  UpperFirstString;

+  CHAR8  UpperSecondString;

+

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  UpperFirstString  = InternalBaseLibAsciiToUpper (*FirstString);

+  UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);

+  while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {

+    FirstString++;

+    SecondString++;

+    UpperFirstString  = InternalBaseLibAsciiToUpper (*FirstString);

+    UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);

+  }

+

+  return UpperFirstString - UpperSecondString;

+}

+

+/**

+  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   A pointer to a Null-terminated ASCII string.

+  @param  SecondString  A 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

+  )

+{

+  if (Length == 0) {

+    return 0;

+  }

+

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (FirstString));

+  ASSERT (AsciiStrSize (SecondString));

+

+  if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {

+    ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));

+  }

+

+  while ((*FirstString != '\0') &&

+         (*FirstString == *SecondString) &&

+         (Length > 1)) {

+    FirstString++;

+    SecondString++;

+    Length--;

+  }

+  return *FirstString - *SecondString;

+}

+

+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated ASCII string.

+  @param  Source      A pointer to a Null-terminated ASCII string.

+

+  @return Destination

+

+**/

+CHAR8 *

+EFIAPI

+AsciiStrCat (

+  IN OUT CHAR8    *Destination,

+  IN CONST CHAR8  *Source

+  )

+{

+  AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (AsciiStrSize (Destination) != 0);

+  return Destination;

+}

+

+/**

+  [ATTENTION] This function will be 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 A pointer to a Null-terminated ASCII string.

+  @param  Source      A 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

+  )

+{

+  UINTN   DestinationLen;

+

+  DestinationLen = AsciiStrLen (Destination);

+  AsciiStrnCpy (Destination + DestinationLen, Source, Length);

+  Destination[DestinationLen + Length] = '\0';

+

+  //

+  // Size of the resulting string should never be zero.

+  // PcdMaximumUnicodeStringLength is tested inside StrLen().

+  //

+  ASSERT (AsciiStrSize (Destination) != 0);

+  return Destination;

+}

+#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          A pointer to a Null-terminated ASCII string.

+  @param  SearchString    A 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

+  )

+{

+  CONST CHAR8 *FirstMatch;

+  CONST CHAR8 *SearchStringTmp;

+

+  //

+  // ASSERT both strings are less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (String) != 0);

+  ASSERT (AsciiStrSize (SearchString) != 0);

+

+  if (*SearchString == '\0') {

+    return (CHAR8 *) String;

+  }

+

+  while (*String != '\0') {

+    SearchStringTmp = SearchString;

+    FirstMatch = String;

+    

+    while ((*String == *SearchStringTmp) 

+            && (*String != '\0')) {

+      String++;

+      SearchStringTmp++;

+    } 

+    

+    if (*SearchStringTmp == '\0') {

+      return (CHAR8 *) FirstMatch;

+    }

+

+    if (*String == '\0') {

+      return NULL;

+    }

+

+    String = FirstMatch + 1;

+  }

+

+  return NULL;

+}

+

+/**

+  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 ASSERT().

+  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          A pointer to a Null-terminated ASCII string.

+

+  @retval Value translated from String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrDecimalToUintn (

+  IN      CONST CHAR8               *String

+  )

+{

+  UINTN     Result;

+  

+  //

+  // ASSERT Strings is less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (String) != 0);

+

+  //

+  // Ignore the pad spaces (space or tab)

+  //

+  while ((*String == ' ') || (*String == '\t' )) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == '0') {

+    String++;

+  }

+

+  Result = 0;

+

+  while (InternalAsciiIsDecimalDigitCharacter (*String)) {

+    //

+    // If the number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= ((((UINTN) ~0) - (*String - L'0')) / 10));

+

+    Result = Result * 10 + (*String - '0');

+    String++;

+  }

+  

+  return Result;

+}

+

+

+/**

+  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 ASSERT().

+  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          A pointer to a Null-terminated ASCII string.

+

+  @retval Value translated from String.

+

+**/

+UINT64

+EFIAPI

+AsciiStrDecimalToUint64 (

+  IN      CONST CHAR8               *String

+  )

+{

+  UINT64     Result;

+  

+  //

+  // ASSERT Strings is less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (String) != 0);

+

+  //

+  // Ignore the pad spaces (space or tab)

+  //

+  while ((*String == ' ') || (*String == '\t' )) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == '0') {

+    String++;

+  }

+

+  Result = 0;

+

+  while (InternalAsciiIsDecimalDigitCharacter (*String)) {

+    //

+    // If the number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));

+

+    Result = MultU64x32 (Result, 10) + (*String - '0');

+    String++;

+  }

+  

+  return Result;

+}

+

+/**

+  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 ASSERT().

+  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          A pointer to a Null-terminated ASCII string.

+

+  @retval Value translated from String.

+

+**/

+UINTN

+EFIAPI

+AsciiStrHexToUintn (

+  IN      CONST CHAR8               *String

+  )

+{

+  UINTN     Result;

+

+  //

+  // ASSERT Strings is less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (String) != 0);

+  

+  //

+  // Ignore the pad spaces (space or tab) 

+  //

+  while ((*String == ' ') || (*String == '\t' )) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == '0') {

+    String++;

+  }

+

+  if (InternalBaseLibAsciiToUpper (*String) == 'X') {

+    ASSERT (*(String - 1) == '0');

+    if (*(String - 1) != '0') {

+      return 0;

+    }

+    //

+    // Skip the 'X'

+    //

+    String++;

+  }

+

+  Result = 0;

+  

+  while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {

+    //

+    // If the Hex Number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= ((((UINTN) ~0) - InternalHexCharToUintn (*String)) >> 4));

+

+    Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);

+    String++;

+  }

+

+  return Result;

+}

+

+

+/**

+  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 ASSERT().

+  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          A pointer to a Null-terminated ASCII string.

+

+  @retval Value translated from String.

+

+**/

+UINT64

+EFIAPI

+AsciiStrHexToUint64 (

+  IN      CONST CHAR8                *String

+  )

+{

+  UINT64    Result;

+

+  //

+  // ASSERT Strings is less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (String) != 0);

+  

+  //

+  // Ignore the pad spaces (space or tab) and leading Zeros

+  //

+  //

+  // Ignore the pad spaces (space or tab) 

+  //

+  while ((*String == ' ') || (*String == '\t' )) {

+    String++;

+  }

+

+  //

+  // Ignore leading Zeros after the spaces

+  //

+  while (*String == '0') {

+    String++;

+  }

+

+  if (InternalBaseLibAsciiToUpper (*String) == 'X') {

+    ASSERT (*(String - 1) == '0');

+    if (*(String - 1) != '0') {

+      return 0;

+    }

+    //

+    // Skip the 'X'

+    //

+    String++;

+  }

+

+  Result = 0;

+  

+  while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {

+    //

+    // If the Hex Number represented by String overflows according 

+    // to the range defined by UINTN, then ASSERT().

+    //

+    ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));

+

+    Result = LShiftU64 (Result, 4);

+    Result = Result + InternalAsciiHexCharToUintn (*String);

+    String++;

+  }

+

+  return Result;

+}

+

+

+/**

+  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        A pointer to a Null-terminated ASCII string.

+  @param  Destination   A pointer to a Null-terminated Unicode string.

+

+  @return Destination.

+

+**/

+CHAR16 *

+EFIAPI

+AsciiStrToUnicodeStr (

+  IN      CONST CHAR8               *Source,

+  OUT     CHAR16                    *Destination

+  )

+{

+  CHAR16                            *ReturnValue;

+

+  ASSERT (Destination != NULL);

+

+  //

+  // ASSERT Source is less long than PcdMaximumAsciiStringLength

+  //

+  ASSERT (AsciiStrSize (Source) != 0);

+

+  //

+  // Source and Destination should not overlap

+  //

+  ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));

+  ASSERT ((UINTN) (Source - (CHAR8 *) Destination) >= (AsciiStrSize (Source) * sizeof (CHAR16)));

+

+

+  ReturnValue = Destination;

+  while (*Source != '\0') {

+    *(Destination++) = (CHAR16) *(Source++);

+  }

+  //

+  // End the Destination with a NULL.

+  //

+  *Destination = '\0';

+

+  //

+  // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength

+  //

+  ASSERT (StrSize (ReturnValue) != 0);

+

+  return ReturnValue;

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Value < 100);

+  return (UINT8) (((Value / 10) << 4) | (Value % 10));

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Value < 0xa0);

+  ASSERT ((Value & 0xf) < 0xa);

+  return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes16.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes16.c
new file mode 100644
index 0000000..64a674a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes16.c
@@ -0,0 +1,39 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Switches the endianess 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

+  )

+{

+  return (UINT16) ((Value<< 8) | (Value>> 8));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes32.c
new file mode 100644
index 0000000..7e30d25
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes32.c
@@ -0,0 +1,45 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Switches the endianess 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

+  )

+{

+  UINT32  LowerBytes;

+  UINT32  HigherBytes;

+

+  LowerBytes  = (UINT32) SwapBytes16 ((UINT16) Value);

+  HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));

+

+  return (LowerBytes << 16 | HigherBytes);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes64.c
new file mode 100644
index 0000000..6a6ce83
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwapBytes64.c
@@ -0,0 +1,39 @@
+/** @file

+  Math worker functions.

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  Switches the endianess 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

+  )

+{

+  return InternalMathSwapBytes64 (Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwitchStack.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwitchStack.c
new file mode 100644
index 0000000..3681117
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/SwitchStack.c
@@ -0,0 +1,76 @@
+/** @file

+  Switch Stack functions.

+

+  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.

+

+**/

+

+#include "BaseLibInternals.h"

+

+/**

+  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.

+  IPF CPUs 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 IA32, x64, and EBC.  

+                      For IPF, 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,

+  ...

+  )

+{

+  VA_LIST    Marker;

+

+  ASSERT (EntryPoint != NULL);

+  ASSERT (NewStack != NULL);

+

+  //

+  // New stack must be aligned with CPU_STACK_ALIGNMENT

+  //

+  ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);

+

+  VA_START (Marker, NewStack);

+

+  InternalSwitchStack (EntryPoint, Context1, Context2, NewStack, Marker);

+

+  VA_END (Marker);

+

+  //

+  // InternalSwitchStack () will never return

+  //

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/Unaligned.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Unaligned.c
new file mode 100644
index 0000000..68dafa6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/Unaligned.c
@@ -0,0 +1,222 @@
+/** @file

+  Unaligned access functions of BaseLib.

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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  A 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *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  A 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer = 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  A 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer & 0xffffff;

+}

+

+/**

+  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  A 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  *Buffer = BitFieldWrite32 (*Buffer, 0, 23, Value);

+  return 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  A 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *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  A pointer to a 32-bit value that may be unaligned.

+  @param  Value   The 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer = 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  A 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *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  A pointer to a 64-bit value that may be unaligned.

+  @param  Value   The 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

+  )

+{

+  ASSERT (Buffer != NULL);

+

+  return *Buffer = Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.S
new file mode 100644
index 0000000..51cf9c0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.S
@@ -0,0 +1,25 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CpuBreakpoint.S

+#

+# Abstract:

+#

+#   Implementation of CpuBreakpoint() on x86_64

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(CpuBreakpoint)

+ASM_PFX(CpuBreakpoint):

+  int $0x3

+  ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.asm
new file mode 100644
index 0000000..25dd9b4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuBreakpoint.Asm

+;

+; Abstract:

+;

+;   CpuBreakpoint function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuBreakpoint (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuBreakpoint   PROC

+    int  3

+    ret

+CpuBreakpoint   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.c
new file mode 100644
index 0000000..d654f84
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuBreakpoint.c
@@ -0,0 +1,39 @@
+/** @file

+  CpuBreakpoint function.

+

+  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.

+

+**/

+

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+void __debugbreak ();

+

+#pragma intrinsic(__debugbreak)

+

+/**

+  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

+  )

+{

+  __debugbreak ();

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuId.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuId.S
new file mode 100644
index 0000000..c3d2597
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuId.S
@@ -0,0 +1,60 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CpuId.S

+#

+# Abstract:

+#

+#   AsmCpuid function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+#  VOID

+#  EFIAPI

+#  AsmCpuid (

+#    IN   UINT32  RegisterInEax,

+#    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmCpuid)

+ASM_PFX(AsmCpuid):

+    push    %rbx

+    mov     %ecx, %eax

+    push    %rax                         # save Index on stack

+    push    %rdx

+    cpuid

+    test    %r9, %r9

+    jz      L1

+    mov     %ecx, (%r9)

+L1:

+    pop     %rcx

+    jrcxz   L2

+    mov     %eax, (%rcx)

+L2:

+    mov     %r8, %rcx

+    jrcxz   L3

+    mov     %ebx, (%rcx)

+L3:

+    mov     0x38(%rsp), %rcx

+    jrcxz   L4

+    mov     %edx, (%rcx)

+L4:

+    pop     %rax                         # restore Index to rax as return value

+    pop     %rbx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuId.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuId.asm
new file mode 100644
index 0000000..c6182c1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuId.asm
@@ -0,0 +1,62 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CpuId.Asm

+;

+; Abstract:

+;

+;   AsmCpuid function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID

+;  EFIAPI

+;  AsmCpuid (

+;    IN   UINT32  RegisterInEax,

+;    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+;    )

+;------------------------------------------------------------------------------

+AsmCpuid    PROC    USES    rbx

+    mov     eax, ecx

+    push    rax                         ; save Index on stack

+    push    rdx

+    cpuid

+    test    r9, r9

+    jz      @F

+    mov     [r9], ecx

+@@:

+    pop     rcx

+    jrcxz   @F

+    mov     [rcx], eax

+@@:

+    mov     rcx, r8

+    jrcxz   @F

+    mov     [rcx], ebx

+@@:

+    mov     rcx, [rsp + 38h]

+    jrcxz   @F

+    mov     [rcx], edx

+@@:

+    pop     rax                         ; restore Index to rax as return value

+    ret

+AsmCpuid    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuIdEx.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuIdEx.S
new file mode 100644
index 0000000..d47f53c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuIdEx.S
@@ -0,0 +1,62 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CpuIdEx.S

+#

+# Abstract:

+#

+#   AsmCpuidEx function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+#  UINT32

+#  EFIAPI

+#  AsmCpuidEx (

+#    IN   UINT32  RegisterInEax,

+#    IN   UINT32  RegisterInEcx,

+#    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+#    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmCpuidEx)

+ASM_PFX(AsmCpuidEx):

+    push    %rbx

+    movl    %ecx,%eax

+    movl    %edx,%ecx

+    push    %rax                  # save Index on stack

+    cpuid

+    mov     0x38(%rsp), %r10

+    test    %r10, %r10

+    jz      L1

+    mov     %ecx,(%r10)

+L1: 

+    mov     %r8, %rcx

+    jrcxz   L2

+    movl    %eax,(%rcx)

+L2: 

+    mov     %r9, %rcx

+    jrcxz   L3

+    mov     %ebx, (%rcx)

+L3: 

+    mov     0x40(%rsp), %rcx

+    jrcxz   L4

+    mov     %edx, (%rcx)

+L4: 

+    pop     %rax                  # restore Index to rax as return value

+    pop     %rbx

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuIdEx.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuIdEx.asm
new file mode 100644
index 0000000..b41ba8e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuIdEx.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CpuIdEx.Asm

+;

+; Abstract:

+;

+;   AsmCpuidEx function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  UINT32

+;  EFIAPI

+;  AsmCpuidEx (

+;    IN   UINT32  RegisterInEax,

+;    IN   UINT32  RegisterInEcx,

+;    OUT  UINT32  *RegisterOutEax  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEbx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEcx  OPTIONAL,

+;    OUT  UINT32  *RegisterOutEdx  OPTIONAL

+;    )

+;------------------------------------------------------------------------------

+AsmCpuidEx  PROC    USES    rbx

+    mov     eax, ecx

+    mov     ecx, edx

+    push    rax                         ; save Index on stack

+    cpuid

+    mov     r10, [rsp + 38h]

+    test    r10, r10

+    jz      @F

+    mov     [r10], ecx

+@@:

+    mov     rcx, r8

+    jrcxz   @F

+    mov     [rcx], eax

+@@:

+    mov     rcx, r9

+    jrcxz   @F

+    mov     [rcx], ebx

+@@:

+    mov     rcx, [rsp + 40h]

+    jrcxz   @F

+    mov     [rcx], edx

+@@:

+    pop     rax                         ; restore Index to rax as return value

+    ret

+AsmCpuidEx  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuPause.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuPause.asm
new file mode 100644
index 0000000..a84465f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/CpuPause.asm
@@ -0,0 +1,37 @@
+;------------------------------------------------------------------------------ ;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CpuPause.Asm

+;

+; Abstract:

+;

+;   CpuPause function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; CpuPause (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+CpuPause    PROC

+    pause

+    ret

+CpuPause    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableCache.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableCache.S
new file mode 100644
index 0000000..970f2f3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableCache.S
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   DisableCache.S

+#

+# Abstract:

+#

+#   Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a

+#   WBINVD instruction.

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmDisableCache (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmDisableCache)

+ASM_PFX(AsmDisableCache):

+    movq    %cr0, %rax

+    btsq    $30, %rax

+    btrq    $29, %rax

+    movq    %rax, %cr0

+    wbinvd

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableCache.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableCache.asm
new file mode 100644
index 0000000..9fd5bd7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableCache.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   DisableCache.Asm

+;

+; Abstract:

+;

+;   Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a

+;   WBINVD instruction.

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmDisableCache (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmDisableCache PROC

+    mov     rax, cr0

+    bts     rax, 30

+    btr     rax, 29

+    mov     cr0, rax

+    wbinvd

+    ret

+AsmDisableCache ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableInterrupts.asm
new file mode 100644
index 0000000..4e54e0d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisableInterrupts.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   DisableInterrupts.Asm

+;

+; Abstract:

+;

+;   DisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; DisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+DisableInterrupts   PROC

+    cli

+    ret

+DisableInterrupts   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.S
new file mode 100644
index 0000000..676e9e1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.S
@@ -0,0 +1,82 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   DisablePaging64.S

+#

+# Abstract:

+#

+#   AsmDisablePaging64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+    

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalX86DisablePaging64 (

+#   IN      UINT16                    Cs,

+#   IN      UINT32                    EntryPoint,

+#   IN      UINT32                    Context1,  OPTIONAL

+#   IN      UINT32                    Context2,  OPTIONAL

+#   IN      UINT32                    NewStack

+#   );

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalX86DisablePaging64)

+ASM_PFX(InternalX86DisablePaging64):

+    cli    

+    lea    L1(%rip), %rsi                 # rsi <- The start address of transition code

+    mov    0x28(%rsp), %edi               # rdi <- New stack

+    lea    _mTransitionEnd(%rip), %rax    # rax <- end of transition code

+    sub    %rsi, %rax                     # rax <- The size of transition piece code

+    add    $4, %rax                       # round rax up to the next 4 byte boundary

+    and    $0xfc, %al

+    sub    %rax, %rdi                     # rdi <- use stack to hold transition code 

+    mov    %edi, %r10d                    # r10 <- The start address of transicition code below 4G

+    push   %rcx                           # save rcx to stack

+    mov    %rax, %rcx                     # rcx <- The size of transition piece code

+    rep

+    movsb                                 # copy transition code to (new stack - 64byte) below 4G

+    pop    %rcx                           # restore rcx

+   

+    mov    %r8d, %esi 

+    mov    %r9d, %edi 

+    mov    %r10d, %eax

+    sub    $4, %eax

+    push   %rcx                           # push Cs to stack

+    push   %r10                           # push address of transition code on stack  

+    .byte  0x48, 0xcb                     # retq: Use far return to load CS register from stack

+                                          # (Use raw byte code since some GNU assemblers generates incorrect code for "retq")  

+L1:

+    mov    %eax,%esp                      # set up new stack

+    mov    %cr0,%rax

+    btr    $0x1f,%eax                     # clear CR0.PG

+    mov    %rax,%cr0                      # disable paging

+

+    mov    %edx,%ebx                      # save EntryPoint to ebx, for rdmsr will overwrite edx

+    mov    $0xc0000080,%ecx

+    rdmsr  

+    and    $0xfe,%ah                      # clear LME

+    wrmsr  

+    mov    %cr4,%rax

+    and    $0xdf,%al                      # clear PAE

+    mov    %rax,%cr4

+    push   %rdi                           # push Context2

+    push   %rsi                           # push Context1

+    callq  *%rbx                          # transfer control to EntryPoint

+    jmp    .                              # no one should get here

+

+_mTransitionEnd :

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm
new file mode 100644
index 0000000..32dcd5a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm
@@ -0,0 +1,84 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   DisablePaging64.Asm

+;

+; Abstract:

+;

+;   AsmDisablePaging64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86DisablePaging64 (

+;   IN      UINT16                    Cs,

+;   IN      UINT32                    EntryPoint,

+;   IN      UINT32                    Context1,  OPTIONAL

+;   IN      UINT32                    Context2,  OPTIONAL

+;   IN      UINT32                    NewStack

+;   );

+;------------------------------------------------------------------------------

+InternalX86DisablePaging64    PROC

+    cli

+    lea     rsi, @F                     ; rsi <- The start address of transition code

+    mov     edi, [rsp + 28h]            ; rdi <- New stack

+    lea     rax, mTransitionEnd         ; rax <- end of transition code

+    sub     rax, rsi                    ; rax <- The size of transition piece code 

+    add     rax, 4                      ; Round RAX up to the next 4 byte boundary

+    and     al, 0fch

+    sub     rdi, rax                    ; rdi <- Use stack to hold transition code

+    mov     r10d, edi                   ; r10 <- The start address of transicition code below 4G

+    push    rcx                         ; save rcx to stack

+    mov     rcx, rax                    ; rcx <- The size of transition piece code

+    rep     movsb                       ; copy transition code to top of new stack which must be below 4GB

+    pop     rcx                         ; restore rcx

+    

+    mov     esi, r8d

+    mov     edi, r9d

+    mov     eax, r10d                   ; eax <- start of the transition code on the stack

+    sub     eax, 4                      ; eax <- One slot below transition code on the stack

+    push    rcx                         ; push Cs to stack

+    push    r10                         ; push address of tansition code on stack

+    DB      48h                         ; prefix to composite "retq" with next "retf"

+    retf                                ; Use far return to load CS register from stack

+

+; Start of transition code

+@@:

+    mov     esp, eax                    ; set up new stack

+    mov     rax, cr0

+    btr     eax, 31                     ; Clear CR0.PG

+    mov     cr0, rax                    ; disable paging and caches

+    

+    mov     ebx, edx                    ; save EntryPoint to rbx, for rdmsr will overwrite rdx

+    mov     ecx, 0c0000080h

+    rdmsr

+    and     ah, NOT 1                   ; clear LME

+    wrmsr

+    mov     rax, cr4

+    and     al, NOT (1 SHL 5)           ; clear PAE

+    mov     cr4, rax

+    push    rdi                         ; push Context2

+    push    rsi                         ; push Context1

+    call    rbx                         ; transfer control to EntryPoint

+    hlt                                 ; no one should get here

+InternalX86DisablePaging64    ENDP

+

+mTransitionEnd LABEL    BYTE

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableCache.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableCache.S
new file mode 100644
index 0000000..9d73960
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableCache.S
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   EnableCache.S

+#

+# Abstract:

+#

+#   Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear 

+#   the NW bit of CR0 to 0

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmEnableCache (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmEnableCache)

+ASM_PFX(AsmEnableCache):

+    wbinvd

+    movq    %cr0, %rax

+    btrq    $30, %rax

+    btrq    $29, %rax

+    movq    %rax, %cr0

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableCache.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableCache.asm
new file mode 100644
index 0000000..88b71d7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableCache.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   EnableCache.Asm

+;

+; Abstract:

+;

+;  Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear 

+;  the NW bit of CR0 to 0

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmEnableCache (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmEnableCache PROC

+    wbinvd

+    mov     rax, cr0

+    btr     rax, 29

+    btr     rax, 30

+    mov     cr0, rax

+    ret

+AsmEnableCache ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.S
new file mode 100644
index 0000000..f2ff61e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.S
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   EnableDisableInterrupts.S

+#

+# Abstract:

+#

+#   EnableDisableInterrupts function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# EnableDisableInterrupts (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(EnableDisableInterrupts)

+ASM_PFX(EnableDisableInterrupts):

+    sti

+    cli

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.asm
new file mode 100644
index 0000000..f6b2d9c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableDisableInterrupts.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   EnableDisableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableDisableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableDisableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+EnableDisableInterrupts PROC

+    sti

+    cli

+    ret

+EnableDisableInterrupts ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableInterrupts.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableInterrupts.asm
new file mode 100644
index 0000000..e776c27
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/EnableInterrupts.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   EnableInterrupts.Asm

+;

+; Abstract:

+;

+;   EnableInterrupts function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; EnableInterrupts (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+EnableInterrupts    PROC

+    sti

+    ret

+EnableInterrupts    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FlushCacheLine.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FlushCacheLine.asm
new file mode 100644
index 0000000..e30f9a9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FlushCacheLine.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   FlushCacheLine.Asm

+;

+; Abstract:

+;

+;   AsmFlushCacheLine function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID *

+; EFIAPI 

+; AsmFlushCacheLine (

+;   IN      VOID                      *LinearAddress

+;   );

+;------------------------------------------------------------------------------

+AsmFlushCacheLine   PROC

+    clflush [rcx]

+    mov     rax, rcx

+    ret

+AsmFlushCacheLine   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FxRestore.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FxRestore.asm
new file mode 100644
index 0000000..8496331
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FxRestore.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   FxRestore.Asm

+;

+; Abstract:

+;

+;   AsmFxRestore function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86FxRestore (

+;   IN CONST IA32_FX_BUFFER *Buffer

+;   );

+;------------------------------------------------------------------------------

+InternalX86FxRestore  PROC

+    fxrstor [rcx]

+    ret

+InternalX86FxRestore  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FxSave.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FxSave.asm
new file mode 100644
index 0000000..d41e935
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/FxSave.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   FxSave.Asm

+;

+; Abstract:

+;

+;   AsmFxSave function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86FxSave (

+;   OUT IA32_FX_BUFFER *Buffer

+;   );

+;------------------------------------------------------------------------------

+InternalX86FxSave PROC

+    fxsave  [rcx]

+    ret

+InternalX86FxSave ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/GccInline.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/GccInline.c
new file mode 100644
index 0000000..3d175ee
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/GccInline.c
@@ -0,0 +1,1806 @@
+/** @file

+  GCC inline implementation of BaseLib processor specific functions.

+  

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+

+

+/**

+  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

+  )

+{

+  // This is a little bit of overkill and it is more about the compiler that it is

+  // actually processor synchronization. This is like the _ReadWriteBarrier 

+  // Microsoft specific intrinsic

+  __asm__ __volatile__ ("":::"memory");

+}

+

+

+/**

+  Enables CPU interrupts.

+

+  Enables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+EnableInterrupts (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("sti"::: "memory");

+}

+

+

+/**

+  Disables CPU interrupts.

+

+  Disables CPU interrupts.

+

+**/

+VOID

+EFIAPI

+DisableInterrupts (

+  VOID

+  )

+{  

+  __asm__ __volatile__ ("cli"::: "memory");

+}

+

+

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ ("pause");

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ ("int $3");

+}

+

+

+

+/**

+  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

+  )

+{

+  UINT32 LowData;

+  UINT32 HighData;

+  

+  __asm__ __volatile__ (

+    "rdmsr"

+    : "=a" (LowData),   // %0

+      "=d" (HighData)   // %1

+    : "c"  (Index)      // %2

+    );

+    

+  return (((UINT64)HighData) << 32) | LowData;

+}

+

+/**

+  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

+  )

+{

+  UINT32 LowData;

+  UINT32 HighData;

+

+  LowData  = (UINT32)(Value);

+  HighData = (UINT32)(Value >> 32);

+  

+  __asm__ __volatile__ (

+    "wrmsr"

+    :

+    : "c" (Index),

+      "a" (LowData),

+      "d" (HighData)

+    );

+    

+  return Value;

+}

+

+

+

+/**

+  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

+  )

+{

+  UINTN Eflags;

+  

+  __asm__ __volatile__ (

+    "pushfq         \n\t"

+    "pop     %0         "

+    : "=r" (Eflags)       // %0

+    );

+    

+  return Eflags;

+}

+

+

+

+/**

+  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

+  )

+{

+  UINTN   Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%cr0,%0" 

+    : "=r" (Data)           // %0

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%cr2,  %0" 

+    : "=r" (Data)           // %0

+    );

+  

+  return Data;

+}

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%cr3,  %0" 

+    : "=r" (Data)           // %0

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%cr4,  %0" 

+    : "=r" (Data)           // %0

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%cr0"

+    :

+    : "r" (Cr0)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%cr2"

+    :

+    : "r" (Cr2)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%cr3"

+    :

+    : "r" (Cr3)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%cr4"

+    :

+    : "r" (Cr4)

+    );

+  return 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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr0, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr1, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr2, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr3, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr4, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr5, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr6, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINTN Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%dr7, %0"

+    : "=r" (Data)

+    );

+  

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr0"

+    :

+    : "r" (Dr0)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr1"

+    :

+    : "r" (Dr1)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr2"

+    :

+    : "r" (Dr2)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr3"

+    :

+    : "r" (Dr3)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr4"

+    :

+    : "r" (Dr4)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr5"

+    :

+    : "r" (Dr5)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr6"

+    :

+    : "r" (Dr6)

+    );

+  return 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

+  )

+{

+  __asm__ __volatile__ (

+    "mov  %0, %%dr7"

+    :

+    : "r" (Dr7)

+    );

+  return 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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov   %%cs, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%ds, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%es, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%fs, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%gs, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "mov  %%ds, %0"

+    :"=a" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "str  %0"

+    : "=r" (Data)

+    );

+    

+  return Data;

+}

+

+

+/**

+  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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadGdtr (

+  OUT     IA32_DESCRIPTOR           *Gdtr

+  )

+{

+  __asm__ __volatile__ (

+    "sgdt %0"

+    : "=m" (*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.

+

+  @param  Gdtr  The pointer to a GDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteGdtr (

+  IN      CONST IA32_DESCRIPTOR     *Gdtr

+  )

+{

+  __asm__ __volatile__ (

+    "lgdt %0"

+    :

+    : "m" (*Gdtr)

+    );

+    

+}

+

+

+/**

+  Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Reads and returns the current IDTR descriptor and returns it in Idtr. This

+  function is only available on IA-32 and X64.

+

+  @param  Idtr  The pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86ReadIdtr (

+  OUT     IA32_DESCRIPTOR           *Idtr

+  )

+{

+  __asm__ __volatile__ (

+    "sidt  %0"

+    : "=m" (*Idtr)

+    );

+}

+

+

+/**

+  Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.

+

+  Writes the current IDTR descriptor and returns it in Idtr. This function is

+  only available on IA-32 and X64.

+

+  @param  Idtr  The pointer to a IDTR descriptor.

+

+**/

+VOID

+EFIAPI

+InternalX86WriteIdtr (

+  IN      CONST IA32_DESCRIPTOR     *Idtr

+  )

+{

+  __asm__ __volatile__ (

+    "lidt %0"

+    :

+    : "m" (*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

+  )

+{

+  UINT16  Data;

+  

+  __asm__ __volatile__ (

+    "sldt  %0"

+    : "=g" (Data)   // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  Writes the current Local Descriptor Table Register (GDTR) 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

+  )

+{

+  __asm__ __volatile__ (

+    "lldtw  %0"

+    :

+    : "g" (Ldtr)   // %0

+    );

+}

+

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxSave (

+  OUT     IA32_FX_BUFFER            *Buffer

+  )

+{

+  __asm__ __volatile__ (

+    "fxsave %0"

+    :

+    : "m" (*Buffer)  // %0

+    );    

+}

+

+

+/**

+  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.

+

+  @param  Buffer  The pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+InternalX86FxRestore (

+  IN      CONST IA32_FX_BUFFER      *Buffer

+  )

+{

+  __asm__ __volatile__ (

+    "fxrstor %0"

+    :

+    : "m" (*Buffer)  // %0

+    );

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd   %%mm0,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd   %%mm1,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd  %%mm2,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd  %%mm3,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd  %%mm4,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd  %%mm5,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd  %%mm6,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  UINT64  Data;

+

+  __asm__ __volatile__ (

+    "movd  %%mm7,  %0    \n\t"

+    : "=r"  (Data)       // %0

+    );

+    

+  return Data;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm0"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm1"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm2"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm3"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm4"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm5"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm6"  // %0

+    :  

+    : "m" (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

+  )

+{

+  __asm__ __volatile__ (

+    "movd  %0, %%mm7"  // %0

+    :  

+    : "m" (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

+  )

+{

+  UINT32  LowData;

+  UINT32  HiData;

+  

+  __asm__ __volatile__ (

+    "rdtsc"

+    : "=a" (LowData),

+      "=d" (HiData)

+    );

+  

+  return (((UINT64)HiData) << 32) | LowData;  

+}

+

+

+/**

+  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

+  )

+{

+  UINT32  LowData;

+  UINT32  HiData;

+  

+  __asm__ __volatile__ (

+    "rdpmc"

+    : "=a" (LowData),

+      "=d" (HiData)

+    : "c"  (Index)

+    );

+  

+  return (((UINT64)HiData) << 32) | LowData;  

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "monitor"

+    :

+    : "a" (Eax),

+      "c" (Ecx),

+      "d" (Edx)

+    );

+    

+  return Eax;

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "mwait"

+    : 

+    : "a"  (Eax),

+      "c"  (Ecx)

+    );

+    

+  return Eax;    

+}

+

+

+/**

+  Executes a WBINVD instruction.

+

+  Executes a WBINVD instruction. This function is only available on IA-32 and

+  X64.

+

+**/

+VOID

+EFIAPI

+AsmWbinvd (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("wbinvd":::"memory");

+}

+

+

+/**

+  Executes a INVD instruction.

+

+  Executes a INVD instruction. This function is only available on IA-32 and

+  X64.

+

+**/

+VOID

+EFIAPI

+AsmInvd (

+  VOID

+  )

+{

+  __asm__ __volatile__ ("invd":::"memory");

+    

+}

+

+

+/**

+  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

+  )

+{

+  __asm__ __volatile__ (

+    "clflush (%0)"

+    :

+    : "r" (LinearAddress) 

+    : "memory"

+    );

+    

+    return LinearAddress;

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Invd.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Invd.asm
new file mode 100644
index 0000000..ed6f95d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Invd.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Invd.Asm

+;

+; Abstract:

+;

+;   AsmInvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmInvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmInvd PROC

+    invd

+    ret

+AsmInvd ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/LongJump.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/LongJump.S
new file mode 100644
index 0000000..f20446f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/LongJump.S
@@ -0,0 +1,54 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   LongJump.S

+#

+# Abstract:

+#

+#   Implementation of _LongJump() on x64.

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# InternalLongJump (

+#   IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+#   IN      UINTN                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalLongJump)

+ASM_PFX(InternalLongJump):

+    mov     (%rcx), %rbx

+    mov     0x8(%rcx), %rsp

+    mov     0x10(%rcx), %rbp

+    mov     0x18(%rcx), %rdi

+    mov     0x20(%rcx), %rsi

+    mov     0x28(%rcx), %r12

+    mov     0x30(%rcx), %r13

+    mov     0x38(%rcx), %r14

+    mov     0x40(%rcx), %r15

+    # load non-volatile fp registers

+    ldmxcsr 0x50(%rcx)

+    movdqu  0x58(%rcx), %xmm6

+    movdqu  0x68(%rcx), %xmm7

+    movdqu  0x78(%rcx), %xmm8

+    movdqu  0x88(%rcx), %xmm9

+    movdqu  0x98(%rcx), %xmm10

+    movdqu  0xA8(%rcx), %xmm11

+    movdqu  0xB8(%rcx), %xmm12

+    movdqu  0xC8(%rcx), %xmm13

+    movdqu  0xD8(%rcx), %xmm14

+    movdqu  0xE8(%rcx), %xmm15  

+    mov     %rdx, %rax          # set return value

+    jmp     *0x48(%rcx)

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/LongJump.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/LongJump.asm
new file mode 100644
index 0000000..eaf32ea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/LongJump.asm
@@ -0,0 +1,58 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   LongJump.Asm

+;

+; Abstract:

+;

+;   Implementation of _LongJump() on x64.

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalLongJump (

+;   IN      BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer,

+;   IN      UINTN                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalLongJump    PROC

+    mov     rbx, [rcx]

+    mov     rsp, [rcx + 8]

+    mov     rbp, [rcx + 10h]

+    mov     rdi, [rcx + 18h]

+    mov     rsi, [rcx + 20h]

+    mov     r12, [rcx + 28h]

+    mov     r13, [rcx + 30h]

+    mov     r14, [rcx + 38h]

+    mov     r15, [rcx + 40h]

+    ; load non-volatile fp registers

+    ldmxcsr [rcx + 50h]

+    movdqu  xmm6,  [rcx + 58h]

+    movdqu  xmm7,  [rcx + 68h]

+    movdqu  xmm8,  [rcx + 78h]

+    movdqu  xmm9,  [rcx + 88h]

+    movdqu  xmm10, [rcx + 98h]

+    movdqu  xmm11, [rcx + 0A8h]

+    movdqu  xmm12, [rcx + 0B8h]

+    movdqu  xmm13, [rcx + 0C8h]

+    movdqu  xmm14, [rcx + 0D8h]

+    movdqu  xmm15, [rcx + 0E8h]

+    mov     rax, rdx               ; set return value

+    jmp     qword ptr [rcx + 48h]

+InternalLongJump    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Monitor.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Monitor.asm
new file mode 100644
index 0000000..8ae6e73
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Monitor.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Monitor.Asm

+;

+; Abstract:

+;

+;   AsmMonitor function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmMonitor (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx,

+;   IN      UINTN                     Edx

+;   );

+;------------------------------------------------------------------------------

+AsmMonitor  PROC

+    mov     eax, ecx

+    mov     ecx, edx

+    mov     edx, r8d

+    DB      0fh, 1, 0c8h                ; monitor

+    ret

+AsmMonitor  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Mwait.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Mwait.asm
new file mode 100644
index 0000000..02ec863
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Mwait.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Mwait.Asm

+;

+; Abstract:

+;

+;   AsmMwait function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmMwait (

+;   IN      UINTN                     Eax,

+;   IN      UINTN                     Ecx

+;   );

+;------------------------------------------------------------------------------

+AsmMwait    PROC

+    mov     eax, ecx

+    mov     ecx, edx

+    DB      0fh, 1, 0c9h                ; mwait

+    ret

+AsmMwait    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Non-existing.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Non-existing.c
new file mode 100644
index 0000000..5ceb64b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Non-existing.c
@@ -0,0 +1,153 @@
+/** @file

+  Non-existing BaseLib functions on x64

+

+  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.

+

+**/

+

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  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.

+

+  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

+InternalX86EnablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  //

+  // This function cannot work on x64 platform

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  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.

+

+  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

+InternalX86DisablePaging32 (

+  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,

+  IN      VOID                      *Context1,  OPTIONAL

+  IN      VOID                      *Context2,  OPTIONAL

+  IN      VOID                      *NewStack

+  )

+{

+  //

+  // This function cannot work on x64 platform

+  //

+  ASSERT (FALSE);

+}

+

+

+/**

+  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.

+

+  @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

+InternalX86EnablePaging64 (

+  IN      UINT16                    Cs,

+  IN      UINT64                    EntryPoint,

+  IN      UINT64                    Context1,  OPTIONAL

+  IN      UINT64                    Context2,  OPTIONAL

+  IN      UINT64                    NewStack

+  )

+{

+  //

+  // This function cannot work on x64 platform.

+  //

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr0.asm
new file mode 100644
index 0000000..c3ff5b0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr0.Asm

+;

+; Abstract:

+;

+;   AsmReadCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr0  PROC

+    mov     rax, cr0

+    ret

+AsmReadCr0  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr2.asm
new file mode 100644
index 0000000..f1473b9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr2.Asm

+;

+; Abstract:

+;

+;   AsmReadCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr2  PROC

+    mov     rax, cr2

+    ret

+AsmReadCr2  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr3.asm
new file mode 100644
index 0000000..432468e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr3.Asm

+;

+; Abstract:

+;

+;   AsmReadCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr3  PROC

+    mov     rax, cr3

+    ret

+AsmReadCr3  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr4.asm
new file mode 100644
index 0000000..17d4499
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCr4.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCr4.Asm

+;

+; Abstract:

+;

+;   AsmReadCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadCr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCr4  PROC

+    mov     rax, cr4

+    ret

+AsmReadCr4  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCs.asm
new file mode 100644
index 0000000..ac3040c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadCs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadCs.Asm

+;

+; Abstract:

+;

+;   AsmReadCs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadCs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadCs   PROC

+    mov     eax, cs

+    ret

+AsmReadCs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr0.asm
new file mode 100644
index 0000000..8ac85ad
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr0.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr0.Asm

+;

+; Abstract:

+;

+;   AsmReadDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr0  PROC

+    mov     rax, dr0

+    ret

+AsmReadDr0  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr1.asm
new file mode 100644
index 0000000..8b042e2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr1.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr1.Asm

+;

+; Abstract:

+;

+;   AsmReadDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr1  PROC

+    mov     rax, dr1

+    ret

+AsmReadDr1  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr2.asm
new file mode 100644
index 0000000..9361756
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr2.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr2.Asm

+;

+; Abstract:

+;

+;   AsmReadDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr2  PROC

+    mov     rax, dr2

+    ret

+AsmReadDr2  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr3.asm
new file mode 100644
index 0000000..a25fc9d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr3.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr3.Asm

+;

+; Abstract:

+;

+;   AsmReadDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr3  PROC

+    mov     rax, dr3

+    ret

+AsmReadDr3  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm
new file mode 100644
index 0000000..dc6c5e9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr4.Asm

+;

+; Abstract:

+;

+;   AsmReadDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr4  PROC

+    ;

+    ; There's no obvious reason to access this register, since it's aliased to

+    ; DR7 when DE=0 or an exception generated when DE=1

+    ;

+    DB      0fh, 21h, 0e0h

+    ret

+AsmReadDr4  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm
new file mode 100644
index 0000000..7e31352
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr5.Asm

+;

+; Abstract:

+;

+;   AsmReadDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr5  PROC

+    ;

+    ; There's no obvious reason to access this register, since it's aliased to

+    ; DR7 when DE=0 or an exception generated when DE=1

+    ;

+    DB      0fh, 21h, 0e8h

+    ret

+AsmReadDr5  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr6.asm
new file mode 100644
index 0000000..ee6b9ec
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr6.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr6.Asm

+;

+; Abstract:

+;

+;   AsmReadDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr6  PROC

+    mov     rax, dr6

+    ret

+AsmReadDr6  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr7.asm
new file mode 100644
index 0000000..7173057
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDr7.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDr7.Asm

+;

+; Abstract:

+;

+;   AsmReadDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadDr7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDr7  PROC

+    mov     rax, dr7

+    ret

+AsmReadDr7  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDs.asm
new file mode 100644
index 0000000..d67512c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadDs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadDs.Asm

+;

+; Abstract:

+;

+;   AsmReadDs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadDs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadDs   PROC

+    mov     eax, ds

+    ret

+AsmReadDs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadEflags.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadEflags.asm
new file mode 100644
index 0000000..b3ecc7c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadEflags.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadEflags.Asm

+;

+; Abstract:

+;

+;   AsmReadEflags function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmReadEflags (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadEflags   PROC

+    pushfq

+    pop     rax

+    ret

+AsmReadEflags   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadEs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadEs.asm
new file mode 100644
index 0000000..76cffdc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadEs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadEs.Asm

+;

+; Abstract:

+;

+;   AsmReadEs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadEs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadEs   PROC

+    mov     eax, es

+    ret

+AsmReadEs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadFs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadFs.asm
new file mode 100644
index 0000000..e91aa14
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadFs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadFs.Asm

+;

+; Abstract:

+;

+;   AsmReadFs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadFs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadFs   PROC

+    mov     eax, fs

+    ret

+AsmReadFs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadGdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadGdtr.asm
new file mode 100644
index 0000000..ebc60bd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadGdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadGdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86ReadGdtr (

+;   OUT IA32_DESCRIPTOR  *Gdtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86ReadGdtr   PROC

+    sgdt    fword ptr [rcx]

+    ret

+InternalX86ReadGdtr   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadGs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadGs.asm
new file mode 100644
index 0000000..f185c38
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadGs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadGs.Asm

+;

+; Abstract:

+;

+;   AsmReadGs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadGs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadGs   PROC

+    mov     eax, gs

+    ret

+AsmReadGs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadIdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadIdtr.asm
new file mode 100644
index 0000000..4d53feb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadIdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadIdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86ReadIdtr (

+;   OUT     IA32_DESCRIPTOR           *Idtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86ReadIdtr   PROC

+    sidt    fword ptr [rcx]

+    ret

+InternalX86ReadIdtr   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadLdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadLdtr.asm
new file mode 100644
index 0000000..dbe517e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadLdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadLdtr.Asm

+;

+; Abstract:

+;

+;   AsmReadLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadLdtr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadLdtr PROC

+    sldt    eax

+    ret

+AsmReadLdtr ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm
new file mode 100644
index 0000000..99212c7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm0.Asm

+;

+; Abstract:

+;

+;   AsmReadMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm0 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm0  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0c0h

+    ret

+AsmReadMm0  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm
new file mode 100644
index 0000000..7a9ae7c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm1.Asm

+;

+; Abstract:

+;

+;   AsmReadMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm1 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm1  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0c8h

+    ret

+AsmReadMm1  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm
new file mode 100644
index 0000000..337ac73
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm2.Asm

+;

+; Abstract:

+;

+;   AsmReadMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm2 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm2  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0d0h

+    ret

+AsmReadMm2  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm
new file mode 100644
index 0000000..266e29a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm3.Asm

+;

+; Abstract:

+;

+;   AsmReadMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm3 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm3  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0d8h

+    ret

+AsmReadMm3  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm
new file mode 100644
index 0000000..9cc7435
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm4.Asm

+;

+; Abstract:

+;

+;   AsmReadMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm4 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm4  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0e0h

+    ret

+AsmReadMm4  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm
new file mode 100644
index 0000000..b665225
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm5.Asm

+;

+; Abstract:

+;

+;   AsmReadMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm5 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm5  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0e8h

+    ret

+AsmReadMm5  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm
new file mode 100644
index 0000000..1e3ebc5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm6.Asm

+;

+; Abstract:

+;

+;   AsmReadMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm6 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm6  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0f0h

+    ret

+AsmReadMm6  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm
new file mode 100644
index 0000000..8228672
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMm7.Asm

+;

+; Abstract:

+;

+;   AsmReadMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMm7 (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadMm7  PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 7eh, 0f8h

+    ret

+AsmReadMm7  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.asm
new file mode 100644
index 0000000..878ed18
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadMsr64.Asm

+;

+; Abstract:

+;

+;   AsmReadMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadMsr64 (

+;   IN UINT32  Index

+;   );

+;------------------------------------------------------------------------------

+AsmReadMsr64    PROC

+    rdmsr                               ; edx & eax are zero extended

+    shl     rdx, 20h

+    or      rax, rdx

+    ret

+AsmReadMsr64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.c
new file mode 100644
index 0000000..343e924
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadMsr64.c
@@ -0,0 +1,39 @@
+/** @file

+  CpuBreakpoint function.

+

+  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.

+

+**/

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+unsigned __int64 __readmsr (int register);

+

+#pragma intrinsic(__readmsr)

+

+/**

+  Read data to MSR.

+

+  @param  Index                Register index of MSR.

+

+  @return Value read from MSR.

+

+**/

+UINT64

+EFIAPI

+AsmReadMsr64 (

+  IN UINT32  Index

+  )

+{

+  return __readmsr (Index);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadPmc.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadPmc.asm
new file mode 100644
index 0000000..1b74f67
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadPmc.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadPmc.Asm

+;

+; Abstract:

+;

+;   AsmReadPmc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadPmc (

+;   IN UINT32   PmcIndex

+;   );

+;------------------------------------------------------------------------------

+AsmReadPmc  PROC

+    rdpmc

+    shl     rdx, 20h

+    or      rax, rdx

+    ret

+AsmReadPmc  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadSs.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadSs.asm
new file mode 100644
index 0000000..8f308c4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadSs.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadSs.Asm

+;

+; Abstract:

+;

+;   AsmReadSs function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadSs (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadSs   PROC

+    mov     eax, ss

+    ret

+AsmReadSs   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadTr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadTr.asm
new file mode 100644
index 0000000..a114f53
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadTr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadTr.Asm

+;

+; Abstract:

+;

+;   AsmReadTr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT16

+; EFIAPI

+; AsmReadTr (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadTr   PROC

+    str     eax

+    ret

+AsmReadTr   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadTsc.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadTsc.asm
new file mode 100644
index 0000000..d792bfb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/ReadTsc.asm
@@ -0,0 +1,40 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ReadTsc.Asm

+;

+; Abstract:

+;

+;   AsmReadTsc function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmReadTsc (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmReadTsc  PROC

+    rdtsc

+    shl     rdx, 20h

+    or      rax, rdx

+    ret

+AsmReadTsc  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SetJump.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SetJump.S
new file mode 100644
index 0000000..ea9e225
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SetJump.S
@@ -0,0 +1,53 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetJump.S

+#

+# Abstract:

+#

+#   Implementation of SetJump() on x86_64

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(SetJump)

+ASM_PFX(SetJump):

+    push   %rcx

+    add    $0xffffffffffffffe0,%rsp

+    call   ASM_PFX(InternalAssertJumpBuffer)

+    add    $0x20,%rsp

+    pop    %rcx

+    pop    %rdx

+    mov    %rbx,(%rcx)

+    mov    %rsp,0x8(%rcx)

+    mov    %rbp,0x10(%rcx)

+    mov    %rdi,0x18(%rcx)

+    mov    %rsi,0x20(%rcx)

+    mov    %r12,0x28(%rcx)

+    mov    %r13,0x30(%rcx)

+    mov    %r14,0x38(%rcx)

+    mov    %r15,0x40(%rcx)

+    mov    %rdx,0x48(%rcx)

+    # save non-volatile fp registers

+    stmxcsr 0x50(%rcx)

+    movdqu  %xmm6, 0x58(%rcx) 

+    movdqu  %xmm7, 0x68(%rcx)

+    movdqu  %xmm8, 0x78(%rcx)

+    movdqu  %xmm9, 0x88(%rcx)

+    movdqu  %xmm10, 0x98(%rcx)

+    movdqu  %xmm11, 0xA8(%rcx)

+    movdqu  %xmm12, 0xB8(%rcx)

+    movdqu  %xmm13, 0xC8(%rcx)

+    movdqu  %xmm14, 0xD8(%rcx)

+    movdqu  %xmm15, 0xE8(%rcx)     

+    xor    %rax,%rax

+    jmpq   *%rdx

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SetJump.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SetJump.asm
new file mode 100644
index 0000000..efdbb9a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SetJump.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetJump.Asm

+;

+; Abstract:

+;

+;   Implementation of SetJump() on x64.

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+EXTERNDEF   InternalAssertJumpBuffer:PROC

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; SetJump (

+;   OUT     BASE_LIBRARY_JUMP_BUFFER  *JumpBuffer

+;   );

+;------------------------------------------------------------------------------

+SetJump     PROC

+    push    rcx

+    add     rsp, -20h

+    call    InternalAssertJumpBuffer

+    add     rsp, 20h

+    pop     rcx

+    pop     rdx

+    mov     [rcx], rbx

+    mov     [rcx + 8], rsp

+    mov     [rcx + 10h], rbp

+    mov     [rcx + 18h], rdi

+    mov     [rcx + 20h], rsi

+    mov     [rcx + 28h], r12

+    mov     [rcx + 30h], r13

+    mov     [rcx + 38h], r14

+    mov     [rcx + 40h], r15

+    mov     [rcx + 48h], rdx

+    ; save non-volatile fp registers

+    stmxcsr [rcx + 50h]

+    movdqu  [rcx + 58h], xmm6

+    movdqu  [rcx + 68h], xmm7

+    movdqu  [rcx + 78h], xmm8

+    movdqu  [rcx + 88h], xmm9

+    movdqu  [rcx + 98h], xmm10

+    movdqu  [rcx + 0A8h], xmm11

+    movdqu  [rcx + 0B8h], xmm12

+    movdqu  [rcx + 0C8h], xmm13

+    movdqu  [rcx + 0D8h], xmm14

+    movdqu  [rcx + 0E8h], xmm15

+    xor     rax, rax

+    jmp     rdx

+SetJump     ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S
new file mode 100644
index 0000000..dc8d80e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SwitchStack.S

+#

+# Abstract:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# Routine Description:

+#

+#   Routine for switching stacks with 2 parameters

+#

+# Arguments:

+#

+#   (rcx) EntryPoint    - Entry point with new stack.

+#   (rdx) Context1      - Parameter1 for entry point.

+#   (r8)  Context2      - Parameter2 for entry point.

+#   (r9)  NewStack      - The pointer to new stack.

+#

+# Returns:

+#

+#   None

+#

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalSwitchStack)

+ASM_PFX(InternalSwitchStack):

+	  pushq   %rbp            

+  	movq    %rsp, %rbp

+    

+    mov     %rcx, %rax  // Shift registers for new call

+    mov     %rdx, %rcx

+    mov     %r8, %rdx

+    #

+    # Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack,

+    # in case the callee wishes to spill them.

+    #

+    lea     -0x20(%r9), %rsp

+    pushq   $0        // stop gdb stack unwind

+    jmp     *%rax     // call EntryPoint ()

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SwitchStack.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SwitchStack.asm
new file mode 100644
index 0000000..0f802b0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/SwitchStack.asm
@@ -0,0 +1,51 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   SwitchStack.Asm

+;

+; Abstract:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; Routine Description:

+;

+;   Routine for switching stacks with 2 parameters

+;

+; Arguments:

+;

+;   (rcx) EntryPoint    - Entry point with new stack.

+;   (rdx) Context1      - Parameter1 for entry point.

+;   (r8)  Context2      - Parameter2 for entry point.

+;   (r9)  NewStack      - The pointer to new stack.

+;

+; Returns:

+;

+;   None

+;

+;------------------------------------------------------------------------------

+InternalSwitchStack PROC

+    mov     rax, rcx

+    mov     rcx, rdx

+    mov     rdx, r8

+    ;

+    ; Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack,

+    ; in case the callee wishes to spill them.

+    ;

+    lea     rsp, [r9 - 20h]

+    call    rax

+InternalSwitchStack ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.S
new file mode 100644
index 0000000..f592a28
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.S
@@ -0,0 +1,334 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   Thunk16.S

+#

+# Abstract:

+#

+#   Real mode thunk

+#

+#------------------------------------------------------------------------------

+

+#include <Library/BaseLib.h>

+

+ASM_GLOBAL ASM_PFX(m16Start)

+ASM_GLOBAL ASM_PFX(m16Size)

+ASM_GLOBAL ASM_PFX(mThunk16Attr)

+ASM_GLOBAL ASM_PFX(m16Gdt)

+ASM_GLOBAL ASM_PFX(m16GdtrBase)

+ASM_GLOBAL ASM_PFX(mTransition)

+ASM_GLOBAL ASM_PFX(InternalAsmThunk16)

+

+# define the structure of IA32_REGS

+.set  _EDI, 0       #size 4

+.set  _ESI, 4       #size 4

+.set  _EBP, 8       #size 4

+.set  _ESP, 12      #size 4

+.set  _EBX, 16      #size 4

+.set  _EDX, 20      #size 4

+.set  _ECX, 24      #size 4

+.set  _EAX, 28      #size 4

+.set  _DS,  32      #size 2

+.set  _ES,  34      #size 2

+.set  _FS,  36      #size 2

+.set  _GS,  38      #size 2

+.set  _EFLAGS, 40   #size 8

+.set  _EIP, 48      #size 4

+.set  _CS, 52       #size 2

+.set  _SS, 54       #size 2

+.set  IA32_REGS_SIZE, 56

+

+    .data

+    

+.set Lm16Size, ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)

+ASM_PFX(m16Size):         .word      Lm16Size

+.set  LmThunk16Attr, L_ThunkAttr - ASM_PFX(m16Start)

+ASM_PFX(mThunk16Attr):    .word      LmThunk16Attr

+.set Lm16Gdt, ASM_PFX(NullSeg) - ASM_PFX(m16Start)

+ASM_PFX(m16Gdt):          .word      Lm16Gdt

+.set Lm16GdtrBase, _16GdtrBase - ASM_PFX(m16Start)

+ASM_PFX(m16GdtrBase):     .word      Lm16GdtrBase

+.set LmTransition, _EntryPoint - ASM_PFX(m16Start)

+ASM_PFX(mTransition):     .word      LmTransition

+

+    .text

+

+ASM_PFX(m16Start):

+

+SavedGdt:    .space 10

+

+#------------------------------------------------------------------------------

+# _BackFromUserCode() takes control in real mode after 'retf' has been executed

+# by user code. It will be shadowed to somewhere in memory below 1MB.

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(BackFromUserCode)

+ASM_PFX(BackFromUserCode):

+    #

+    # The order of saved registers on the stack matches the order they appears

+    # in IA32_REGS structure. This facilitates wrapper function to extract them

+    # into that structure.

+    #

+    # Some instructions for manipulation of segment registers have to be written

+    # in opcode since 64-bit MASM prevents accesses to those registers.

+    #

+    .byte 0x16                          # push ss

+    .byte 0xe                           # push cs

+    .byte 0x66

+    call    L_Base                       # push eip

+L_Base: 

+    .byte 0x66

+    pushq   $0                          # reserved high order 32 bits of EFlags

+    .byte 0x66, 0x9c                    # pushfd actually

+    cli                                 # disable interrupts

+    push    %gs

+    push    %fs

+    .byte 6                             # push es

+    .byte 0x1e                          # push ds

+    .byte 0x66,0x60                     # pushad

+    .byte 0x66,0xba                     # mov edx, imm32

+L_ThunkAttr:  .space  4

+    testb   $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl

+    jz      L_1

+    movl    $0x15cd2401,%eax            # mov ax, 2401h & int 15h

+    cli                                 # disable interrupts

+    jnc     L_2

+L_1: 

+    testb   $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl

+    jz      L_2

+    inb     $0x92,%al

+    orb     $2,%al

+    outb    %al, $0x92                   # deactivate A20M#

+L_2: 

+    xorw    %ax, %ax                     # xor eax, eax

+    movl    %ss, %eax                    # mov ax, ss

+    lea     IA32_REGS_SIZE(%esp), %bp

+    #

+    # rsi in the following 2 instructions is indeed bp in 16-bit code

+    #

+    movw    %bp, (_ESP - IA32_REGS_SIZE)(%rsi)

+    .byte 0x66

+    movl    (_EIP - IA32_REGS_SIZE)(%rsi), %ebx

+    shlw    $4,%ax                      # shl eax, 4

+    addw    %ax,%bp                     # add ebp, eax

+    movw    %cs,%ax

+    shlw    $4,%ax

+    lea     (L_64BitCode - L_Base)(%ebx, %eax), %ax

+    .byte 0x66,0x2e,0x89,0x87           # mov cs:[bx + (L_64Eip - L_Base)], eax

+    .word   L_64Eip - L_Base

+    .byte 0x66,0xb8                     # mov eax, imm32

+L_SavedCr4: .space      4

+    movq    %rax, %cr4

+    #

+    # rdi in the instruction below is indeed bx in 16-bit code

+    #

+    .byte 0x66,0x2e                     # 2eh is "cs:" segment override

+    lgdt    (SavedGdt - L_Base)(%rdi)

+    .byte 0x66

+    movl    $0xc0000080,%ecx

+    rdmsr

+    orb     $1,%ah

+    wrmsr

+    .byte 0x66,0xb8                     # mov eax, imm32

+L_SavedCr0: .space      4

+    movq    %rax, %cr0

+    .byte 0x66,0xea                     # jmp far cs:L_64Bit

+L_64Eip:    .space      4

+L_SavedCs:  .space      2

+L_64BitCode:

+    .byte   0x90

+    .byte   0x48,0xbc                  # mov rsp, imm64

+L_SavedSp:  .space      8              # restore stack

+    nop

+    ret

+

+_EntryPoint: .long      ASM_PFX(ToUserCode) - ASM_PFX(m16Start)

+             .word      CODE16

+_16Gdtr:     .word      GDT_SIZE - 1

+_16GdtrBase: .quad      0

+_16Idtr:     .word      0x3ff

+             .long      0

+

+#------------------------------------------------------------------------------

+# _ToUserCode() takes control in real mode before passing control to user code.

+# It will be shadowed to somewhere in memory below 1MB.

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(ToUserCode)

+ASM_PFX(ToUserCode):

+    movl    %edx,%ss                    # set new segment selectors

+    movl    %edx,%ds

+    movl    %edx,%es

+    movl    %edx,%fs

+    movl    %edx,%gs

+    .byte 0x66

+    movl    $0xc0000080,%ecx

+    movq    %rax, %cr0

+    rdmsr

+    andb    $0xfe, %ah                  # $0b11111110

+    wrmsr

+    movq    %rbp, %cr4

+    movl    %esi,%ss                    # set up 16-bit stack segment

+    movw    %bx,%sp                     # set up 16-bit stack pointer

+    .byte 0x66                          # make the following call 32-bit

+    call    L_Base1                       # push eip

+L_Base1: 

+    popw    %bp                         # ebp <- address of L_Base1

+    pushq   (IA32_REGS_SIZE + 2)(%esp)

+    lea     0x0c(%rsi), %eax

+    pushq   %rax

+    lret                                # execution begins at next instruction

+L_RealMode: 

+    .byte 0x66,0x2e                     # CS and operand size override

+    lidt    (_16Idtr - L_Base1)(%rsi)

+    .byte 0x66,0x61                     # popad

+    .byte 0x1f                          # pop ds

+    .byte 0x7                           # pop es

+    .byte 0x0f, 0xa1                    # pop fs

+    .byte 0x0f, 0xa9                    # pop gs

+    .byte 0x66, 0x9d                    # popfd

+    leaw    4(%esp),%sp                 # skip high order 32 bits of EFlags

+    .byte 0x66                          # make the following retf 32-bit

+    lret                                # transfer control to user code

+

+.set  CODE16,  ASM_PFX(_16Code) - .

+.set  DATA16,  ASM_PFX(_16Data) - .

+.set  DATA32,  ASM_PFX(_32Data) - .

+

+ASM_PFX(NullSeg):   .quad      0

+ASM_PFX(_16Code):

+            .word -1

+            .word 0

+            .byte 0

+            .byte 0x9b

+            .byte 0x8f                  # 16-bit segment, 4GB limit

+            .byte 0

+ASM_PFX(_16Data):

+            .word -1

+            .word 0

+            .byte 0

+            .byte 0x93

+            .byte 0x8f                  # 16-bit segment, 4GB limit

+            .byte 0

+ASM_PFX(_32Data):

+            .word -1

+            .word 0

+            .byte 0

+            .byte 0x93

+            .byte 0xcf                  # 16-bit segment, 4GB limit

+            .byte 0

+

+.set  GDT_SIZE, . - ASM_PFX(NullSeg)

+

+#------------------------------------------------------------------------------

+# IA32_REGISTER_SET *

+# EFIAPI

+# InternalAsmThunk16 (

+#   IN      IA32_REGISTER_SET         *RegisterSet,

+#   IN OUT  VOID                      *Transition

+#   );

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalAsmThunk16)

+ASM_PFX(InternalAsmThunk16):

+    pushq   %rbp

+    pushq   %rbx

+    pushq   %rsi

+    pushq   %rdi

+    

+    movl    %ds, %ebx

+    pushq   %rbx      # Save ds segment register on the stack

+    movl    %es, %ebx

+    pushq   %rbx      # Save es segment register on the stack

+    movl    %ss, %ebx

+    pushq   %rbx      # Save ss segment register on the stack

+

+    .byte   0x0f, 0xa0                  #push   fs

+    .byte   0x0f, 0xa8                  #push   gs

+    movq    %rcx, %rsi

+    movzwl  _SS(%rsi), %r8d

+    movl    _ESP(%rsi), %edi

+    lea     -(IA32_REGS_SIZE + 4)(%edi), %rdi

+    imul    $16, %r8d, %eax 

+    movl    %edi,%ebx                   # ebx <- stack for 16-bit code

+    pushq   $(IA32_REGS_SIZE / 4)

+    addl    %eax,%edi                   # edi <- linear address of 16-bit stack

+    popq    %rcx

+    rep

+    movsl                               # copy RegSet

+    lea     (L_SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx

+    movl    %edx,%eax                   # eax <- transition code address

+    andl    $0xf,%edx

+    shll    $12,%eax                    # segment address in high order 16 bits

+    .set LBackFromUserCodeDelta, ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start) 

+    lea     (LBackFromUserCodeDelta)(%rdx), %ax

+    stosl                               # [edi] <- return address of user code

+    sgdt    0x60(%rsp)                  # save GDT stack in argument space

+    movzwq  0x60(%rsp), %r10            # r10 <- GDT limit 

+    lea     ((ASM_PFX(InternalAsmThunk16) - L_SavedCr4) + 0xf)(%rcx), %r11 

+    andq    $0xfffffffffffffff0, %r11   # r11 <- 16-byte aligned shadowed GDT table in real mode buffer      

+    

+    movw    %r10w, (SavedGdt - L_SavedCr4)(%rcx)       # save the limit of shadowed GDT table

+    movq    %r11, (SavedGdt - L_SavedCr4 + 0x2)(%rcx)  # save the base address of shadowed GDT table

+    

+    movq    0x62(%rsp) ,%rsi            # rsi <- the original GDT base address

+    xchg   %r10, %rcx                   # save rcx to r10 and initialize rcx to be the limit of GDT table 

+    incq   %rcx                         # rcx <- the size of memory to copy

+    xchg   %r11, %rdi                   # save rdi to r11 and initialize rdi to the base address of shadowed GDT table

+    rep

+    movsb                               # perform memory copy to shadow GDT table

+    movq   %r10, %rcx                   # restore the orignal rcx before memory copy

+    movq   %r11, %rdi                   # restore the original rdi before memory copy

+       

+    sidt    0x50(%rsp)

+    movq    %cr0, %rax

+    .set LSavedCrDelta, L_SavedCr0 - L_SavedCr4

+    movl    %eax, (LSavedCrDelta)(%rcx)

+    andl    $0x7ffffffe,%eax            # clear PE, PG bits

+    movq    %cr4, %rbp

+    movl    %ebp, (%rcx)                # save CR4 in SavedCr4

+    andl    $0xffffffcf,%ebp            # clear PAE, PSE bits

+    movl    %r8d, %esi                  # esi <- 16-bit stack segment

+    .byte      0x6a, DATA32

+    popq    %rdx

+    lgdt    (_16Gdtr - L_SavedCr4)(%rcx)

+    movl    %edx,%ss

+    pushfq

+    lea     -8(%rdx), %edx

+    lea     L_RetFromRealMode(%rip), %r8

+    pushq   %r8

+    movl    %cs, %r8d

+    movw    %r8w, (L_SavedCs - L_SavedCr4)(%rcx)

+    movq    %rsp, (L_SavedSp - L_SavedCr4)(%rcx)

+    .byte   0xff, 0x69                  #  jmp (_EntryPoint - L_SavedCr4)(%rcx)

+    .set    Ltemp1, _EntryPoint - L_SavedCr4

+    .byte   Ltemp1

+L_RetFromRealMode: 

+    popfq

+    lgdt    0x60(%rsp)                  # restore protected mode GDTR

+    lidt    0x50(%rsp)                  # restore protected mode IDTR

+    lea     -IA32_REGS_SIZE(%rbp), %eax

+    .byte 0x0f, 0xa9                    # pop gs

+    .byte 0x0f, 0xa1                    # pop fs

+    

+    popq     %rbx

+    movl     %ebx, %ss

+    popq     %rbx

+    movl     %ebx, %es

+    popq     %rbx

+    movl     %ebx, %ds

+    

+    popq    %rdi

+    popq    %rsi

+    popq    %rbx

+    popq    %rbp

+

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm
new file mode 100644
index 0000000..e01de27
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm
@@ -0,0 +1,315 @@
+

+#include "BaseLibInternals.h"

+

+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   Thunk.asm

+;

+; Abstract:

+;

+;   Real mode thunk

+;

+;------------------------------------------------------------------------------

+

+EXTERNDEF   m16Start:BYTE

+EXTERNDEF   m16Size:WORD

+EXTERNDEF   mThunk16Attr:WORD

+EXTERNDEF   m16Gdt:WORD

+EXTERNDEF   m16GdtrBase:WORD

+EXTERNDEF   mTransition:WORD

+

+IA32_REGS   STRUC   4t

+_EDI        DD      ?

+_ESI        DD      ?

+_EBP        DD      ?

+_ESP        DD      ?

+_EBX        DD      ?

+_EDX        DD      ?

+_ECX        DD      ?

+_EAX        DD      ?

+_DS         DW      ?

+_ES         DW      ?

+_FS         DW      ?

+_GS         DW      ?

+_EFLAGS     DQ      ?

+_EIP        DD      ?

+_CS         DW      ?

+_SS         DW      ?

+IA32_REGS   ENDS

+

+    .const

+

+m16Size         DW      InternalAsmThunk16 - m16Start

+mThunk16Attr    DW      _ThunkAttr - m16Start

+m16Gdt          DW      _NullSeg - m16Start

+m16GdtrBase     DW      _16GdtrBase - m16Start

+mTransition     DW      _EntryPoint - m16Start

+

+    .code

+

+m16Start    LABEL   BYTE

+

+SavedGdt    LABEL   FWORD

+            DW      ?

+            DQ      ?

+

+;------------------------------------------------------------------------------

+; _BackFromUserCode() takes control in real mode after 'retf' has been executed

+; by user code. It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_BackFromUserCode   PROC

+    ;

+    ; The order of saved registers on the stack matches the order they appears

+    ; in IA32_REGS structure. This facilitates wrapper function to extract them

+    ; into that structure.

+    ;

+    ; Some instructions for manipulation of segment registers have to be written

+    ; in opcode since 64-bit MASM prevents accesses to those registers.

+    ;

+    DB      16h                         ; push ss

+    DB      0eh                         ; push cs

+    DB      66h

+    call    @Base                       ; push eip

+@Base:

+    DB      66h

+    push    0                           ; reserved high order 32 bits of EFlags

+    pushf                               ; pushfd actually

+    cli                                 ; disable interrupts

+    push    gs

+    push    fs

+    DB      6                           ; push es

+    DB      1eh                         ; push ds

+    DB      66h, 60h                    ; pushad

+    DB      66h, 0bah                   ; mov edx, imm32

+_ThunkAttr  DD      ?

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15

+    jz      @1

+    mov     eax, 15cd2401h              ; mov ax, 2401h & int 15h

+    cli                                 ; disable interrupts

+    jnc     @2

+@1:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL

+    jz      @2

+    in      al, 92h

+    or      al, 2

+    out     92h, al                     ; deactivate A20M#

+@2:

+    xor     ax, ax                      ; xor eax, eax

+    mov     eax, ss                     ; mov ax, ss

+    lea     bp, [esp + sizeof (IA32_REGS)]

+    ;

+    ; rsi in the following 2 instructions is indeed bp in 16-bit code

+    ;

+    mov     word ptr (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._ESP, bp

+    DB      66h

+    mov     ebx, (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._EIP

+    shl     ax, 4                       ; shl eax, 4

+    add     bp, ax                      ; add ebp, eax

+    mov     ax, cs

+    shl     ax, 4

+    lea     ax, [eax + ebx + (@64BitCode - @Base)]

+    DB      66h, 2eh, 89h, 87h          ; mov cs:[bx + (@64Eip - @Base)], eax

+    DW      @64Eip - @Base

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr4    DD      ?

+    mov     cr4, rax

+    ;

+    ; rdi in the instruction below is indeed bx in 16-bit code

+    ;

+    DB      66h, 2eh                    ; 2eh is "cs:" segment override

+    lgdt    fword ptr [rdi + (SavedGdt - @Base)]

+    DB      66h

+    mov     ecx, 0c0000080h

+    rdmsr

+    or      ah, 1

+    wrmsr

+    DB      66h, 0b8h                   ; mov eax, imm32

+SavedCr0    DD      ?

+    mov     cr0, rax

+    DB      66h, 0eah                   ; jmp far cs:@64Bit

+@64Eip      DD      ?

+SavedCs     DW      ?

+@64BitCode:

+    db      090h 

+    db      048h, 0bch                 ; mov rsp, imm64

+SavedSp     DQ   ?                     ; restore stack

+    nop

+    ret

+_BackFromUserCode   ENDP

+

+_EntryPoint DD      _ToUserCode - m16Start

+            DW      CODE16

+_16Gdtr     LABEL   FWORD

+            DW      GDT_SIZE - 1

+_16GdtrBase DQ      _NullSeg

+_16Idtr     FWORD   (1 SHL 10) - 1

+

+;------------------------------------------------------------------------------

+; _ToUserCode() takes control in real mode before passing control to user code.

+; It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_ToUserCode PROC

+    mov     ss, edx                     ; set new segment selectors

+    mov     ds, edx

+    mov     es, edx

+    mov     fs, edx

+    mov     gs, edx

+    DB      66h

+    mov     ecx, 0c0000080h

+    mov     cr0, rax                    ; real mode starts at next instruction

+    rdmsr

+    and     ah, NOT 1

+    wrmsr

+    mov     cr4, rbp

+    mov     ss, esi                     ; set up 16-bit stack segment

+    mov     sp, bx                      ; set up 16-bit stack pointer

+    DB      66h                         ; make the following call 32-bit

+    call    @Base                       ; push eip

+@Base:

+    pop     bp                          ; ebp <- address of @Base

+    push    [esp + sizeof (IA32_REGS) + 2]

+    lea     eax, [rsi + (@RealMode - @Base)]    ; rsi is "bp" in 16-bit code

+    push    rax

+    retf                                ; execution begins at next instruction

+@RealMode:

+    DB      66h, 2eh                    ; CS and operand size override

+    lidt    fword ptr [rsi + (_16Idtr - @Base)]

+    DB      66h, 61h                    ; popad

+    DB      1fh                         ; pop ds

+    DB      07h                         ; pop es

+    pop     fs

+    pop     gs

+    popf                                ; popfd

+    lea     sp, [esp + 4]               ; skip high order 32 bits of EFlags

+    DB      66h                         ; make the following retf 32-bit

+    retf                                ; transfer control to user code

+_ToUserCode ENDP

+

+CODE16  = _16Code - $

+DATA16  = _16Data - $

+DATA32  = _32Data - $

+

+_NullSeg    DQ      0

+_16Code     LABEL   QWORD

+            DW      -1

+            DW      0

+            DB      0

+            DB      9bh

+            DB      8fh                 ; 16-bit segment, 4GB limit

+            DB      0

+_16Data     LABEL   QWORD

+            DW      -1

+            DW      0

+            DB      0

+            DB      93h

+            DB      8fh                 ; 16-bit segment, 4GB limit

+            DB      0

+_32Data     LABEL   QWORD

+            DW      -1

+            DW      0

+            DB      0

+            DB      93h

+            DB      0cfh                ; 16-bit segment, 4GB limit

+            DB      0

+

+GDT_SIZE = $ - _NullSeg

+

+;------------------------------------------------------------------------------

+; IA32_REGISTER_SET *

+; EFIAPI

+; InternalAsmThunk16 (

+;   IN      IA32_REGISTER_SET         *RegisterSet,

+;   IN OUT  VOID                      *Transition

+;   );

+;------------------------------------------------------------------------------

+InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi

+    mov     rbx, ds

+    push    rbx          ; Save ds segment register on the stack

+    mov     rbx, es

+    push    rbx          ; Save es segment register on the stack

+    mov     rbx, ss

+    push    rbx          ; Save ss segment register on the stack

+    

+    push    fs

+    push    gs

+    mov     rsi, rcx

+    movzx   r8d, (IA32_REGS ptr [rsi])._SS

+    mov     edi, (IA32_REGS ptr [rsi])._ESP

+    lea     rdi, [edi - (sizeof (IA32_REGS) + 4)]

+    imul    eax, r8d, 16                ; eax <- r8d(stack segment) * 16

+    mov     ebx, edi                    ; ebx <- stack for 16-bit code

+    push    sizeof (IA32_REGS) / 4

+    add     edi, eax                    ; edi <- linear address of 16-bit stack

+    pop     rcx

+    rep     movsd                       ; copy RegSet

+    lea     ecx, [rdx + (SavedCr4 - m16Start)]

+    mov     eax, edx                    ; eax <- transition code address

+    and     edx, 0fh

+    shl     eax, 12                     ; segment address in high order 16 bits

+    lea     ax, [rdx + (_BackFromUserCode - m16Start)]  ; offset address

+    stosd                               ; [edi] <- return address of user code

+  

+    sgdt    fword ptr [rsp + 60h]       ; save GDT stack in argument space

+    movzx   r10, word ptr [rsp + 60h]   ; r10 <- GDT limit 

+    lea     r11, [rcx + (InternalAsmThunk16 - SavedCr4) + 0xf]

+    and     r11, 0xfffffff0             ; r11 <- 16-byte aligned shadowed GDT table in real mode buffer

+    

+    mov     word ptr [rcx + (SavedGdt - SavedCr4)], r10w      ; save the limit of shadowed GDT table

+    mov     qword ptr [rcx + (SavedGdt - SavedCr4) + 2], r11  ; save the base address of shadowed GDT table

+    

+    mov     rsi, qword ptr [rsp + 62h]  ; rsi <- the original GDT base address

+    xchg    rcx, r10                    ; save rcx to r10 and initialize rcx to be the limit of GDT table

+    inc     rcx                         ; rcx <- the size of memory to copy

+    xchg    rdi, r11                    ; save rdi to r11 and initialize rdi to the base address of shadowed GDT table

+    rep     movsb                       ; perform memory copy to shadow GDT table

+    mov     rcx, r10                    ; restore the orignal rcx before memory copy

+    mov     rdi, r11                    ; restore the original rdi before memory copy

+    

+    sidt    fword ptr [rsp + 50h]       ; save IDT stack in argument space

+    mov     rax, cr0

+    mov     [rcx + (SavedCr0 - SavedCr4)], eax

+    and     eax, 7ffffffeh              ; clear PE, PG bits

+    mov     rbp, cr4

+    mov     [rcx], ebp                  ; save CR4 in SavedCr4

+    and     ebp, NOT 30h                ; clear PAE, PSE bits

+    mov     esi, r8d                    ; esi <- 16-bit stack segment

+    DB      6ah, DATA32                 ; push DATA32

+    pop     rdx                         ; rdx <- 32-bit data segment selector

+    lgdt    fword ptr [rcx + (_16Gdtr - SavedCr4)]

+    mov     ss, edx

+    pushfq

+    lea     edx, [rdx + DATA16 - DATA32]

+    lea     r8, @RetFromRealMode

+    push    r8

+    mov     r8d, cs

+    mov     [rcx + (SavedCs - SavedCr4)], r8w

+    mov     [rcx + (SavedSp - SavedCr4)], rsp

+    jmp     fword ptr [rcx + (_EntryPoint - SavedCr4)]

+@RetFromRealMode:

+    popfq

+    lgdt    fword ptr [rsp + 60h]       ; restore protected mode GDTR

+    lidt    fword ptr [rsp + 50h]       ; restore protected mode IDTR

+    lea     eax, [rbp - sizeof (IA32_REGS)]

+    pop     gs

+    pop     fs

+    pop     rbx

+    mov     ss, rbx

+    pop     rbx

+    mov     es, rbx

+    pop     rbx

+    mov     ds, rbx

+    ret

+InternalAsmThunk16  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.nasm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.nasm
new file mode 100644
index 0000000..cfa55d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Thunk16.nasm
@@ -0,0 +1,325 @@
+

+#include "BaseLibInternals.h"

+

+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   Thunk.asm

+;

+; Abstract:

+;

+;   Real mode thunk

+;

+;------------------------------------------------------------------------------

+

+global ASM_PFX(m16Size)

+global ASM_PFX(mThunk16Attr)

+global ASM_PFX(m16Gdt)

+global ASM_PFX(m16GdtrBase)

+global ASM_PFX(mTransition)

+global ASM_PFX(m16Start)

+

+struc IA32_REGS

+

+  ._EDI:       resd      1

+  ._ESI:       resd      1

+  ._EBP:       resd      1

+  ._ESP:       resd      1

+  ._EBX:       resd      1

+  ._EDX:       resd      1

+  ._ECX:       resd      1

+  ._EAX:       resd      1

+  ._DS:        resw      1

+  ._ES:        resw      1

+  ._FS:        resw      1

+  ._GS:        resw      1

+  ._EFLAGS:    resq      1

+  ._EIP:       resd      1

+  ._CS:        resw      1

+  ._SS:        resw      1

+  .size:

+

+endstruc

+

+SECTION .data

+

+;

+; These are global constant to convey information to C code.

+;

+ASM_PFX(m16Size)         DW      ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)

+ASM_PFX(mThunk16Attr)    DW      _BackFromUserCode.ThunkAttrEnd - 4 - ASM_PFX(m16Start)

+ASM_PFX(m16Gdt)          DW      _NullSeg - ASM_PFX(m16Start)

+ASM_PFX(m16GdtrBase)     DW      _16GdtrBase - ASM_PFX(m16Start)

+ASM_PFX(mTransition)     DW      _EntryPoint - ASM_PFX(m16Start)

+

+SECTION .text

+

+ASM_PFX(m16Start):

+

+SavedGdt:

+            dw  0

+            dq  0

+

+;------------------------------------------------------------------------------

+; _BackFromUserCode() takes control in real mode after 'retf' has been executed

+; by user code. It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_BackFromUserCode:

+    ;

+    ; The order of saved registers on the stack matches the order they appears

+    ; in IA32_REGS structure. This facilitates wrapper function to extract them

+    ; into that structure.

+    ;

+BITS    16

+    push    ss

+    push    cs

+    ;

+    ; Note: We can't use o32 on the next instruction because of a bug

+    ; in NASM 2.09.04 through 2.10rc1.

+    ;

+    call    dword .Base                 ; push eip

+.Base:

+    push    dword 0                     ; reserved high order 32 bits of EFlags

+    pushfd

+    cli                                 ; disable interrupts

+    push    gs

+    push    fs

+    push    es

+    push    ds

+    pushad

+    mov     edx, strict dword 0

+.ThunkAttrEnd:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15

+    jz      .1

+    mov     ax, 2401h

+    int     15h

+    cli                                 ; disable interrupts

+    jnc     .2

+.1:

+    test    dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL

+    jz      .2

+    in      al, 92h

+    or      al, 2

+    out     92h, al                     ; deactivate A20M#

+.2:

+    xor     eax, eax

+    mov     ax, ss

+    lea     ebp, [esp + IA32_REGS.size]

+    mov     [bp - IA32_REGS.size + IA32_REGS._ESP], ebp

+    mov     ebx, [bp - IA32_REGS.size + IA32_REGS._EIP]

+    shl     eax, 4                      ; shl eax, 4

+    add     ebp, eax                    ; add ebp, eax

+    mov     eax, cs

+    shl     eax, 4

+    lea     eax, [eax + ebx + (.X64JmpEnd - .Base)]

+    mov     [cs:bx + (.X64JmpEnd - 6 - .Base)], eax

+    mov     eax, strict dword 0

+.SavedCr4End:

+    mov     cr4, eax

+o32 lgdt [cs:bx + (SavedGdt - .Base)]

+    mov     ecx, 0c0000080h

+    rdmsr

+    or      ah, 1

+    wrmsr

+    mov     eax, strict dword 0

+.SavedCr0End:

+    mov     cr0, eax

+    jmp     0:strict dword 0

+.X64JmpEnd:

+BITS    64

+    nop

+    mov rsp, strict qword 0

+.SavedSpEnd:

+    nop

+    ret

+

+_EntryPoint:

+        DD      _ToUserCode - ASM_PFX(m16Start)

+        DW      CODE16

+_16Gdtr:

+        DW      GDT_SIZE - 1

+_16GdtrBase:

+        DQ      0

+_16Idtr:

+        DW      (1 << 10) - 1

+        DD      0

+

+;------------------------------------------------------------------------------

+; _ToUserCode() takes control in real mode before passing control to user code.

+; It will be shadowed to somewhere in memory below 1MB.

+;------------------------------------------------------------------------------

+_ToUserCode:

+BITS    16

+    mov     ss, dx                      ; set new segment selectors

+    mov     ds, dx

+    mov     es, dx

+    mov     fs, dx

+    mov     gs, dx

+    mov     ecx, 0c0000080h

+    mov     cr0, eax                    ; real mode starts at next instruction

+    rdmsr

+    and     ah, ~1

+    wrmsr

+    mov     cr4, ebp

+    mov     ss, si                      ; set up 16-bit stack segment

+    mov     esp, ebx                    ; set up 16-bit stack pointer

+    call    dword .Base                 ; push eip

+.Base:

+    pop     ebp                         ; ebp <- address of .Base

+    push    word [dword esp + IA32_REGS.size + 2]

+    lea     ax, [bp + (.RealMode - .Base)]

+    push    ax

+    retf                                ; execution begins at next instruction

+.RealMode:

+

+o32 lidt    [cs:bp + (_16Idtr - .Base)]

+

+    popad

+    pop     ds

+    pop     es

+    pop     fs

+    pop     gs

+    popfd

+    lea     esp, [esp + 4]        ; skip high order 32 bits of EFlags

+

+o32 retf                                ; transfer control to user code

+

+ALIGN   8

+

+CODE16  equ _16Code - $

+DATA16  equ _16Data - $

+DATA32  equ _32Data - $

+

+_NullSeg    DQ      0

+_16Code:

+            DW      -1

+            DW      0

+            DB      0

+            DB      9bh

+            DB      8fh                 ; 16-bit segment, 4GB limit

+            DB      0

+_16Data:

+            DW      -1

+            DW      0

+            DB      0

+            DB      93h

+            DB      8fh                 ; 16-bit segment, 4GB limit

+            DB      0

+_32Data:

+            DW      -1

+            DW      0

+            DB      0

+            DB      93h

+            DB      0cfh                ; 16-bit segment, 4GB limit

+            DB      0

+

+GDT_SIZE equ $ - _NullSeg

+

+;------------------------------------------------------------------------------

+; IA32_REGISTER_SET *

+; EFIAPI

+; InternalAsmThunk16 (

+;   IN      IA32_REGISTER_SET         *RegisterSet,

+;   IN OUT  VOID                      *Transition

+;   );

+;------------------------------------------------------------------------------

+global ASM_PFX(InternalAsmThunk16)

+ASM_PFX(InternalAsmThunk16):

+BITS    64

+    push    rbp

+    push    rbx

+    push    rsi

+    push    rdi

+    

+    mov     ebx, ds

+    push    rbx          ; Save ds segment register on the stack

+    mov     ebx, es

+    push    rbx          ; Save es segment register on the stack

+    mov     ebx, ss

+    push    rbx          ; Save ss segment register on the stack

+    

+    push    fs

+    push    gs

+    mov     rsi, rcx

+    movzx   r8d, word [rsi + IA32_REGS._SS]

+    mov     edi, [rsi + IA32_REGS._ESP]

+    lea     rdi, [edi - (IA32_REGS.size + 4)]

+    imul    eax, r8d, 16                ; eax <- r8d(stack segment) * 16

+    mov     ebx, edi                    ; ebx <- stack for 16-bit code

+    push    IA32_REGS.size / 4

+    add     edi, eax                    ; edi <- linear address of 16-bit stack

+    pop     rcx

+    rep     movsd                       ; copy RegSet

+    lea     ecx, [rdx + (_BackFromUserCode.SavedCr4End - ASM_PFX(m16Start))]

+    mov     eax, edx                    ; eax <- transition code address

+    and     edx, 0fh

+    shl     eax, 12                     ; segment address in high order 16 bits

+    lea     ax, [rdx + (_BackFromUserCode - ASM_PFX(m16Start))]  ; offset address

+    stosd                               ; [edi] <- return address of user code

+  

+    sgdt    [rsp + 60h]       ; save GDT stack in argument space

+    movzx   r10, word [rsp + 60h]   ; r10 <- GDT limit 

+    lea     r11, [rcx + (ASM_PFX(InternalAsmThunk16) - _BackFromUserCode.SavedCr4End) + 0xf]

+    and     r11, ~0xf            ; r11 <- 16-byte aligned shadowed GDT table in real mode buffer

+    

+    mov     [rcx + (SavedGdt - _BackFromUserCode.SavedCr4End)], r10w      ; save the limit of shadowed GDT table

+    mov     [rcx + (SavedGdt - _BackFromUserCode.SavedCr4End) + 2], r11  ; save the base address of shadowed GDT table

+    

+    mov     rsi, [rsp + 62h]  ; rsi <- the original GDT base address

+    xchg    rcx, r10                    ; save rcx to r10 and initialize rcx to be the limit of GDT table

+    inc     rcx                         ; rcx <- the size of memory to copy

+    xchg    rdi, r11                    ; save rdi to r11 and initialize rdi to the base address of shadowed GDT table

+    rep     movsb                       ; perform memory copy to shadow GDT table

+    mov     rcx, r10                    ; restore the orignal rcx before memory copy

+    mov     rdi, r11                    ; restore the original rdi before memory copy

+    

+    sidt    [rsp + 50h]       ; save IDT stack in argument space

+    mov     rax, cr0

+    mov     [rcx + (_BackFromUserCode.SavedCr0End - 4 - _BackFromUserCode.SavedCr4End)], eax

+    and     eax, 7ffffffeh              ; clear PE, PG bits

+    mov     rbp, cr4

+    mov     [rcx - 4], ebp              ; save CR4 in _BackFromUserCode.SavedCr4End - 4

+    and     ebp, ~30h                ; clear PAE, PSE bits

+    mov     esi, r8d                    ; esi <- 16-bit stack segment

+    push    DATA32

+    pop     rdx                         ; rdx <- 32-bit data segment selector

+    lgdt    [rcx + (_16Gdtr - _BackFromUserCode.SavedCr4End)]

+    mov     ss, edx

+    pushfq

+    lea     edx, [rdx + DATA16 - DATA32]

+    lea     r8, [REL .RetFromRealMode]

+    push    r8

+    mov     r8d, cs

+    mov     [rcx + (_BackFromUserCode.X64JmpEnd - 2 - _BackFromUserCode.SavedCr4End)], r8w

+    mov     [rcx + (_BackFromUserCode.SavedSpEnd - 8 - _BackFromUserCode.SavedCr4End)], rsp

+    jmp     dword far [rcx + (_EntryPoint - _BackFromUserCode.SavedCr4End)]

+.RetFromRealMode:

+    popfq

+    lgdt    [rsp + 60h]       ; restore protected mode GDTR

+    lidt    [rsp + 50h]       ; restore protected mode IDTR

+    lea     eax, [rbp - IA32_REGS.size]

+    pop     gs

+    pop     fs

+    pop     rbx

+    mov     ss, ebx

+    pop     rbx

+    mov     es, ebx

+    pop     rbx

+    mov     ds, ebx

+

+    pop     rdi

+    pop     rsi

+    pop     rbx

+    pop     rbp

+

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Wbinvd.S b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Wbinvd.S
new file mode 100644
index 0000000..52702d5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Wbinvd.S
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   Wbinvd.S

+#

+# Abstract:

+#

+#   AsmWbinvd function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# VOID

+# EFIAPI

+# AsmWbinvd (

+#   VOID

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(AsmWbinvd)

+ASM_PFX(AsmWbinvd):

+    wbinvd

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Wbinvd.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Wbinvd.asm
new file mode 100644
index 0000000..b0807e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/Wbinvd.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   Wbinvd.Asm

+;

+; Abstract:

+;

+;   AsmWbinvd function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWbinvd (

+;   VOID

+;   );

+;------------------------------------------------------------------------------

+AsmWbinvd   PROC

+    wbinvd

+    ret

+AsmWbinvd   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr0.asm
new file mode 100644
index 0000000..98fef9c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr0.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr0 (

+;   UINTN  Cr0

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr0 PROC

+    mov     cr0, rcx

+    mov     rax, rcx

+    ret

+AsmWriteCr0 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr2.asm
new file mode 100644
index 0000000..3d77d6a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr2.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr2 (

+;   UINTN  Cr2

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr2 PROC

+    mov     cr2, rcx

+    mov     rax, rcx

+    ret

+AsmWriteCr2 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr3.asm
new file mode 100644
index 0000000..9b39938
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr3.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr3 (

+;   UINTN  Cr3

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr3 PROC

+    mov     cr3, rcx

+    mov     rax, rcx

+    ret

+AsmWriteCr3 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr4.asm
new file mode 100644
index 0000000..1455842
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteCr4.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteCr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteCr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteCr4 (

+;   UINTN  Cr4

+;   );

+;------------------------------------------------------------------------------

+AsmWriteCr4 PROC

+    mov     cr4, rcx

+    mov     rax, rcx

+    ret

+AsmWriteCr4 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr0.asm
new file mode 100644
index 0000000..dafe9ab
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr0.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr0.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr0 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr0 PROC

+    mov     dr0, rcx

+    mov     rax, rcx

+    ret

+AsmWriteDr0 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr1.asm
new file mode 100644
index 0000000..7167f5e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr1.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr1.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr1 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr1 PROC

+    mov     dr1, rcx

+    mov     rax, rcx

+    ret

+AsmWriteDr1 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr2.asm
new file mode 100644
index 0000000..c14ba34
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr2.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr2.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr2 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr2 PROC

+    mov     dr2, rcx

+    mov     rax, rcx

+    ret

+AsmWriteDr2 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr3.asm
new file mode 100644
index 0000000..8873916
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr3.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr3.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr3 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr3 PROC

+    mov     dr3, rcx

+    mov     rax, rcx

+    ret

+AsmWriteDr3 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm
new file mode 100644
index 0000000..4803525
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr4.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr4 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr4 PROC

+    ;

+    ; There's no obvious reason to access this register, since it's aliased to

+    ; DR6 when DE=0 or an exception generated when DE=1

+    ;

+    DB      0fh, 23h, 0e1h

+    mov     rax, rcx

+    ret

+AsmWriteDr4 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm
new file mode 100644
index 0000000..2cdb328
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   WriteDr5.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr5 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr5 PROC

+    ;

+    ; There's no obvious reason to access this register, since it's aliased to

+    ; DR7 when DE=0 or an exception generated when DE=1

+    ;

+    DB      0fh, 23h, 0e9h

+    mov     rax, rcx

+    ret

+AsmWriteDr5 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr6.asm
new file mode 100644
index 0000000..22c9c87
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr6.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr6.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr6 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr6 PROC

+    mov     dr6, rcx

+    mov     rax, rcx

+    ret

+AsmWriteDr6 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr7.asm
new file mode 100644
index 0000000..b55afd3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteDr7.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteDr7.Asm

+;

+; Abstract:

+;

+;   AsmWriteDr7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINTN

+; EFIAPI

+; AsmWriteDr7 (

+;   IN UINTN Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteDr7 PROC

+    mov     dr7, rcx

+    mov     rax, rcx

+    ret

+AsmWriteDr7 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteGdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteGdtr.asm
new file mode 100644
index 0000000..0cc8b7a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteGdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteGdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteGdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86WriteGdtr (

+;   IN      CONST IA32_DESCRIPTOR     *Idtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86WriteGdtr  PROC

+    lgdt    fword ptr [rcx]

+    ret

+InternalX86WriteGdtr  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteIdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteIdtr.asm
new file mode 100644
index 0000000..01ca1c0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteIdtr.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   WriteIdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteIdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; InternalX86WriteIdtr (

+;   IN      CONST IA32_DESCRIPTOR     *Idtr

+;   );

+;------------------------------------------------------------------------------

+InternalX86WriteIdtr  PROC

+    pushfq

+    cli

+    lidt    fword ptr [rcx]

+    popfq

+    ret

+InternalX86WriteIdtr  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteLdtr.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteLdtr.asm
new file mode 100644
index 0000000..af67863
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteLdtr.asm
@@ -0,0 +1,38 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteLdtr.Asm

+;

+; Abstract:

+;

+;   AsmWriteLdtr function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteLdtr (

+;   IN UINT16 Ldtr

+;   );

+;------------------------------------------------------------------------------

+AsmWriteLdtr    PROC

+    lldt    cx

+    ret

+AsmWriteLdtr    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm
new file mode 100644
index 0000000..f40db03
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm0.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm0 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm0 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm0 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0c1h

+    ret

+AsmWriteMm0 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm
new file mode 100644
index 0000000..ec17208
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm1.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm1 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm1 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm1 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0c9h

+    ret

+AsmWriteMm1 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm
new file mode 100644
index 0000000..38c0d5e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm2.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm2 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm2 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm2 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0d1h

+    ret

+AsmWriteMm2 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm
new file mode 100644
index 0000000..5f5bbdd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm3.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm3 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm3 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm3 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0d9h

+    ret

+AsmWriteMm3 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm
new file mode 100644
index 0000000..7f53313
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm4.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm4 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm4 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm4 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0e1h

+    ret

+AsmWriteMm4 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm
new file mode 100644
index 0000000..ea30bc1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm5.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm5 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm5 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm5 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0e9h

+    ret

+AsmWriteMm5 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm
new file mode 100644
index 0000000..aa926ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm6.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm6 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm6 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm6 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0f1h

+    ret

+AsmWriteMm6 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm
new file mode 100644
index 0000000..652e041
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMm7.Asm

+;

+; Abstract:

+;

+;   AsmWriteMm7 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; AsmWriteMm7 (

+;   IN UINT64   Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMm7 PROC

+    ;

+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here

+    ;

+    DB      48h, 0fh, 6eh, 0f9h

+    ret

+AsmWriteMm7 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm
new file mode 100644
index 0000000..19ef572
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   WriteMsr64.Asm

+;

+; Abstract:

+;

+;   AsmWriteMsr64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; AsmWriteMsr64 (

+;   IN UINT32  Index,

+;   IN UINT64  Value

+;   );

+;------------------------------------------------------------------------------

+AsmWriteMsr64   PROC

+    mov     rax, rdx                    ; meanwhile, rax <- return value

+    shr     rdx, 20h                    ; edx:eax contains the value to write

+    wrmsr

+    ret

+AsmWriteMsr64   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.c
new file mode 100644
index 0000000..58f0754
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.c
@@ -0,0 +1,42 @@
+/** @file

+  CpuBreakpoint function.

+

+  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.

+

+**/

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+void __writemsr (unsigned long Register, unsigned __int64 Value);

+

+#pragma intrinsic(__writemsr)

+

+/**

+  Write data to MSR.

+

+  @param  Index                The register index of MSR.

+  @param  Value                Data wants to be written.

+

+  @return Value written to MSR.

+

+**/

+UINT64

+EFIAPI

+AsmWriteMsr64 (

+  IN UINT32  Index,

+  IN UINT64  Value

+  )

+{

+  __writemsr (Index, Value);

+  return Value;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86DisablePaging32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86DisablePaging32.c
new file mode 100644
index 0000000..cf14c84
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86DisablePaging32.c
@@ -0,0 +1,66 @@
+/** @file

+  IA-32/x64 AsmDisablePaging32()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (EntryPoint != NULL);

+  ASSERT (NewStack != NULL);

+  InternalX86DisablePaging32 (EntryPoint, Context1, Context2, NewStack);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86DisablePaging64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86DisablePaging64.c
new file mode 100644
index 0000000..add86cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86DisablePaging64.c
@@ -0,0 +1,63 @@
+/** @file

+  IA-32/x64 AsmDisablePaging64()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (EntryPoint != 0);

+  ASSERT (NewStack != 0);

+  InternalX86DisablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86EnablePaging32.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86EnablePaging32.c
new file mode 100644
index 0000000..cb0ea29
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86EnablePaging32.c
@@ -0,0 +1,69 @@
+/** @file

+  IA-32/x64 AsmEnablePaging32()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (EntryPoint != NULL);

+  ASSERT (NewStack != NULL);

+  InternalX86EnablePaging32 (EntryPoint, Context1, Context2, NewStack);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86EnablePaging64.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86EnablePaging64.c
new file mode 100644
index 0000000..28f9f27
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86EnablePaging64.c
@@ -0,0 +1,65 @@
+/** @file

+  IA-32/x64 AsmEnablePaging64()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (EntryPoint != 0);

+  ASSERT (NewStack != 0);

+  InternalX86EnablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86FxRestore.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86FxRestore.c
new file mode 100644
index 0000000..b2a02fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86FxRestore.c
@@ -0,0 +1,49 @@
+/** @file

+  IA-32/x64 AsmFxRestore()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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  A pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+AsmFxRestore (

+  IN      CONST IA32_FX_BUFFER      *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (0 == ((UINTN)Buffer & 0xf));

+

+  //

+  // Check the flag recorded by AsmFxSave()

+  //

+  ASSERT (0xAA5555AA == *(UINT32 *) (&Buffer->Buffer[sizeof (Buffer->Buffer) - 4]));

+

+  InternalX86FxRestore (Buffer);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86FxSave.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86FxSave.c
new file mode 100644
index 0000000..0a40bcc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86FxSave.c
@@ -0,0 +1,48 @@
+/** @file

+  IA-32/x64 AsmFxSave()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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  A pointer to a buffer to save the floating point/SSE/SSE2 context.

+

+**/

+VOID

+EFIAPI

+AsmFxSave (

+  OUT     IA32_FX_BUFFER            *Buffer

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (0 == ((UINTN)Buffer & 0xf));

+

+  InternalX86FxSave (Buffer);

+

+  //

+  // Mark one flag at end of Buffer, it will be check by AsmFxRestor()

+  //

+  *(UINT32 *) (&Buffer->Buffer[sizeof (Buffer->Buffer) - 4]) = 0xAA5555AA;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86GetInterruptState.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86GetInterruptState.c
new file mode 100644
index 0000000..ed3f495
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86GetInterruptState.c
@@ -0,0 +1,41 @@
+/** @file

+  IA-32/x64 GetInterruptState()

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  Retrieves the current CPU interrupt state.

+

+  Returns TRUE is interrupts are currently enabled. Otherwise

+  returns FALSE.

+

+  @retval TRUE  CPU interrupts are enabled.

+  @retval FALSE CPU interrupts are disabled.

+

+**/

+BOOLEAN

+EFIAPI

+GetInterruptState (

+  VOID

+  )

+{

+  IA32_EFLAGS32                     EFlags;

+

+  EFlags.UintN = AsmReadEflags ();

+  return (BOOLEAN)(1 == EFlags.Bits.IF);

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86MemoryFence.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86MemoryFence.c
new file mode 100644
index 0000000..77e1c5a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86MemoryFence.c
@@ -0,0 +1,32 @@
+/** @file

+  IA-32/x64 MemoryFence().

+

+  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.

+

+**/

+

+

+

+

+/**

+  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

+  )

+{

+  return;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86Msr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86Msr.c
new file mode 100644
index 0000000..9430980
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86Msr.c
@@ -0,0 +1,660 @@
+/** @file

+  IA-32/x64 MSR functions.

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+

+/**

+  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

+  )

+{

+  return (UINT32)AsmReadMsr64 (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

+  )

+{

+  return (UINT32)AsmWriteMsr64 (Index, 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

+  )

+{

+  return (UINT32)AsmMsrOr64 (Index, 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

+  )

+{

+  return (UINT32)AsmMsrAnd64 (Index, 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

+  )

+{

+  return (UINT32)AsmMsrAndThenOr64 (Index, AndData, 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

+  )

+{

+  return BitFieldRead32 (AsmReadMsr32 (Index), StartBit, 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     The 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

+  )

+{

+  ASSERT (EndBit < sizeof (Value) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldWrite64 (Index, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < sizeof (OrData) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldOr64 (Index, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < sizeof (AndData) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldAnd64 (Index, StartBit, EndBit, 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

+  )

+{

+  ASSERT (EndBit < sizeof (AndData) * 8);

+  ASSERT (StartBit <= EndBit);

+  return (UINT32)AsmMsrBitFieldAndThenOr64 (

+                   Index,

+                   StartBit,

+                   EndBit,

+                   AndData,

+                   OrData

+                   );

+}

+

+/**

+  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

+  )

+{

+  return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) | 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

+  )

+{

+  return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) & 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

+  )

+{

+  return AsmWriteMsr64 (Index, (AsmReadMsr64 (Index) & AndData) | 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

+  )

+{

+  return BitFieldRead64 (AsmReadMsr64 (Index), StartBit, 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     The 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

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldWrite64 (AsmReadMsr64 (Index), StartBit, EndBit, 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

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldOr64 (AsmReadMsr64 (Index), StartBit, EndBit, 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

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldAnd64 (AsmReadMsr64 (Index), StartBit, EndBit, 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

+  )

+{

+  return AsmWriteMsr64 (

+           Index,

+           BitFieldAndThenOr64 (

+             AsmReadMsr64 (Index),

+             StartBit,

+             EndBit,

+             AndData,

+             OrData

+             )

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86ReadGdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86ReadGdtr.c
new file mode 100644
index 0000000..ecd2b80
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86ReadGdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  IA-32/x64 AsmReadGdtr()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Gdtr != NULL);

+  InternalX86ReadGdtr (Gdtr);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86ReadIdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86ReadIdtr.c
new file mode 100644
index 0000000..392b6e3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86ReadIdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  IA-32/x64 AsmReadIdtr()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Idtr != NULL);

+  InternalX86ReadIdtr (Idtr);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86Thunk.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86Thunk.c
new file mode 100644
index 0000000..dac1d19
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86Thunk.c
@@ -0,0 +1,268 @@
+/** @file

+  Real Mode Thunk Functions for IA32 and x64.

+

+  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.

+

+**/

+

+

+#include "BaseLibInternals.h"

+

+extern CONST UINT8                  m16Start;

+extern CONST UINT16                 m16Size;

+extern CONST UINT16                 mThunk16Attr;

+extern CONST UINT16                 m16Gdt;

+extern CONST UINT16                 m16GdtrBase;

+extern CONST UINT16                 mTransition;

+

+/**

+  Invokes 16-bit code in big real mode and returns the updated register set.

+

+  This function transfers control to the 16-bit code specified by CS:EIP using

+  the stack specified by SS:ESP in RegisterSet. The updated registers are saved

+  on the real mode stack and the starting address of the save area is returned.

+

+  @param  RegisterSet Values of registers before invocation of 16-bit code.

+  @param  Transition  The pointer to the transition code under 1MB.

+

+  @return The pointer to a IA32_REGISTER_SET structure containing the updated

+          register values.

+

+**/

+IA32_REGISTER_SET *

+EFIAPI

+InternalAsmThunk16 (

+  IN      IA32_REGISTER_SET         *RegisterSet,

+  IN OUT  VOID                      *Transition

+  );

+

+/**

+  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

+  )

+{

+  ASSERT (RealModeBufferSize != NULL);

+  ASSERT (ExtraStackSize != NULL);

+

+  *RealModeBufferSize = m16Size;

+

+  //

+  // Extra 4 bytes for return address, and another 4 bytes for mode transition

+  //

+  *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8;

+}

+

+/**

+  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

+  )

+{

+  IA32_SEGMENT_DESCRIPTOR           *RealModeGdt;

+

+  ASSERT (ThunkContext != NULL);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);

+  ASSERT (ThunkContext->RealModeBufferSize >= m16Size);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);

+

+  CopyMem (ThunkContext->RealModeBuffer, &m16Start, m16Size);

+

+  //

+  // Point RealModeGdt to the GDT to be used in transition

+  //

+  // RealModeGdt[0]: Reserved as NULL descriptor

+  // RealModeGdt[1]: Code Segment

+  // RealModeGdt[2]: Data Segment

+  // RealModeGdt[3]: Call Gate

+  //

+  RealModeGdt = (IA32_SEGMENT_DESCRIPTOR*)(

+                  (UINTN)ThunkContext->RealModeBuffer + m16Gdt);

+

+  //

+  // Update Code & Data Segment Descriptor

+  //

+  RealModeGdt[1].Bits.BaseLow =

+    (UINT32)(UINTN)ThunkContext->RealModeBuffer & ~0xf;

+  RealModeGdt[1].Bits.BaseMid =

+    (UINT32)(UINTN)ThunkContext->RealModeBuffer >> 16;

+

+  //

+  // Update transition code entry point offset

+  //

+  *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mTransition) +=

+    (UINT32)(UINTN)ThunkContext->RealModeBuffer & 0xf;

+

+  //

+  // Update Segment Limits for both Code and Data Segment Descriptors

+  //

+  if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) {

+    //

+    // Set segment limits to 64KB

+    //

+    RealModeGdt[1].Bits.LimitHigh = 0;

+    RealModeGdt[1].Bits.G = 0;

+    RealModeGdt[2].Bits.LimitHigh = 0;

+    RealModeGdt[2].Bits.G = 0;

+  }

+

+  //

+  // Update GDTBASE for this thunk context

+  //

+  *(VOID**)((UINTN)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt;

+

+  //

+  // Update Thunk Attributes

+  //

+  *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mThunk16Attr) =

+    ThunkContext->ThunkAttributes;

+}

+

+/**

+  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 is 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

+  )

+{

+  IA32_REGISTER_SET                 *UpdatedRegs;

+

+  ASSERT (ThunkContext != NULL);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);

+  ASSERT (ThunkContext->RealModeBufferSize >= m16Size);

+  ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);

+  ASSERT (((ThunkContext->ThunkAttributes & (THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 | THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL)) != \

+           (THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 | THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL)));

+           

+  UpdatedRegs = InternalAsmThunk16 (

+                  ThunkContext->RealModeState,

+                  ThunkContext->RealModeBuffer

+                  );

+

+  CopyMem (ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs));

+}

+

+/**

+  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

+  )

+{

+  AsmPrepareThunk16 (ThunkContext);

+  AsmThunk16 (ThunkContext);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86WriteGdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86WriteGdtr.c
new file mode 100644
index 0000000..54383d5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86WriteGdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  IA-32/x64 AsmWriteGdtr()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Gdtr != NULL);

+  InternalX86WriteGdtr (Gdtr);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86WriteIdtr.c b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86WriteIdtr.c
new file mode 100644
index 0000000..d187bc2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseLib/X86WriteIdtr.c
@@ -0,0 +1,39 @@
+/** @file

+  IA-32/x64 AsmWriteIdtr()

+

+  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.

+

+**/

+

+

+

+

+#include "BaseLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (Idtr != NULL);

+  InternalX86WriteIdtr (Idtr);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
new file mode 100644
index 0000000..5dfab35
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -0,0 +1,56 @@
+## @file

+#  Instance of Base Memory Library without assembly.

+#

+#  Base Memory Library implementation - no ASM.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLib

+  MODULE_UNI_FILE                = BaseMemoryLib.uni

+  FILE_GUID                      = fd44e603-002a-4b29-9f5f-529e815b6165

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  SetMem.c

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGeneric.c

+  MemLibGuid.c

+  CopyMem.c

+  MemLibInternals.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.uni
new file mode 100644
index 0000000..96cb62d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.c
new file mode 100644
index 0000000..bbee8f2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 A pointer to the destination buffer to compare.

+  @param  SourceBuffer      A 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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CopyMem.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CopyMem.c
new file mode 100644
index 0000000..37f0366
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CopyMem.c
@@ -0,0 +1,62 @@
+/** @file

+  Implementation of the InternalMemCopyMem routine. This function is broken

+  out into its own source file so that it can be excluded from a build for a

+  particular platform easily if an optimized version is desired.

+

+  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.

+

+**/

+

+

+

+

+#include "MemLibInternals.h"

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer The target of the copy request.

+  @param  SourceBuffer      The place to copy from.

+  @param  Length            The number of bytes to copy.

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memcpy()

+  //

+  volatile UINT8                    *Destination8;

+  CONST UINT8                       *Source8;

+

+  if (SourceBuffer > DestinationBuffer) {

+    Destination8 = (UINT8*)DestinationBuffer;

+    Source8 = (CONST UINT8*)SourceBuffer;

+    while (Length-- != 0) {

+      *(Destination8++) = *(Source8++);

+    }

+  } else if (SourceBuffer < DestinationBuffer) {

+    Destination8 = (UINT8*)DestinationBuffer + Length;

+    Source8 = (CONST UINT8*)SourceBuffer + Length;

+    while (Length-- != 0) {

+      *(--Destination8) = *(--Source8);

+    }

+  }

+  return DestinationBuffer;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.c
new file mode 100644
index 0000000..9f64e85
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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   A pointer to the destination buffer of the memory copy.

+  @param  SourceBuffer        A 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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibGeneric.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibGeneric.c
new file mode 100644
index 0000000..a977c4a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibGeneric.c
@@ -0,0 +1,264 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length The number of bytes to set.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            Length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*Pointer == Value) {

+      return Pointer;

+    }

+    ++Pointer;

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*Pointer == Value) {

+      return Pointer;

+    }

+    ++Pointer;

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*Pointer == Value) {

+      return Pointer;

+    }

+    ++Pointer;

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*Pointer == Value) {

+      return Pointer;

+    }

+    ++Pointer;

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibGuid.c
new file mode 100644
index 0000000..dc16bd5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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   A pointer to the destination GUID.

+  @param  SourceGuid        A pointer to the source GUID.

+

+  @return DestinationGuid.

+

+**/

+GUID *

+EFIAPI

+CopyGuid (

+  OUT GUID       *DestinationGuid,

+  IN CONST GUID  *SourceGuid

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibInternals.h
new file mode 100644
index 0000000..6f75839
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            The number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The calue to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.c
new file mode 100644
index 0000000..4fd75fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.c
new file mode 100644
index 0000000..fb30fa5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.c
new file mode 100644
index 0000000..fceb6d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.c
new file mode 100644
index 0000000..65c8b11
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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, or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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, or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem.c
new file mode 100644
index 0000000..5e74085
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem.c
@@ -0,0 +1,53 @@
+/** @file

+  Implementation of the EfiSetMem routine. This function is broken

+  out into its own source file so that it can be excluded from a

+  build for a particular platform easily if an optimized version

+  is desired.

+

+  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.

+

+**/

+

+

+

+

+#include "MemLibInternals.h"

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set.

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  //

+  // Declare the local variables that actually move the data elements as

+  // volatile to prevent the optimizer from replacing this function with

+  // the intrinsic memset()

+  //

+  volatile UINT8                    *Pointer;

+

+  Pointer = (UINT8*)Buffer;

+  while (Length-- > 0) {

+    *(Pointer++) = Value;

+  }

+  return Buffer;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.c
new file mode 100644
index 0000000..0ecfdae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.c
new file mode 100644
index 0000000..f7ce307
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.c
new file mode 100644
index 0000000..13d4b05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
new file mode 100644
index 0000000..8a33927
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.c
new file mode 100644
index 0000000..2a0a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf
new file mode 100644
index 0000000..1903be5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf
@@ -0,0 +1,104 @@
+## @file

+#  Instance of Base Memory Library using MMX registers.

+#

+#  Base Memory Library that uses MMX registers for high performance.

+#  Optimized for use in DXE.

+#

+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibMmx

+  MODULE_UNI_FILE                = BaseMemoryLibMmx.uni

+  FILE_GUID                      = d458a654-f64c-49db-b8d1-3821306bf1f6

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[Sources]

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+  MemLibInternals.h

+

+[Sources.Ia32]

+  Ia32/ScanMem64.S

+  Ia32/ScanMem32.S

+  Ia32/ScanMem16.S

+  Ia32/ScanMem8.S

+  Ia32/CompareMem.S

+  Ia32/SetMem64.S

+  Ia32/SetMem32.S

+  Ia32/SetMem16.S

+  Ia32/ZeroMem.S

+  Ia32/SetMem.S

+  Ia32/CopyMem.S

+  Ia32/ScanMem64.asm

+  Ia32/ScanMem32.asm

+  Ia32/ScanMem16.asm

+  Ia32/ScanMem8.asm

+  Ia32/CompareMem.asm

+  Ia32/SetMem64.asm

+  Ia32/SetMem32.asm

+  Ia32/SetMem16.asm

+  Ia32/ZeroMem.asm

+  Ia32/SetMem.asm

+  Ia32/CopyMem.asm

+

+[Sources.X64]

+  X64/ZeroMem.asm

+  X64/ScanMem64.asm

+  X64/ScanMem32.asm

+  X64/ScanMem16.asm

+  X64/ScanMem8.asm

+  X64/CompareMem.asm

+  X64/SetMem64.asm

+  X64/SetMem32.asm

+  X64/SetMem16.asm

+  X64/SetMem.asm

+  X64/CopyMem.asm

+  X64/ScanMem64.S

+  X64/ScanMem32.S

+  X64/ScanMem16.S

+  X64/ScanMem8.S

+  X64/CompareMem.S

+  X64/SetMem64.S

+  X64/SetMem32.S

+  X64/SetMem16.S

+  X64/ZeroMem.S

+  X64/SetMem.S

+  X64/CopyMem.S

+

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.uni b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.uni
new file mode 100644
index 0000000..f443219
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/CompareMemWrapper.c
new file mode 100644
index 0000000..c59000d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/CopyMemWrapper.c
new file mode 100644
index 0000000..9b76f0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.S
new file mode 100644
index 0000000..b509586
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.S
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CompareMem.Asm

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCompareMem):

+    push    %esi

+    push    %edi

+    movl    12(%esp), %esi

+    movl    16(%esp), %edi

+    movl    20(%esp), %ecx

+    repe    cmpsb

+    movzbl  -1(%esi), %eax

+    movzbl  -1(%edi), %edx

+    subl    %edx, %eax

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.asm
new file mode 100644
index 0000000..5a0792d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CompareMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.S
new file mode 100644
index 0000000..b934ff5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.S
@@ -0,0 +1,86 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   CopyMem.asm

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCopyMem):

+    push    %esi

+    push    %edi

+    movl    16(%esp), %esi              # esi <- Source

+    movl    12(%esp), %edi              # edi <- Destination

+    movl    20(%esp), %edx              # edx <- Count

+    leal    -1(%esi,%edx,), %eax        # eax <- End of Source

+    cmpl    %edi, %esi

+    jae     L0

+    cmpl    %edi, %eax                  # Overlapped?

+    jae     L_CopyBackward              # Copy backward if overlapped

+L0:

+    xorl    %ecx, %ecx

+    subl    %esi, %ecx

+    andl    $7, %ecx                    # ecx + esi aligns on 8-byte boundary

+    jz      L1

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx                  # edx <- remaining bytes to copy

+    rep

+    movsb

+L1:

+    movl    %edx, %ecx

+    andl    $7, %edx

+    shrl    $3, %ecx                    # ecx <- # of Qwords to copy

+    jz      L_CopyBytes

+    pushl   %eax

+    pushl   %eax

+    movq    %mm0, (%esp)                # save mm0

+L2:

+    movq    (%esi), %mm0

+    movq    %mm0, (%edi)

+    addl    $8, %esi

+    addl    $8, %edi

+    loop    L2

+    movq    (%esp), %mm0                # restore mm0

+    popl    %ecx                        # stack cleanup

+    popl    %ecx                        # stack cleanup

+    jmp     L_CopyBytes

+L_CopyBackward:

+    movl    %eax, %esi                  # esi <- Last byte in Source

+    leal    -1(%edi,%edx,), %edi        # edi <- Last byte in Destination

+    std

+L_CopyBytes:

+    movl    %edx, %ecx

+    rep

+    movsb

+    cld

+    movl    12(%esp), %eax

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.asm
new file mode 100644
index 0000000..38e1da7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/CopyMem.asm
@@ -0,0 +1,77 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [esi + edx - 1]        ; eax <- End of Source

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, edi                    ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     ecx, edx

+    and     edx, 7

+    shr     ecx, 3                      ; ecx <- # of Qwords to copy

+    jz      @CopyBytes

+    push    eax

+    push    eax

+    movq    [esp], mm0                  ; save mm0

+@@:

+    movq    mm0, [esi]

+    movq    [edi], mm0

+    add     esi, 8

+    add     edi, 8

+    loop    @B

+    movq    mm0, [esp]                  ; restore mm0

+    pop     ecx                         ; stack cleanup

+    pop     ecx                         ; stack cleanup

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     esi, eax                    ; esi <- Last byte in Source

+    lea     edi, [edi + edx - 1]        ; edi <- Last byte in Destination

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb

+    cld

+    mov     eax, [esp + 12]

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.S
new file mode 100644
index 0000000..e247d4a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem16.Asm

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem16):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasw

+    leal    -2(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..0ee190e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem16.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.S
new file mode 100644
index 0000000..066fde4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem32.Asm

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem32):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasl

+    leal    -4(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..adbf295
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem32.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.S
new file mode 100644
index 0000000..b3435d7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem64.Asm

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    cmpl    (%edi), %eax

+    leal    8(%edi), %edi

+    loopne  L0

+    jne     L1

+    cmpl    -4(%edi), %edx

+    jecxz   L1

+    jne     L0

+L1:

+    leal    -8(%edi), %eax

+    cmovne  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..0a0f5d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.S
new file mode 100644
index 0000000..5e451fd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem8.Asm

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem8):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movb    16(%esp), %al

+    repne   scasb

+    leal    -1(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..c64d41d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ScanMem8.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.S
new file mode 100644
index 0000000..7329d68
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.S
@@ -0,0 +1,66 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   SetMem.asm

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem):

+    push    %edi

+    movb    16(%esp), %al

+    movb    %al, %ah

+    shrdl   $16, %eax, %edx

+    shldl   $16, %edx, %eax

+    movl    12(%esp), %ecx              # ecx <- Count

+    movl    8(%esp), %edi               # edi <- Buffer

+    movl    %ecx, %edx

+    andl    $7, %edx

+    shrl    $3, %ecx                    # # of Qwords to set

+    jz      L1

+    addl    $-16, %esp

+    movq    %mm0, (%esp)                # save mm0

+    movq    %mm1, 8(%esp)               # save mm1

+    movd    %eax, %mm0

+    movd    %eax, %mm1

+    psllq   $32, %mm0

+    por     %mm1, %mm0                  # fill mm0 with 8 Value's

+L0:

+    movq    %mm0, (%edi)

+    addl    $8, %edi

+    loop    L0

+    movq    (%esp), %mm0                # restore mm0

+    movq    8(%esp), %mm1               # restore mm1

+    addl    $0x10, %esp                 # stack cleanup

+L1:

+    movl    %edx, %ecx

+    rep

+    stosb

+    movl    8(%esp), %eax               # eax <- Buffer as return value

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.asm
new file mode 100644
index 0000000..e43ea08
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem.asm
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov     al, [esp + 16]

+    mov     ah, al

+    shrd    edx, eax, 16

+    shld    eax, edx, 16

+    mov     ecx, [esp + 12]             ; ecx <- Count

+    mov     edi, [esp + 8]              ; edi <- Buffer

+    mov     edx, ecx

+    and     edx, 7

+    shr     ecx, 3                      ; # of Qwords to set

+    jz      @SetBytes

+    add     esp, -10h

+    movq    [esp], mm0                  ; save mm0

+    movq    [esp + 8], mm1              ; save mm1

+    movd    mm0, eax

+    movd    mm1, eax

+    psllq   mm0, 32

+    por     mm0, mm1                    ; fill mm0 with 8 Value's

+@@:

+    movq    [edi], mm0

+    add     edi, 8

+    loop    @B

+    movq    mm0, [esp]                  ; restore mm0

+    movq    mm1, [esp + 8]              ; restore mm1

+    add     esp, 10h                    ; stack cleanup

+@SetBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]              ; eax <- Buffer as return value

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.S
new file mode 100644
index 0000000..4d84beb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.S
@@ -0,0 +1,59 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   SetMem16.asm

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem16):

+    push    %edi

+    movl    16(%esp), %eax

+    shrdl   $16, %eax, %edx

+    shldl   $16, %edx, %eax

+    movl    12(%esp), %edx

+    movl    8(%esp), %edi

+    movl    %edx, %ecx

+    andl    $3, %edx

+    shrl    $2, %ecx

+    jz      L1

+    movd    %eax, %mm0

+    movd    %eax, %mm1

+    psllq   $32, %mm0

+    por     %mm1, %mm0

+L0:

+    movq    %mm0, (%edi)

+    addl    $8, %edi

+    loop    L0

+L1:

+    movl    %edx, %ecx

+    rep

+    stosw

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.asm
new file mode 100644
index 0000000..8d5bca0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem16.asm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     eax, [esp + 16]

+    shrd    edx, eax, 16

+    shld    eax, edx, 16

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     ecx, edx

+    and     edx, 3

+    shr     ecx, 2

+    jz      @SetWords

+    movd    mm0, eax

+    movd    mm1, eax

+    psllq   mm0, 32

+    por     mm0, mm1

+@@:

+    movq    [edi], mm0

+    add     edi, 8

+    loop    @B

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.S
new file mode 100644
index 0000000..fb0d078
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   SetMem32.asm

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem32):

+    movl    4(%esp), %eax

+    movl    8(%esp), %ecx

+    movd    12(%esp), %mm0

+    shrl    %ecx

+    movl    %eax, %edx

+    jz      L1

+    movq    %mm0, %mm1

+    psllq   $32, %mm1

+    por     %mm1, %mm0

+L0:

+    movq    %mm0, (%edx)

+    lea     8(%edx), %edx

+    loop    L0

+L1:

+    jnc     L2

+    movd    %mm0, (%edx)

+L2:

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.asm
new file mode 100644
index 0000000..031c48a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem32.asm
@@ -0,0 +1,59 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC

+    mov     eax, [esp + 4]              ; eax <- Buffer as return value

+    mov     ecx, [esp + 8]              ; ecx <- Count

+    movd    mm0, dword ptr [esp + 12]             ; mm0 <- Value

+    shr     ecx, 1                      ; ecx <- number of qwords to set

+    mov     edx, eax                    ; edx <- Buffer

+    jz      @SetDwords

+    movq    mm1, mm0

+    psllq   mm1, 32

+    por     mm0, mm1

+@@:

+    movq    qword ptr [edx], mm0

+    lea     edx, [edx + 8]              ; use "lea" to avoid change in flags

+    loop    @B

+@SetDwords:

+    jnc     @F

+    movd    dword ptr [edx], mm0

+@@:

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.S
new file mode 100644
index 0000000..53379ad
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   SetMem64.asm

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem64):

+    movl    4(%esp), %eax

+    movl    8(%esp), %ecx

+    movq    12(%esp), %mm0

+    movl    %eax, %edx

+L0:

+    movq    %mm0, (%edx)

+    lea     8(%edx), %edx

+    loop    L0

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.asm
new file mode 100644
index 0000000..42870bd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/SetMem64.asm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC

+    mov     eax, [esp + 4]

+    mov     ecx, [esp + 8]

+    movq    mm0, [esp + 12]

+    mov     edx, eax

+@@:

+    movq    [edx], mm0

+    add     edx, 8

+    loop    @B

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.S
new file mode 100644
index 0000000..d645271
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.S
@@ -0,0 +1,54 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   ZeroMem.asm

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemZeroMem):

+    push    %edi

+    movl    8(%esp), %edi

+    movl    12(%esp), %ecx

+    movl    %ecx, %edx

+    shrl    $3, %ecx

+    jz      L_ZeroBytes

+    pxor    %mm0, %mm0

+L0:

+    movq    %mm0, (%edi)

+    addl    $8, %edi

+    loop    L0

+L_ZeroBytes:

+    andl    $7, %edx

+    xorl    %eax, %eax

+    movl    %edx, %ecx

+    rep

+    stosb

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..1676b35
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/Ia32/ZeroMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .mmx

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edx, ecx

+    shr     ecx, 3

+    jz      @ZeroBytes

+    pxor    mm0, mm0

+@@:

+    movq    [edi], mm0

+    add     edi, 8

+    loop    @B

+@ZeroBytes:

+    and     edx, 7

+    xor     eax, eax

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibGuid.c
new file mode 100644
index 0000000..c04af6e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibInternals.h
new file mode 100644
index 0000000..38bb975
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer The target of the copy request.

+  @param  SourceBuffer      The place to copy from.

+  @param  Length            The number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  Teh pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem16Wrapper.c
new file mode 100644
index 0000000..4fd75fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem32Wrapper.c
new file mode 100644
index 0000000..defd510
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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       Thevalue to search for in the target buffer.

+

+  @return A pointer to the matching byte in the target buffer or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem64Wrapper.c
new file mode 100644
index 0000000..fceb6d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem8Wrapper.c
new file mode 100644
index 0000000..efbbe20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem16Wrapper.c
new file mode 100644
index 0000000..0ecfdae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem32Wrapper.c
new file mode 100644
index 0000000..f7ce307
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem64Wrapper.c
new file mode 100644
index 0000000..13d4b05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
new file mode 100644
index 0000000..8a33927
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.S
new file mode 100644
index 0000000..5902405
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.S
@@ -0,0 +1,59 @@
+#

+# ConvertAsm.py: Automatically generated from CompareMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+ASM_PFX(InternalMemCompareMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rcx, %rsi 

+    movq    %rdx, %rdi 

+    movq    %r8, %rcx 

+    repe    cmpsb

+    movzbq  -1(%rsi), %rax

+    movzbq  -1(%rdi), %rdx

+    subq    %rdx, %rax 

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm
new file mode 100644
index 0000000..0ef05b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CompareMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.S
new file mode 100644
index 0000000..1d87e2d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.S
@@ -0,0 +1,74 @@
+#

+# ConvertAsm.py: Automatically generated from CopyMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+ASM_PFX(InternalMemCopyMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rdx, %rsi                  # rsi <- Source

+    movq    %rcx, %rdi                  # rdi <- Destination

+    leaq    -1(%rsi, %r8,), %r9         # r9 <- End of Source          

+    cmpq    %rdi, %rsi 

+    movq    %rdi, %rax                  # rax <- Destination as return value

+    jae     L0

+    cmpq    %rdi, %r9

+    jae     L_CopyBackward              # Copy backward if overlapped

+L0:

+    movq    %r8, %rcx 

+    andq    $7, %r8

+    shrq    $3, %rcx                    # rcx <- # of Qwords to copy

+    jz      L_CopyBytes

+    movd    %mm0, %r10                  # (Save mm0 in r10)

+L1:

+    movq    (%rsi), %mm0

+    movntq  %mm0, (%rdi)

+    addq    $8, %rsi 

+    addq    $8, %rdi

+    loop    L1

+    mfence

+    movd    %r10, %mm0                  # (Restore mm0)

+    jmp     L_CopyBytes

+L_CopyBackward:

+    movq    %r9, %rsi                   # rsi <- End of Source

+    leaq    -1(%rdi, %r8,), %rdi        # rdi <- End of Destination

+    std                                 # set direction flag

+L_CopyBytes:

+    movq    %r8, %rcx 

+    rep     movsb                       # Copy bytes backward

+    cld

+    popq    %rdi

+    popq    %rsi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm
new file mode 100644
index 0000000..6e74985
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/CopyMem.asm
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID *

+; EFIAPI

+; InternalMemCopyMem (

+;   OUT     VOID                      *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rsi + r8 - 1]          ; r9 <- End of Source

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F

+    cmp     r9, rdi

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     rcx, r8

+    and     r8, 7

+    shr     rcx, 3                      ; rcx <- # of Qwords to copy

+    jz      @CopyBytes

+    DB      49h, 0fh, 7eh, 0c2h         ; movd r10, mm0 (Save mm0 in r10)

+@@:

+    DB      0fh, 6fh, 06h               ; movd mm0, [rsi]

+    DB      0fh, 0e7h, 07h              ; movntq [rdi], mm0

+    add     rsi, 8

+    add     rdi, 8

+    loop    @B

+    mfence

+    DB      49h, 0fh, 6eh, 0c2h         ; movd mm0, r10 (Restore mm0)

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     rsi, r9                     ; rsi <- End of Source

+    lea     rdi, [rdi + r8 - 1]         ; rdi <- End of Destination

+    std                                 ; set direction flag

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb                       ; Copy bytes backward

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.S
new file mode 100644
index 0000000..8f18996
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem16.S

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+ASM_PFX(InternalMemScanMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi 

+    movq    %r8, %rax 

+    movq    %rdx, %rcx 

+    repne   scasw

+    leaq    -2(%rdi), %rax

+    cmovnz  %rcx, %rax 

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm
new file mode 100644
index 0000000..a6114db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem16.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.S
new file mode 100644
index 0000000..05b6f64
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem32.S

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+ASM_PFX(InternalMemScanMem32):

+    pushq    %rdi

+    movq     %rcx, %rdi 

+    movq     %r8, %rax 

+    movq     %rdx, %rcx 

+    repne    scasl

+    leaq     -4(%rdi), %rax

+    cmovnz   %rcx, %rax 

+    popq     %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm
new file mode 100644
index 0000000..40ff6c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.S
new file mode 100644
index 0000000..dd7c1b8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.S
@@ -0,0 +1,55 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+ASM_PFX(InternalMemScanMem64):

+    pushq    %rdi

+    movq     %rcx, %rdi 

+    movq     %r8, %rax 

+    movq     %rdx, %rcx 

+    repne    scasq

+    leaq     -8(%rdi), %rax

+    cmovnz   %rcx, %rax 

+    popq     %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm
new file mode 100644
index 0000000..e78da7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.S
new file mode 100644
index 0000000..4f3b950
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem8.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+ASM_PFX(InternalMemScanMem8):

+    pushq    %rdi

+    movq     %rcx, %rdi 

+    movq     %rdx, %rcx  

+    movq     %r8,   %rax 

+    repne    scasb

+    leaq     -1(%rdi), %rax

+    cmovnz   %rcx, %rax                     # set rax to 0 if not found

+    popq     %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm
new file mode 100644
index 0000000..fee2397
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ScanMem8.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.S
new file mode 100644
index 0000000..ad7131f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.S
@@ -0,0 +1,61 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+ASM_PFX(InternalMemSetMem):

+    push    %rdi

+    movq    %r8, %rax

+    movb    %al, %ah

+    movd    %rax, %mm0

+    movq    %rcx, %r8

+    movq    %r8, %rdi                     # rdi <- Buffer

+    movq    %rdx, %rcx

+    andq    $7, %rdx 

+    shrq    $3, %rcx

+    jz      L_SetBytes

+    .byte   0x0f, 0x70, 0x0C0, 0x00

+L0:

+    movntq  %mm0, (%rdi) 

+    addq    $8, %rdi

+    loop    L0

+    mfence

+L_SetBytes:

+    movl    %edx, %ecx

+    rep       stosb

+    movq    %r8, %rax

+    pop     %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm
new file mode 100644
index 0000000..9ff949c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem.asm
@@ -0,0 +1,58 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID *

+; EFIAPI

+; InternalMemSetMem (

+;   OUT     VOID                      *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    rdi

+    mov     rax, r8

+    mov     ah, al

+    DB      48h, 0fh, 6eh, 0c0h         ; movd mm0, rax

+    mov     r8, rcx

+    mov     rdi, r8                     ; rdi <- Buffer

+    mov     rcx, rdx

+    and     edx, 7

+    shr     rcx, 3

+    jz      @SetBytes

+    DB      0fh, 70h, 0C0h, 00h         ; pshufw mm0, mm0, 0h

+@@:

+    DB      0fh, 0e7h, 07h              ; movntq [rdi], mm0

+    add     rdi, 8

+    loop    @B

+    mfence

+@SetBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     rax, r8

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.S
new file mode 100644
index 0000000..c947afd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.S
@@ -0,0 +1,60 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+ASM_PFX(InternalMemSetMem16):

+    pushq    %rdi

+    movq     %r8, %rax 

+    movd     %rax, %mm0 

+    movq     %rcx, %r8 

+    movq     %r8, %rdi 

+    movq     %rdx, %rcx 

+    andl     $3, %edx 

+    shrq     $2, %rcx

+    jz       L_SetWords

+    .byte    0x0f, 0x70, 0x0C0, 0x00

+L0:

+    movntq   %mm0, (%rdi) 

+    addq     $8, %rdi 

+    loop     L0

+    mfence

+L_SetWords:

+    movl    %edx, %ecx 

+    rep     stosw

+    movq    %r8, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm
new file mode 100644
index 0000000..fbd98b0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem16.asm
@@ -0,0 +1,57 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; VOID *

+; EFIAPI

+; InternalMemSetMem16 (

+;   OUT     VOID                      *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    rdi

+    mov     rax, r8

+    DB      48h, 0fh, 6eh, 0c0h         ; movd mm0, rax

+    mov     r8, rcx

+    mov     rdi, r8

+    mov     rcx, rdx

+    and     edx, 3

+    shr     rcx, 2

+    jz      @SetWords

+    DB      0fh, 70h, 0C0h, 00h         ; pshufw mm0, mm0, 0h

+@@:

+    DB      0fh, 0e7h, 07h              ; movntq [rdi], mm0

+    add     rdi, 8

+    loop    @B

+    mfence

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     rax, r8

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.S
new file mode 100644
index 0000000..4ab8e3a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.S
@@ -0,0 +1,55 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+ASM_PFX(InternalMemSetMem32):

+    movd    %r8, %mm0                   # mm0 <- Value

+    movq    %rcx, %rax                  # rax <- Buffer

+    xchgq   %rdx, %rcx                  # rcx <- Count  rdx <- Buffer

+    shrq    $1, % rcx                   # rcx <- # of qwords to set

+    jz      L_SetDwords

+   .byte    0x0f, 0x70, 0x0C0, 0x44

+L0:

+    movntq  %mm0, (%rdx) 

+    leaq    8(%rdx), %rdx               # use "lea" to avoid flag changes

+    loop    L0

+    mfence

+L_SetDwords:

+    jnc     L1

+    movd    %mm0, (%rdx) 

+L1:

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm
new file mode 100644
index 0000000..a0bdd89
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC

+    DB      49h, 0fh, 6eh, 0c0h         ; movd mm0, r8 (Value)

+    mov     rax, rcx                    ; rax <- Buffer

+    xchg    rcx, rdx                    ; rcx <- Count  rdx <- Buffer

+    shr     rcx, 1                      ; rcx <- # of qwords to set

+    jz      @SetDwords

+    DB      0fh, 70h, 0C0h, 44h         ; pshufw mm0, mm0, 44h

+@@:

+    DB      0fh, 0e7h, 02h              ; movntq [rdx], mm0

+    lea     rdx, [rdx + 8]              ; use "lea" to avoid flag changes

+    loop    @B

+    mfence

+@SetDwords:

+    jnc     @F

+    DB      0fh, 7eh, 02h               ; movd [rdx], mm0

+@@:

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.S
new file mode 100644
index 0000000..a4c7d8c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+ASM_PFX(InternalMemSetMem64):

+    movd      %r8, %mm0                 #Value

+    movq      %rcx, %rax                #rax <- Buffer

+    xchg      %rdx, %rcx                #rcx <- Count

+L0:

+    movntq  %mm0, (%rdx) 

+    addq    $8, %rdx

+    loop    L0

+    mfence

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm
new file mode 100644
index 0000000..f26177f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/SetMem64.asm
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC

+    DB      49h, 0fh, 6eh, 0c0h         ; movd mm0, r8 (Value)

+    mov     rax, rcx                    ; rax <- Buffer

+    xchg    rcx, rdx                    ; rcx <- Count

+@@:

+    DB      0fh, 0e7h, 02h              ; movntq  [rdx], mm0

+    add     rdx, 8

+    loop    @B

+    mfence

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ZeroMem.S
new file mode 100644
index 0000000..79f0b3d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ZeroMem.S
@@ -0,0 +1,57 @@
+#

+# ConvertAsm.py: Automatically generated from ZeroMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+ASM_PFX(InternalMemZeroMem):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %rdi, %r8

+    andq    $7, %rdx

+    shrq    $3, %rcx

+    jz      L_ZeroBytes

+    pxor    %mm0, %mm0

+L0:

+    movntq  %mm0, (%rdi)

+    addq    $8, %rdi

+    loop    L0

+    mfence

+L_ZeroBytes:

+    xorl    %eax, %eax

+    movl    %edx, %ecx

+    rep     stosb

+    movq    %r8, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ZeroMem.asm
new file mode 100644
index 0000000..0fcf50c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/X64/ZeroMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     r8, rdi

+    and     edx, 7

+    shr     rcx, 3

+    jz      @ZeroBytes

+    DB      0fh, 0efh, 0c0h             ; pxor mm0, mm0

+@@:

+    DB      0fh, 0e7h, 7                ; movntq [rdi], mm0

+    add     rdi, 8

+    loop    @B

+    DB      0fh, 0aeh, 0f0h             ; mfence

+@ZeroBytes:

+    xor     eax, eax

+    mov     ecx, edx

+    rep     stosb

+    mov     rax, r8

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ZeroMemWrapper.c
new file mode 100644
index 0000000..2a0a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibMmx/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
new file mode 100644
index 0000000..ad5ed20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
@@ -0,0 +1,114 @@
+## @file

+#  Instance of Base Memory Library optimized for use in DXE phase.

+#

+#  Base Memory Library that is optimized for use in DXE phase.  

+#  Uses REP, MMX, XMM registers as required for best performance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibOptDxe

+  MODULE_UNI_FILE                = BaseMemoryLibOptDxe.uni

+  FILE_GUID                      = 02BD55C2-AB1D-4b75-B0FD-9A63AE09B31D

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  MemLibInternals.h

+

+[Sources.Ia32]

+  Ia32/ScanMem64.S

+  Ia32/ScanMem32.S

+  Ia32/ScanMem16.S

+  Ia32/ScanMem8.S

+  Ia32/CompareMem.S

+  Ia32/ZeroMem.S

+  Ia32/SetMem64.S

+  Ia32/SetMem32.S

+  Ia32/SetMem16.S

+  Ia32/SetMem.S

+  Ia32/CopyMem.S

+  Ia32/ScanMem64.asm

+  Ia32/ScanMem32.asm

+  Ia32/ScanMem16.asm

+  Ia32/ScanMem8.asm

+  Ia32/CompareMem.asm

+  Ia32/ZeroMem.asm

+  Ia32/SetMem64.asm

+  Ia32/SetMem32.asm

+  Ia32/SetMem16.asm

+  Ia32/SetMem.asm

+  Ia32/CopyMem.asm

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+

+[Sources.X64]

+  X64/ScanMem64.asm

+  X64/ScanMem64.S

+  X64/ScanMem32.asm

+  X64/ScanMem32.S

+  X64/ScanMem16.asm

+  X64/ScanMem16.S

+  X64/ScanMem8.asm

+  X64/ScanMem8.S

+  X64/CompareMem.asm

+  X64/CompareMem.S

+  X64/ZeroMem.asm

+  X64/ZeroMem.S

+  X64/SetMem64.asm

+  X64/SetMem64.S

+  X64/SetMem32.asm

+  X64/SetMem32.S

+  X64/SetMem16.asm

+  X64/SetMem16.S

+  X64/SetMem.asm

+  X64/SetMem.S

+  X64/CopyMem.asm

+  X64/CopyMem.S

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni
new file mode 100644
index 0000000..0f0b14e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c
new file mode 100644
index 0000000..c59000d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c
new file mode 100644
index 0000000..9b76f0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S
new file mode 100644
index 0000000..2375878
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.S
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCompareMem):

+    push    %esi

+    push    %edi

+    movl    12(%esp), %esi

+    movl    16(%esp), %edi

+    movl    20(%esp), %ecx

+    repe    cmpsb

+    movzbl  -1(%esi), %eax

+    movzbl  -1(%edi), %edx

+    subl    %edx, %eax

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm
new file mode 100644
index 0000000..5a0792d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CompareMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S
new file mode 100644
index 0000000..bfc02d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.S
@@ -0,0 +1,85 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCopyMem):

+    push    %esi

+    push    %edi

+    movl    16(%esp), %esi              # esi <- Source

+    movl    12(%esp), %edi              # edi <- Destination

+    movl    20(%esp), %edx              # edx <- Count

+    leal    -1(%esi,%edx,), %eax        # eax <- End of Source

+    cmpl    %edi, %esi

+    jae     L0

+    cmpl    %edi, %eax                  # Overlapped?

+    jae     L_CopyBackward               # Copy backward if overlapped

+L0:

+    xorl    %ecx, %ecx

+    subl    %edi, %ecx

+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary

+    jz      L1

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx                  # edx <- remaining bytes to copy

+    rep

+    movsb

+L1:

+    movl    %edx, %ecx

+    andl    $15, %edx

+    shrl    $4, %ecx                    # ecx <- # of DQwords to copy

+    jz      L_CopyBytes

+    addl    $-16, %esp

+    movdqu  %xmm0, (%esp)

+L2:

+    movdqu  (%esi), %xmm0

+    movntdq %xmm0, (%edi)

+    addl    $16, %esi

+    addl    $16, %edi

+    loop    L2

+    mfence

+    movdqu  (%esp),%xmm0

+    addl    $16, %esp                   # stack cleanup

+    jmp     L_CopyBytes

+L_CopyBackward:

+    movl    %eax, %esi                  # esi <- Last byte in Source

+    leal    -1(%edi,%edx,), %edi        # edi <- Last byte in Destination

+    std

+L_CopyBytes:

+    movl    %edx, %ecx

+    rep

+    movsb

+    cld

+    movl    12(%esp), %eax              # eax <- Destination as return value

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm
new file mode 100644
index 0000000..a57a628
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/CopyMem.asm
@@ -0,0 +1,84 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [esi + edx - 1]        ; eax <- End of Source

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, edi                    ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx                    ; edx <- remaining bytes to copy

+    rep     movsb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4                      ; ecx <- # of DQwords to copy

+    jz      @CopyBytes

+    add     esp, -16

+    movdqu  [esp], xmm0                 ; save xmm0

+@@:

+    movdqu  xmm0, [esi]                 ; esi may not be 16-bytes aligned

+    movntdq [edi], xmm0                 ; edi should be 16-bytes aligned

+    add     esi, 16

+    add     edi, 16

+    loop    @B

+    mfence

+    movdqu  xmm0, [esp]                 ; restore xmm0

+    add     esp, 16                     ; stack cleanup

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     esi, eax                    ; esi <- Last byte in Source

+    lea     edi, [edi + edx - 1]        ; edi <- Last byte in Destination

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb

+    cld

+    mov     eax, [esp + 12]             ; eax <- Destination as return value

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S
new file mode 100644
index 0000000..e247d4a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem16.Asm

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem16):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasw

+    leal    -2(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..0ee190e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem16.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S
new file mode 100644
index 0000000..7f0a324
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem32.S

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem32):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasl

+    leal    -4(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..adbf295
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem32.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S
new file mode 100644
index 0000000..c8f76f1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    cmpl    (%edi), %eax

+    leal    8(%edi), %edi

+    loopne  L0

+    jne     L1

+    cmpl    -4(%edi), %edx

+    jecxz   L1

+    jne     L0

+L1:

+    leal    -8(%edi), %eax

+    cmovne  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..0a0f5d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S
new file mode 100644
index 0000000..478b926
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem8):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movb    16(%esp), %al

+    repne   scasb

+    leal    -1(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..c64d41d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ScanMem8.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S
new file mode 100644
index 0000000..8c643ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.S
@@ -0,0 +1,50 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem):

+    push    %edi

+    movl    12(%esp),%ecx

+    movb    16(%esp),%al

+    movb    %al, %ah

+    shrd    $16, %eax, %edx

+    shld    $16, %edx, %eax

+    movl    %ecx, %edx

+    movl    8(%esp),%edi

+    shr    $2, %ecx

+    rep stosl

+    movl    %edx, %ecx

+    andl    $3, %ecx

+    rep stosb

+    movl    8(%esp),%eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm
new file mode 100644
index 0000000..663d238
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov         ecx, [esp + 12]

+    mov         al,  [esp + 16]

+    mov         ah,  al

+    shrd        edx, eax, 16

+    shld        eax, edx, 16

+    mov         edx, ecx

+    mov         edi, [esp + 8]

+    shr         ecx, 2

+    rep stosd

+    mov         ecx, edx

+    and         ecx, 3

+    rep stosb

+    mov         eax, [esp + 8]

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S
new file mode 100644
index 0000000..a31c8ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem16):

+    push    %edi

+    movl    16(%esp), %eax

+    movl    8(%esp), %edi

+    movl    12(%esp), %ecx

+    rep

+    stosw

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm
new file mode 100644
index 0000000..3f3350d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem16.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S
new file mode 100644
index 0000000..73e36b7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem32):

+    push    %edi

+    movl    16(%esp),%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    rep

+    stosl

+    movl    8(%esp),%eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm
new file mode 100644
index 0000000..b27b85b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosd

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S
new file mode 100644
index 0000000..51687d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    mov     %eax, -8(%edi, %ecx, 8)

+    mov     %edx, -4(%edi, %ecx, 8)

+    loop    L0

+    movl    %edi, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm
new file mode 100644
index 0000000..146f3b9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/SetMem64.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    mov     [edi + ecx*8 - 8], eax

+    mov     [edi + ecx*8 - 4], edx

+    loop    @B

+    mov     eax, edi

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S
new file mode 100644
index 0000000..8ac5289
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemZeroMem):

+    push    %edi

+    xorl    %eax,%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    movl    %ecx,%edx

+    shrl    $2,%ecx

+    andl    $3,%edx

+    pushl   %edi

+    rep

+    stosl

+    movl    %edx,%ecx

+    rep

+    stosb

+    popl    %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..722bf67
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/Ia32/ZeroMem.asm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    xor     eax, eax

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edx, ecx

+    shr     ecx, 2

+    and     edx, 3

+    push    edi

+    rep     stosd

+    mov     ecx, edx

+    rep     stosb

+    pop     eax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c
new file mode 100644
index 0000000..c04af6e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h
new file mode 100644
index 0000000..b15e3c1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer The target of the copy request.

+  @param  SourceBuffer      The place to copy from.

+  @param  Length            The number of bytes to copy.

+

+  @return Destination.

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set.

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c
new file mode 100644
index 0000000..4fd75fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c
new file mode 100644
index 0000000..fb30fa5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c
new file mode 100644
index 0000000..fceb6d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c
new file mode 100644
index 0000000..ae60ff4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ScanMem8Wrapper.c
@@ -0,0 +1,100 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c
new file mode 100644
index 0000000..0ecfdae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c
new file mode 100644
index 0000000..f7ce307
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c
new file mode 100644
index 0000000..13d4b05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
new file mode 100644
index 0000000..c4c3fd2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S
new file mode 100644
index 0000000..1f6212a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.S
@@ -0,0 +1,59 @@
+#

+# ConvertAsm.py: Automatically generated from CompareMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------ 

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+ASM_PFX(InternalMemCompareMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rcx, %rsi

+    movq    %rdx, %rdi

+    movq    %r8, %rcx

+    repe    cmpsb

+    movzbq  -1(%rsi) , %rax

+    movzbq  -1(%rdi) , %rdx

+    sub     %dl, %al

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm
new file mode 100644
index 0000000..0ef05b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CompareMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S
new file mode 100644
index 0000000..13a47dc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.S
@@ -0,0 +1,82 @@
+#

+# ConvertAsm.py: Automatically generated from CopyMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+ASM_PFX(InternalMemCopyMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rdx, %rsi                  # rsi <- Source

+    movq    %rcx, %rdi                  # rdi <- Destination

+    leaq    -1(%rsi,%r8,), %r9          # r9 <- Last byte of Source      

+    cmpq    %rdi, %rsi

+    movq    %rdi, %rax                  # rax <- Destination as return value

+    jae     L0                          # Copy forward if Source > Destination

+    cmpq    %rdi, %r9                   # Overlapped?

+    jae     L_CopyBackward              # Copy backward if overlapped

+L0:

+    xorq    %rcx, %rcx

+    subq    %rdi, %rcx                  # rcx <- -rdi

+    andq    $15, %rcx                   # rcx + rsi should be 16 bytes aligned

+    jz      L1                          # skip if rcx == 0

+    cmpq    %r8, %rcx

+    cmova   %r8, %rcx

+    subq    %rcx, %r8

+    rep     movsb

+L1:

+    movq    %r8,  %rcx

+    andq    $15, %r8

+    shrq    $4, %rcx                    # rcx <- # of DQwords to copy

+    jz      L_CopyBytes

+    movdqu  %xmm0, 0x18(%rsp)           # save xmm0 on stack

+L2:

+    movdqu  (%rsi), %xmm0               # rsi may not be 16-byte aligned

+    movntdq %xmm0, (%rdi)               # rdi should be 16-byte aligned

+    addq    $16, %rsi

+    addq    $16, %rdi

+    loop    L2

+    mfence

+    movdqa  0x18(%rsp), %xmm0            # restore xmm0

+    jmp     L_CopyBytes                  # copy remaining bytes

+L_CopyBackward:

+    movq    %r9, %rsi                   # rsi <- Last byte of Source

+    leaq     -1(%rdi, %r8,), %rdi       # rdi <- Last byte of Destination

+    std

+L_CopyBytes:

+    movq    %r8, %rcx

+    rep     movsb

+    cld

+    popq    %rdi

+    popq    %rsi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm
new file mode 100644
index 0000000..8bcaca7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/CopyMem.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rsi + r8 - 1]          ; r9 <- Last byte of Source

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F                          ; Copy forward if Source > Destination

+    cmp     r9, rdi                     ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     rcx, rcx

+    sub     rcx, rdi                    ; rcx <- -rdi

+    and     rcx, 15                     ; rcx + rsi should be 16 bytes aligned

+    jz      @F                          ; skip if rcx == 0

+    cmp     rcx, r8

+    cmova   rcx, r8

+    sub     r8, rcx

+    rep     movsb

+@@:

+    mov     rcx, r8

+    and     r8, 15

+    shr     rcx, 4                      ; rcx <- # of DQwords to copy

+    jz      @CopyBytes

+    movdqa  [rsp + 18h], xmm0           ; save xmm0 on stack

+@@:

+    movdqu  xmm0, [rsi]                 ; rsi may not be 16-byte aligned

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rsi, 16

+    add     rdi, 16

+    loop    @B

+    mfence

+    movdqa  xmm0, [rsp + 18h]           ; restore xmm0

+    jmp     @CopyBytes                  ; copy remaining bytes

+@CopyBackward:

+    mov     rsi, r9                     ; rsi <- Last byte of Source

+    lea     rdi, [rdi + r8 - 1]         ; rdi <- Last byte of Destination

+    std

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S
new file mode 100644
index 0000000..f72de1d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem16.S

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID          *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+ASM_PFX(InternalMemScanMem16):

+    pushq  %rdi

+    movq   %rcx, %rdi

+    movq   %r8, %rax

+    movq   %rdx, %rcx

+    repne   scasw

+    leaq    -2(%rdi), %rax

+    cmovnz  %rcx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm
new file mode 100644
index 0000000..a6114db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem16.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S
new file mode 100644
index 0000000..d7ab3f8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem32.S

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+ASM_PFX(InternalMemScanMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    movq    %rdx, %rcx

+    repne   scasl

+    leaq    -4(%rdi), %rax

+    cmovnz  %rcx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm
new file mode 100644
index 0000000..40ff6c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S
new file mode 100644
index 0000000..e7fb076
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.S
@@ -0,0 +1,55 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID          *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+ASM_PFX(InternalMemScanMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    movq    %rdx, %rcx

+    repne   scasq

+    leaq    -8(%rdi), %rax

+    cmovnz  %rcx, %rax

+    popq    %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm
new file mode 100644
index 0000000..e78da7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S
new file mode 100644
index 0000000..3f0ad09
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem8.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID          *Buffer,

+#   IN      UINTN               Length,

+#   IN      UINT8               Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+ASM_PFX(InternalMemScanMem8):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasb

+    leaq    -1(%rdi), %rax

+    cmovnz  %rcx, %rax                  # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm
new file mode 100644
index 0000000..fee2397
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ScanMem8.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S
new file mode 100644
index 0000000..2391348
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.S
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+ASM_PFX(InternalMemSetMem):

+    pushq   %rdi

+    pushq   %rbx

+    pushq   %rcx        # push Buffer

+    movq    %r8, %rax   # rax = Value

+    andq    $0xff, %rax # rax = lower 8 bits of r8, upper 56 bits are 0

+    movb    %al, %ah    # ah  = al

+    movw    %ax, %bx    # bx  = ax

+    shlq    $0x10, %rax # rax = ax << 16

+    movw    %bx,  %ax   # ax  = bx

+    movq    %rax, %rbx  # ebx = eax

+    shlq    $0x20, %rax # rax = rax << 32

+    orq     %rbx, %rax  # eax = ebx

+    movq    %rcx, %rdi  # rdi = Buffer

+    movq    %rdx, %rcx  # rcx = Count

+    shrq    $3, %rcx    # rcx = rcx / 8

+    cld

+    rep     stosq 

+    movq    %rdx, %rcx  # rcx = rdx

+    andq    $7, %rcx    # rcx = rcx & 7

+    rep     stosb 

+    popq    %rax        # rax = Buffer

+    popq    %rbx

+    popq    %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm
new file mode 100644
index 0000000..5ca1571
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem.asm
@@ -0,0 +1,58 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    rdi rbx

+    push    rcx       ; push Buffer

+    mov     rax, r8   ; rax = Value

+    and     rax, 0ffh ; rax = lower 8 bits of r8, upper 56 bits are 0

+    mov     ah,  al   ; ah  = al

+    mov     bx,  ax   ; bx  = ax

+    shl     rax, 10h  ; rax = ax << 16

+    mov     ax,  bx   ; ax  = bx

+    mov     rbx, rax  ; ebx = eax

+    shl     rax, 20h  ; rax = rax << 32

+    or      rax, rbx  ; eax = ebx

+    mov     rdi, rcx  ; rdi = Buffer

+    mov     rcx, rdx  ; rcx = Count

+    shr     rcx, 3    ; rcx = rcx / 8

+    cld

+    rep     stosq 

+    mov     rcx, rdx  ; rcx = rdx

+    and     rcx, 7    ; rcx = rcx & 7

+    rep     stosb 

+    pop     rax       ; rax = Buffer

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S
new file mode 100644
index 0000000..cb11f8a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+ASM_PFX(InternalMemSetMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchg    %rdx, %rcx

+    rep     stosw

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm
new file mode 100644
index 0000000..1ac3b8d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem16.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    rdi

+    push    rcx

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosw

+    pop     rax

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S
new file mode 100644
index 0000000..9b9a63d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+ASM_PFX(InternalMemSetMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosl

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm
new file mode 100644
index 0000000..4a42b2f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    rdi

+    push    rcx

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosd

+    pop     rax

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S
new file mode 100644
index 0000000..90acd1f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.S
@@ -0,0 +1,46 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+ASM_PFX(InternalMemSetMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchg    %rdx, %rcx

+    rep     stosq

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm
new file mode 100644
index 0000000..9611c4c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/SetMem64.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    rdi

+    push    rcx

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosq

+    pop     rax

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S
new file mode 100644
index 0000000..3432f23
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.S
@@ -0,0 +1,51 @@
+#

+# ConvertAsm.py: Automatically generated from ZeroMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+ASM_PFX(InternalMemZeroMem):

+    pushq   %rdi

+    pushq   %rcx

+    xorq    %rax, %rax

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    shrq    $3, %rcx

+    andq    $7, %rdx

+    cld

+    rep     stosq

+    movq    %rdx, %rcx

+    rep     stosb

+    popq    %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm
new file mode 100644
index 0000000..29398fb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/X64/ZeroMem.asm
@@ -0,0 +1,48 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    rdi

+    push    rcx       ; push Buffer

+    xor     rax, rax  ; rax = 0

+    mov     rdi, rcx  ; rdi = Buffer

+    mov     rcx, rdx  ; rcx = Count

+    shr     rcx, 3    ; rcx = rcx / 8

+    and     rdx, 7    ; rdx = rdx & 7

+    cld

+    rep     stosq

+    mov     rcx, rdx  ; rcx = rdx

+    rep     stosb

+    pop     rax       ; rax = Buffer

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c
new file mode 100644
index 0000000..2a0a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptDxe/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
new file mode 100644
index 0000000..7c1f68a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
@@ -0,0 +1,115 @@
+## @file

+#  Instance of Base Memory Library optimized for use in PEI phase.

+#

+#  Base Memory Library that is optimized for use in PEI phase.  

+#  Uses REP, MMX, XMM registers as required for best performance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibOptPei

+  MODULE_UNI_FILE                = BaseMemoryLibOptPei.uni

+  FILE_GUID                      = D6F43B1B-0F21-462b-B8B7-A033C3EB4261

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  MemLibInternals.h

+

+[Sources.Ia32]

+  Ia32/ScanMem64.S

+  Ia32/ScanMem32.S

+  Ia32/ScanMem16.S

+  Ia32/ScanMem8.S

+  Ia32/CompareMem.S

+  Ia32/ZeroMem.S

+  Ia32/SetMem64.S

+  Ia32/SetMem32.S

+  Ia32/SetMem16.S

+  Ia32/SetMem.S

+  Ia32/CopyMem.S

+  Ia32/ScanMem64.asm

+  Ia32/ScanMem32.asm

+  Ia32/ScanMem16.asm

+  Ia32/ScanMem8.asm

+  Ia32/CompareMem.asm

+  Ia32/ZeroMem.asm

+  Ia32/SetMem64.asm

+  Ia32/SetMem32.asm

+  Ia32/SetMem16.asm

+  Ia32/SetMem.asm

+  Ia32/CopyMem.asm

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+

+[Sources.X64]

+  X64/ScanMem64.asm

+  X64/ScanMem64.S

+  X64/ScanMem32.asm

+  X64/ScanMem32.S

+  X64/ScanMem16.asm

+  X64/ScanMem16.S

+  X64/ScanMem8.asm

+  X64/ScanMem8.S

+  X64/CompareMem.asm

+  X64/CompareMem.S

+  X64/ZeroMem.asm

+  X64/ZeroMem.S

+  X64/SetMem64.asm

+  X64/SetMem64.S

+  X64/SetMem32.asm

+  X64/SetMem32.S

+  X64/SetMem16.asm

+  X64/SetMem16.S

+  X64/SetMem.asm

+  X64/SetMem.S

+  X64/CopyMem.asm

+  X64/CopyMem.S

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.uni b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.uni
new file mode 100644
index 0000000..91f19cd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/CompareMemWrapper.c
new file mode 100644
index 0000000..c59000d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/CopyMemWrapper.c
new file mode 100644
index 0000000..9b76f0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CompareMem.S
new file mode 100644
index 0000000..2375878
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CompareMem.S
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCompareMem):

+    push    %esi

+    push    %edi

+    movl    12(%esp), %esi

+    movl    16(%esp), %edi

+    movl    20(%esp), %ecx

+    repe    cmpsb

+    movzbl  -1(%esi), %eax

+    movzbl  -1(%edi), %edx

+    subl    %edx, %eax

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CompareMem.asm
new file mode 100644
index 0000000..5a0792d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CompareMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CopyMem.S
new file mode 100644
index 0000000..9d5873c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CopyMem.S
@@ -0,0 +1,62 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCopyMem):

+    push    %esi

+    push    %edi

+    movl    16(%esp), %esi              # esi <- Source

+    movl    12(%esp), %edi              # edi <- Destination

+    movl    20(%esp), %edx              # edx <- Count

+    cmpl    %esi, %edi

+    je      L_CopyDone

+    cmpl    $0, %edx

+    je      L_CopyDone

+    leal    -1(%esi, %edx), %eax        # eax <- End of Source

+    cmpl    %edi, %esi

+    jae     L_CopyBytes

+    cmpl    %edi, %eax

+    jb      L_CopyBytes                 # Copy backward if overlapped

+    movl    %eax, %esi                  # esi <- End of Source

+    leal    -1(%edi, %edx), %edi        # edi <- End of Destination

+    std

+L_CopyBytes:

+    movl    %edx, %ecx

+    rep

+    movsb                               # Copy bytes backward

+    cld

+L_CopyDone:

+    movl    12(%esp), %eax              # eax <- Destination as return value

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CopyMem.asm
new file mode 100644
index 0000000..6f8d007
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/CopyMem.asm
@@ -0,0 +1,61 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.Asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp+16]                ; esi <- Source

+    mov     edi, [esp+12]                ; edi <- Destination

+    mov     edx, [esp+20]                ; edx <- Count

+    cmp     esi, edi

+    je      @CopyDone

+    cmp     edx, 0

+    je      @CopyDone

+    lea     eax, [esi + edx - 1]         ; eax <- End of Source

+    cmp     esi, edi

+    jae     @CopyBytes

+    cmp     eax, edi

+    jb      @CopyBytes                   ; Copy backward if overlapped

+    mov     esi, eax                     ; esi <- End of Source

+    lea     edi, [edi + edx - 1]         ; edi <- End of Destination

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb                        ; Copy bytes backward

+    cld

+@CopyDone:

+    mov     eax, [esp + 12]             ; eax <- Destination as return value

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem16.S
new file mode 100644
index 0000000..c1a3748
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem16.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem16.S

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem16):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasw

+    leal    -2(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..0ee190e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem16.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem32.S
new file mode 100644
index 0000000..066fde4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem32.Asm

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem32):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasl

+    leal    -4(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..adbf295
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem32.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem64.S
new file mode 100644
index 0000000..c8f76f1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem64.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    cmpl    (%edi), %eax

+    leal    8(%edi), %edi

+    loopne  L0

+    jne     L1

+    cmpl    -4(%edi), %edx

+    jecxz   L1

+    jne     L0

+L1:

+    leal    -8(%edi), %eax

+    cmovne  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..0a0f5d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem8.S
new file mode 100644
index 0000000..478b926
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem8.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem8):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movb    16(%esp), %al

+    repne   scasb

+    leal    -1(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..c64d41d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ScanMem8.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem.S
new file mode 100644
index 0000000..8c643ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem.S
@@ -0,0 +1,50 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem):

+    push    %edi

+    movl    12(%esp),%ecx

+    movb    16(%esp),%al

+    movb    %al, %ah

+    shrd    $16, %eax, %edx

+    shld    $16, %edx, %eax

+    movl    %ecx, %edx

+    movl    8(%esp),%edi

+    shr    $2, %ecx

+    rep stosl

+    movl    %edx, %ecx

+    andl    $3, %ecx

+    rep stosb

+    movl    8(%esp),%eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem.asm
new file mode 100644
index 0000000..663d238
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov         ecx, [esp + 12]

+    mov         al,  [esp + 16]

+    mov         ah,  al

+    shrd        edx, eax, 16

+    shld        eax, edx, 16

+    mov         edx, ecx

+    mov         edi, [esp + 8]

+    shr         ecx, 2

+    rep stosd

+    mov         ecx, edx

+    and         ecx, 3

+    rep stosb

+    mov         eax, [esp + 8]

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem16.S
new file mode 100644
index 0000000..a31c8ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem16.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem16):

+    push    %edi

+    movl    16(%esp), %eax

+    movl    8(%esp), %edi

+    movl    12(%esp), %ecx

+    rep

+    stosw

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem16.asm
new file mode 100644
index 0000000..3f3350d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem16.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem32.S
new file mode 100644
index 0000000..73e36b7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem32.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem32):

+    push    %edi

+    movl    16(%esp),%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    rep

+    stosl

+    movl    8(%esp),%eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem32.asm
new file mode 100644
index 0000000..b27b85b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosd

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem64.S
new file mode 100644
index 0000000..51687d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem64.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    mov     %eax, -8(%edi, %ecx, 8)

+    mov     %edx, -4(%edi, %ecx, 8)

+    loop    L0

+    movl    %edi, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem64.asm
new file mode 100644
index 0000000..146f3b9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/SetMem64.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    mov     [edi + ecx*8 - 8], eax

+    mov     [edi + ecx*8 - 4], edx

+    loop    @B

+    mov     eax, edi

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ZeroMem.S
new file mode 100644
index 0000000..8ac5289
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ZeroMem.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemZeroMem):

+    push    %edi

+    xorl    %eax,%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    movl    %ecx,%edx

+    shrl    $2,%ecx

+    andl    $3,%edx

+    pushl   %edi

+    rep

+    stosl

+    movl    %edx,%ecx

+    rep

+    stosb

+    popl    %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..722bf67
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/Ia32/ZeroMem.asm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    xor     eax, eax

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edx, ecx

+    shr     ecx, 2

+    and     edx, 3

+    push    edi

+    rep     stosd

+    mov     ecx, edx

+    rep     stosb

+    pop     eax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/MemLibGuid.c
new file mode 100644
index 0000000..6f6edd0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/MemLibInternals.h
new file mode 100644
index 0000000..34eff54
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer The target of the copy request.

+  @param  SourceBuffer      The place to copy from.

+  @param  Length            The number of bytes to copy.

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set.

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem16Wrapper.c
new file mode 100644
index 0000000..4fd75fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem32Wrapper.c
new file mode 100644
index 0000000..fb30fa5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem64Wrapper.c
new file mode 100644
index 0000000..fceb6d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem8Wrapper.c
new file mode 100644
index 0000000..efbbe20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem16Wrapper.c
new file mode 100644
index 0000000..0ecfdae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem32Wrapper.c
new file mode 100644
index 0000000..ea6a5a9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem64Wrapper.c
new file mode 100644
index 0000000..13d4b05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c
new file mode 100644
index 0000000..8a33927
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CompareMem.S
new file mode 100644
index 0000000..26ed8dd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CompareMem.S
@@ -0,0 +1,59 @@
+#

+# ConvertAsm.py: Automatically generated from CompareMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+ASM_PFX(InternalMemCompareMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rcx, %rsi

+    movq    %rdx, %rdi

+    movq    %r8, %rcx

+    repe    cmpsb

+    movzbq  -1(%rsi) , %rax

+    movzbq  -1(%rdi) , %rdx

+    subq    %rdx, %rax

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CompareMem.asm
new file mode 100644
index 0000000..0ef05b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CompareMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CopyMem.S
new file mode 100644
index 0000000..fad30a5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CopyMem.S
@@ -0,0 +1,66 @@
+#

+# ConvertAsm.py: Automatically generated from CopyMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+ASM_PFX(InternalMemCopyMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rdx, %rsi                  # rsi <- Source

+    movq    %rcx, %rdi                  # rdi <- Destination

+    leaq    -1(%rsi, %r8,), %r9         # r9 <- End of Source

+    cmpq    %rdi, %rsi

+    movq    %rdi, %rax                  # rax <- Destination as return value

+    jae     _InternalMemCopyMem_al_0000

+    cmpq    %rdi, %r9

+    jae     _atSym_CopyBackward         # Copy backward if overlapped

+_InternalMemCopyMem_al_0000:

+    movq    %r8, %rcx

+    andq    $7, %r8

+    shrq    $3, %rcx

+    rep     movsq                       # Copy as many Qwords as possible

+    jmp     _atSym_CopyBytes

+_atSym_CopyBackward:

+    movq    %r9, %rsi                   # rsi <- End of Source

+    leaq    -1(%rdi, %r8), %rdi         # rdi <- End of Destination

+    std                                 # set direction flag

+_atSym_CopyBytes:

+    movq    %r8, %rcx

+    rep     movsb                       # Copy bytes backward

+    cld

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CopyMem.asm
new file mode 100644
index 0000000..df2e7cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/CopyMem.asm
@@ -0,0 +1,61 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.Asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rsi + r8 - 1]          ; r9 <- End of Source

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F

+    cmp     r9, rdi

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     rcx, r8

+    and     r8, 7

+    shr     rcx, 3

+    rep     movsq                       ; Copy as many Qwords as possible

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     rsi, r9                     ; rsi <- End of Source

+    lea     rdi, [rdi + r8 - 1]         ; esi <- End of Destination

+    std                                 ; set direction flag

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb                       ; Copy bytes backward

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem16.S
new file mode 100644
index 0000000..282dc3c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem16.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem16.S

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+ASM_PFX(InternalMemScanMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasw

+    leaq    -2(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem16.asm
new file mode 100644
index 0000000..a6114db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem16.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem32.S
new file mode 100644
index 0000000..70426e7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem32.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem32.S

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+ASM_PFX(InternalMemScanMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasl

+    leaq    -4(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem32.asm
new file mode 100644
index 0000000..40ff6c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem64.S
new file mode 100644
index 0000000..eac15bc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem64.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+ASM_PFX(InternalMemScanMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasq

+    leaq    -8(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem64.asm
new file mode 100644
index 0000000..e78da7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem8.S
new file mode 100644
index 0000000..cea3f56
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem8.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem8.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+ASM_PFX(InternalMemScanMem8):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasb

+    leaq    -1(%rdi), %rax

+    cmovnz  %rcx, %rax                  # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem8.asm
new file mode 100644
index 0000000..fee2397
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ScanMem8.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem.S
new file mode 100644
index 0000000..5dead6c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+ASM_PFX(InternalMemSetMem):

+    pushq   %rdi

+    movq    %r8, %rax    # rax = Value

+    movq    %rcx, %rdi   # rdi = Buffer

+    xchgq   %rdx, %rcx   # rcx = Count, rdx = Buffer

+    rep     stosb

+    movq    %rdx, %rax   # rax = Buffer

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem.asm
new file mode 100644
index 0000000..72b6405
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    rdi

+    push    rcx         ; push Buffer

+    mov     rax, r8     ; rax = Value

+    mov     rdi, rcx    ; rdi = Buffer

+    mov     rcx, rdx    ; rcx = Count

+    rep     stosb

+    pop     rax         ; rax = Buffer

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem16.S
new file mode 100644
index 0000000..4c291e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem16.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+ASM_PFX(InternalMemSetMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosw

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem16.asm
new file mode 100644
index 0000000..446e3a3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem16.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosw

+    mov     rax, rdx

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem32.S
new file mode 100644
index 0000000..9b9a63d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem32.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+ASM_PFX(InternalMemSetMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosl

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem32.asm
new file mode 100644
index 0000000..abe733e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem32.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosd

+    mov     rax, rdx

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem64.S
new file mode 100644
index 0000000..6721693
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem64.S
@@ -0,0 +1,46 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+ASM_PFX(InternalMemSetMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosq

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem64.asm
new file mode 100644
index 0000000..0a91105
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/SetMem64.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosq

+    mov     rax, rdx

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ZeroMem.S
new file mode 100644
index 0000000..83f3901
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ZeroMem.S
@@ -0,0 +1,50 @@
+#

+# ConvertAsm.py: Automatically generated from ZeroMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+ASM_PFX(InternalMemZeroMem):

+    pushq   %rdi

+    pushq   %rcx

+    xorq    %rax, %rax

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    shrq    $3, %rcx

+    andq    $7, %rdx

+    rep     stosq

+    movl    %edx, %ecx

+    rep     stosb

+    popq    %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ZeroMem.asm
new file mode 100644
index 0000000..fc4403a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/X64/ZeroMem.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    rdi

+    push    rcx

+    xor     rax, rax

+    mov     rdi, rcx

+    mov     rcx, rdx

+    shr     rcx, 3

+    and     rdx, 7

+    rep     stosq

+    mov     ecx, edx

+    rep     stosb

+    pop     rax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ZeroMemWrapper.c
new file mode 100644
index 0000000..2a0a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibOptPei/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
new file mode 100644
index 0000000..fd63242
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
@@ -0,0 +1,102 @@
+## @file

+#  Instance of Base Memory Library using REP string instructions.

+#

+#  Base Memory Library that uses REP string instructions for

+#  high performance and small size. Optimized for use in PEI.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibRepStr

+  MODULE_UNI_FILE                = BaseMemoryLibRepStr.uni

+  FILE_GUID                      = e7884bf4-51a1-485b-982a-ff89129983bc

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  MemLibInternals.h

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+

+[Sources.Ia32]

+  Ia32/ScanMem64.S

+  Ia32/ScanMem32.S

+  Ia32/ScanMem16.S

+  Ia32/ScanMem8.S

+  Ia32/CompareMem.S

+  Ia32/ZeroMem.S

+  Ia32/SetMem64.S

+  Ia32/SetMem32.S

+  Ia32/SetMem16.S

+  Ia32/SetMem.S

+  Ia32/CopyMem.S

+  Ia32/ScanMem64.asm

+  Ia32/ScanMem32.asm

+  Ia32/ScanMem16.asm

+  Ia32/ScanMem8.asm

+  Ia32/CompareMem.asm

+  Ia32/ZeroMem.asm

+  Ia32/SetMem64.asm

+  Ia32/SetMem32.asm

+  Ia32/SetMem16.asm

+  Ia32/SetMem.asm

+  Ia32/CopyMem.asm

+

+[Sources.X64]

+  X64/ScanMem64.S

+  X64/ScanMem32.S

+  X64/ScanMem16.S

+  X64/ScanMem8.S

+  X64/CompareMem.S

+  X64/ZeroMem.S

+  X64/SetMem64.S

+  X64/SetMem32.S

+  X64/SetMem16.S

+  X64/SetMem.S

+  X64/CopyMem.S

+  X64/ScanMem64.asm

+  X64/ScanMem32.asm

+  X64/ScanMem16.asm

+  X64/ScanMem8.asm

+  X64/CompareMem.asm

+  X64/ZeroMem.asm

+  X64/SetMem64.asm

+  X64/SetMem32.asm

+  X64/SetMem16.asm

+  X64/SetMem.asm

+  X64/CopyMem.asm

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.uni b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.uni
new file mode 100644
index 0000000..fcac2bf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/CompareMemWrapper.c
new file mode 100644
index 0000000..c59000d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/CopyMemWrapper.c
new file mode 100644
index 0000000..9b76f0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.S
new file mode 100644
index 0000000..b509586
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.S
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CompareMem.Asm

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCompareMem):

+    push    %esi

+    push    %edi

+    movl    12(%esp), %esi

+    movl    16(%esp), %edi

+    movl    20(%esp), %ecx

+    repe    cmpsb

+    movzbl  -1(%esi), %eax

+    movzbl  -1(%edi), %edx

+    subl    %edx, %eax

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.asm
new file mode 100644
index 0000000..5a0792d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CompareMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.S
new file mode 100644
index 0000000..5aeef75
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.S
@@ -0,0 +1,65 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CopyMem.Asm

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCopyMem):

+    push    %esi

+    push    %edi

+    movl    16(%esp), %esi              # esi <- Source

+    movl    12(%esp), %edi              # edi <- Destination

+    movl    20(%esp), %edx              # edx <- Count

+    leal    -1(%esi, %edx), %eax        # eax <- End of Source

+    cmpl    %edi, %esi

+    jae     L0

+    cmpl    %edi, %eax

+    jae     L_CopyBackward              # Copy backward if overlapped

+L0:

+    movl    %edx, %ecx

+    andl    $3, %edx

+    shrl    $2, %ecx

+    rep

+    movsl                               # Copy as many Dwords as possible

+    jmp     L_CopyBytes

+L_CopyBackward:

+    movl    %eax, %esi                  # esi <- End of Source

+    leal    -1(%edi, %edx), %edi        # edi <- End of Destination

+    std

+L_CopyBytes:

+    movl    %edx, %ecx

+    rep

+    movsb                               # Copy bytes backward

+    cld

+    movl    12(%esp), %eax              # eax <- Destination as return value

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.asm
new file mode 100644
index 0000000..cdb3520
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.asm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.Asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [esi + edx - 1]        ; eax <- End of Source

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, edi

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     ecx, edx

+    and     edx, 3

+    shr     ecx, 2

+    rep     movsd                       ; Copy as many Dwords as possible

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     esi, eax                    ; esi <- End of Source

+    lea     edi, [edi + edx - 1]        ; edi <- End of Destination

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb                       ; Copy bytes backward

+    cld

+    mov     eax, [esp + 12]             ; eax <- Destination as return value

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.S
new file mode 100644
index 0000000..e247d4a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem16.Asm

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem16):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasw

+    leal    -2(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..0ee190e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem16.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.S
new file mode 100644
index 0000000..066fde4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem32.Asm

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem32):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasl

+    leal    -4(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..adbf295
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem32.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.S
new file mode 100644
index 0000000..b3435d7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem64.Asm

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    cmpl    (%edi), %eax

+    leal    8(%edi), %edi

+    loopne  L0

+    jne     L1

+    cmpl    -4(%edi), %edx

+    jecxz   L1

+    jne     L0

+L1:

+    leal    -8(%edi), %eax

+    cmovne  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..0a0f5d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.S
new file mode 100644
index 0000000..5e451fd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem8.Asm

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem8):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movb    16(%esp), %al

+    repne   scasb

+    leal    -1(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..c64d41d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ScanMem8.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.S
new file mode 100644
index 0000000..9b1f1cb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem.Asm

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+    .code:

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem):

+    push    %edi

+    movl    16(%esp),%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    rep

+    stosb

+    movl    8(%esp),%eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.asm
new file mode 100644
index 0000000..3fdaba9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosb

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.S
new file mode 100644
index 0000000..e35774a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem16.Asm

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem16):

+    push    %edi

+    movl    16(%esp), %eax

+    movl    8(%esp), %edi

+    movl    12(%esp), %ecx

+    rep

+    stosw

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.asm
new file mode 100644
index 0000000..3f3350d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem16.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.S
new file mode 100644
index 0000000..0a8b1c3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.S
@@ -0,0 +1,43 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem32.Asm

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem32):

+    push    %edi

+    movl    16(%esp),%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    rep

+    stosl

+    movl    8(%esp),%eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.asm
new file mode 100644
index 0000000..b27b85b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    edi

+    mov     eax, [esp + 16]

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    rep     stosd

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.S
new file mode 100644
index 0000000..2e4b7ce
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.S
@@ -0,0 +1,46 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem64.Asm

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    mov     %eax, -8(%edi, %ecx, 8)

+    mov     %edx, -4(%edi, %ecx, 8)

+    loop    L0

+    movl    %edi, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.asm
new file mode 100644
index 0000000..146f3b9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/SetMem64.asm
@@ -0,0 +1,49 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    mov     [edi + ecx*8 - 8], eax

+    mov     [edi + ecx*8 - 4], edx

+    loop    @B

+    mov     eax, edi

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.S
new file mode 100644
index 0000000..86ba241
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.S
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ZeroMem.Asm

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemZeroMem):

+    push    %edi

+    xorl    %eax,%eax

+    movl    8(%esp),%edi

+    movl    12(%esp),%ecx

+    movl    %ecx,%edx

+    shrl    $2,%ecx

+    andl    $3,%edx

+    pushl   %edi

+    rep

+    stosl

+    movl    %edx,%ecx

+    rep

+    stosb

+    popl    %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..722bf67
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/Ia32/ZeroMem.asm
@@ -0,0 +1,50 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    xor     eax, eax

+    mov     edi, [esp + 8]

+    mov     ecx, [esp + 12]

+    mov     edx, ecx

+    shr     ecx, 2

+    and     edx, 3

+    push    edi

+    rep     stosd

+    mov     ecx, edx

+    rep     stosb

+    pop     eax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibGuid.c
new file mode 100644
index 0000000..6f6edd0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibInternals.h
new file mode 100644
index 0000000..cfca474
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer Target of copy

+  @param  SourceBuffer      Place to copy from

+  @param  Length            The number of bytes to copy

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem16Wrapper.c
new file mode 100644
index 0000000..4fd75fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem32Wrapper.c
new file mode 100644
index 0000000..fb30fa5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem64Wrapper.c
new file mode 100644
index 0000000..fceb6d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem8Wrapper.c
new file mode 100644
index 0000000..efbbe20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem16Wrapper.c
new file mode 100644
index 0000000..0ecfdae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem32Wrapper.c
new file mode 100644
index 0000000..f7ce307
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem64Wrapper.c
new file mode 100644
index 0000000..13d4b05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
new file mode 100644
index 0000000..8a33927
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CompareMem.S
new file mode 100644
index 0000000..3087aea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CompareMem.S
@@ -0,0 +1,59 @@
+#

+# ConvertAsm.py: Automatically generated from CompareMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID          *DestinationBuffer,

+#   IN      CONST VOID          *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+ASM_PFX(InternalMemCompareMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rcx, %rsi

+    movq    %rdx, %rdi

+    movq    %r8, %rcx

+    repe    cmpsb

+    movzbq  -1(%rsi) , %rax

+    movzbq  -1(%rdi) , %rdx

+    subq    %rdx, %rax

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CompareMem.asm
new file mode 100644
index 0000000..0ef05b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CompareMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CopyMem.S
new file mode 100644
index 0000000..4d7a7d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CopyMem.S
@@ -0,0 +1,66 @@
+#

+# ConvertAsm.py: Automatically generated from CopyMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+ASM_PFX(InternalMemCopyMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rdx, %rsi                  # rsi <- Source

+    movq    %rcx, %rdi                  # rdi <- Destination

+    leaq    -1(%rsi, %r8,), %r9         # r9 <- End of Source

+    cmpq    %rdi, %rsi

+    movq    %rdi, %rax                  # rax <- Destination as return value

+    jae     L0

+    cmpq    %rdi, %r9

+    jae     L_CopyBackward               # Copy backward if overlapped

+L0:

+    movq    %r8, %rcx

+    andq    $7, %r8

+    shrq    $3, %rcx

+    rep     movsq                       # Copy as many Qwords as possible

+    jmp     L_CopyBytes

+L_CopyBackward:

+    movq    %r9, %rsi                   # rsi <- End of Source

+    leaq    -1(%rdi, %r8),  %rdi        # esi <- End of Destination

+    std                                 # set direction flag

+L_CopyBytes:

+    movq    %r8, %rcx

+    rep     movsb                       # Copy bytes backward

+    cld

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CopyMem.asm
new file mode 100644
index 0000000..df2e7cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/CopyMem.asm
@@ -0,0 +1,61 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.Asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rsi + r8 - 1]          ; r9 <- End of Source

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F

+    cmp     r9, rdi

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    mov     rcx, r8

+    and     r8, 7

+    shr     rcx, 3

+    rep     movsq                       ; Copy as many Qwords as possible

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     rsi, r9                     ; rsi <- End of Source

+    lea     rdi, [rdi + r8 - 1]         ; esi <- End of Destination

+    std                                 ; set direction flag

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb                       ; Copy bytes backward

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem16.S
new file mode 100644
index 0000000..282dc3c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem16.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem16.S

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+ASM_PFX(InternalMemScanMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasw

+    leaq    -2(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem16.asm
new file mode 100644
index 0000000..a6114db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem16.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem32.S
new file mode 100644
index 0000000..70426e7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem32.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem32.S

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+ASM_PFX(InternalMemScanMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasl

+    leaq    -4(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem32.asm
new file mode 100644
index 0000000..40ff6c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem64.S
new file mode 100644
index 0000000..eac15bc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem64.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+ASM_PFX(InternalMemScanMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasq

+    leaq    -8(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem64.asm
new file mode 100644
index 0000000..e78da7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem8.S
new file mode 100644
index 0000000..cea3f56
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem8.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem8.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+ASM_PFX(InternalMemScanMem8):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasb

+    leaq    -1(%rdi), %rax

+    cmovnz  %rcx, %rax                  # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem8.asm
new file mode 100644
index 0000000..fee2397
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ScanMem8.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem.S
new file mode 100644
index 0000000..2e7edfa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+ASM_PFX(InternalMemSetMem):

+    pushq   %rdi

+    movq    %r8, %rax      # rax = Value

+    movq    %rcx, %rdi     # rdi = Buffer

+    xchgq   %rdx, %rcx     # rcx = Count, rdx = Buffer

+    rep     stosb

+    movq    %rdx, %rax     # rax = Buffer

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem.asm
new file mode 100644
index 0000000..ef15710
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.Asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    rdi

+    mov     rax, r8    ; rax = Value

+    mov     rdi, rcx   ; rdi = Buffer

+    xchg    rcx, rdx   ; rcx = Count, rdx = Buffer

+    rep     stosb

+    mov     rax, rdx   ; rax = Buffer

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem16.S
new file mode 100644
index 0000000..4c291e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem16.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+ASM_PFX(InternalMemSetMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosw

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem16.asm
new file mode 100644
index 0000000..446e3a3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem16.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.Asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosw

+    mov     rax, rdx

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem32.S
new file mode 100644
index 0000000..9b9a63d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem32.S
@@ -0,0 +1,47 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+ASM_PFX(InternalMemSetMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosl

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem32.asm
new file mode 100644
index 0000000..abe733e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem32.asm
@@ -0,0 +1,44 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.Asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosd

+    mov     rax, rdx

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem64.S
new file mode 100644
index 0000000..6721693
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem64.S
@@ -0,0 +1,46 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+ASM_PFX(InternalMemSetMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %r8, %rax

+    xchgq   %rdx, %rcx

+    rep     stosq

+    movq    %rdx, %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem64.asm
new file mode 100644
index 0000000..0a91105
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/SetMem64.asm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.Asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    xchg    rcx, rdx

+    rep     stosq

+    mov     rax, rdx

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ZeroMem.S
new file mode 100644
index 0000000..83f3901
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ZeroMem.S
@@ -0,0 +1,50 @@
+#

+# ConvertAsm.py: Automatically generated from ZeroMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+ASM_PFX(InternalMemZeroMem):

+    pushq   %rdi

+    pushq   %rcx

+    xorq    %rax, %rax

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    shrq    $3, %rcx

+    andq    $7, %rdx

+    rep     stosq

+    movl    %edx, %ecx

+    rep     stosb

+    popq    %rax

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ZeroMem.asm
new file mode 100644
index 0000000..fc4403a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/X64/ZeroMem.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.Asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    rdi

+    push    rcx

+    xor     rax, rax

+    mov     rdi, rcx

+    mov     rcx, rdx

+    shr     rcx, 3

+    and     rdx, 7

+    rep     stosq

+    mov     ecx, edx

+    rep     stosb

+    pop     rax

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ZeroMemWrapper.c
new file mode 100644
index 0000000..2a0a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibRepStr/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
new file mode 100644
index 0000000..fc53f68
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
@@ -0,0 +1,101 @@
+## @file

+#  Instance of Base Memory Library using SSE2 registers.

+#

+#  Base Memory Library that uses SSE2 registers for high performance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseMemoryLibSse2

+  MODULE_UNI_FILE                = BaseMemoryLibSse2.uni

+  FILE_GUID                      = 65a18235-5096-4032-8c63-214f0249ce8d

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  MemLibInternals.h

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGuid.c

+

+[Sources.Ia32]

+  Ia32/ScanMem64.S

+  Ia32/ScanMem32.S

+  Ia32/ScanMem16.S

+  Ia32/ScanMem8.S

+  Ia32/CompareMem.S

+  Ia32/ZeroMem.S

+  Ia32/SetMem64.S

+  Ia32/SetMem32.S

+  Ia32/SetMem16.S

+  Ia32/SetMem.S

+  Ia32/CopyMem.S

+  Ia32/ScanMem64.asm

+  Ia32/ScanMem32.asm

+  Ia32/ScanMem16.asm

+  Ia32/ScanMem8.asm

+  Ia32/CompareMem.asm

+  Ia32/ZeroMem.asm

+  Ia32/SetMem64.asm

+  Ia32/SetMem32.asm

+  Ia32/SetMem16.asm

+  Ia32/SetMem.asm

+  Ia32/CopyMem.asm

+

+[Sources.X64]

+  X64/ScanMem64.asm

+  X64/ScanMem32.asm

+  X64/ScanMem16.asm

+  X64/ScanMem8.asm

+  X64/CompareMem.asm

+  X64/ZeroMem.asm

+  X64/SetMem64.asm

+  X64/SetMem32.asm

+  X64/SetMem16.asm

+  X64/SetMem.asm

+  X64/CopyMem.asm

+  X64/ScanMem64.S

+  X64/ScanMem32.S

+  X64/ScanMem16.S

+  X64/ScanMem8.S

+  X64/CompareMem.S

+  X64/ZeroMem.S

+  X64/SetMem64.S

+  X64/SetMem32.S

+  X64/SetMem16.S

+  X64/SetMem.S

+  X64/CopyMem.S

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.uni b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.uni
new file mode 100644
index 0000000..490b4db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/CompareMemWrapper.c
new file mode 100644
index 0000000..c59000d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/CopyMemWrapper.c
new file mode 100644
index 0000000..9b76f0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.S
new file mode 100644
index 0000000..b509586
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.S
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CompareMem.Asm

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCompareMem):

+    push    %esi

+    push    %edi

+    movl    12(%esp), %esi

+    movl    16(%esp), %edi

+    movl    20(%esp), %ecx

+    repe    cmpsb

+    movzbl  -1(%esi), %eax

+    movzbl  -1(%edi), %edx

+    subl    %edx, %eax

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.asm
new file mode 100644
index 0000000..5a0792d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CompareMem.asm
@@ -0,0 +1,56 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    esi edi

+    mov     esi, [esp + 12]

+    mov     edi, [esp + 16]

+    mov     ecx, [esp + 20]

+    repe    cmpsb

+    movzx   eax, byte ptr [esi - 1]

+    movzx   edx, byte ptr [edi - 1]

+    sub     eax, edx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.S
new file mode 100644
index 0000000..17414ab
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.S
@@ -0,0 +1,85 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   CopyMem.asm

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemCopyMem):

+    push    %esi

+    push    %edi

+    movl    16(%esp), %esi              # esi <- Source

+    movl    12(%esp), %edi              # edi <- Destination

+    movl    20(%esp), %edx              # edx <- Count

+    leal    -1(%esi,%edx,), %eax        # eax <- End of Source

+    cmpl    %edi, %esi

+    jae     L0

+    cmpl    %edi, %eax                  # Overlapped?

+    jae     L_CopyBackward               # Copy backward if overlapped

+L0:

+    xorl    %ecx, %ecx

+    subl    %edi, %ecx

+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary

+    jz      L1

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx                  # edx <- remaining bytes to copy

+    rep

+    movsb

+L1:

+    movl    %edx, %ecx

+    andl    $15, %edx

+    shrl    $4, %ecx                    # ecx <- # of DQwords to copy

+    jz      L_CopyBytes

+    addl    $-16, %esp

+    movdqu  %xmm0, (%esp)

+L2:

+    movdqu  (%esi), %xmm0

+    movntdq %xmm0, (%edi)

+    addl    $16, %esi

+    addl    $16, %edi

+    loop    L2

+    mfence

+    movdqu  (%esp),%xmm0

+    addl    $16, %esp                   # stack cleanup

+    jmp     L_CopyBytes

+L_CopyBackward:

+    movl    %eax, %esi                  # esi <- Last byte in Source

+    leal    -1(%edi,%edx,), %edi        # edi <- Last byte in Destination

+    std

+L_CopyBytes:

+    movl    %edx, %ecx

+    rep

+    movsb

+    cld

+    movl    12(%esp), %eax              # eax <- Destination as return value

+    pop     %edi

+    pop     %esi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.asm
new file mode 100644
index 0000000..a57a628
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/CopyMem.asm
@@ -0,0 +1,84 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    esi edi

+    mov     esi, [esp + 16]             ; esi <- Source

+    mov     edi, [esp + 12]             ; edi <- Destination

+    mov     edx, [esp + 20]             ; edx <- Count

+    lea     eax, [esi + edx - 1]        ; eax <- End of Source

+    cmp     esi, edi

+    jae     @F

+    cmp     eax, edi                    ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx                    ; edx <- remaining bytes to copy

+    rep     movsb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4                      ; ecx <- # of DQwords to copy

+    jz      @CopyBytes

+    add     esp, -16

+    movdqu  [esp], xmm0                 ; save xmm0

+@@:

+    movdqu  xmm0, [esi]                 ; esi may not be 16-bytes aligned

+    movntdq [edi], xmm0                 ; edi should be 16-bytes aligned

+    add     esi, 16

+    add     edi, 16

+    loop    @B

+    mfence

+    movdqu  xmm0, [esp]                 ; restore xmm0

+    add     esp, 16                     ; stack cleanup

+    jmp     @CopyBytes

+@CopyBackward:

+    mov     esi, eax                    ; esi <- Last byte in Source

+    lea     edi, [edi + edx - 1]        ; edi <- Last byte in Destination

+    std

+@CopyBytes:

+    mov     ecx, edx

+    rep     movsb

+    cld

+    mov     eax, [esp + 12]             ; eax <- Destination as return value

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.S
new file mode 100644
index 0000000..e247d4a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem16.Asm

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem16):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasw

+    leal    -2(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.asm
new file mode 100644
index 0000000..0ee190e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem16.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasw

+    lea     eax, [edi - 2]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.S
new file mode 100644
index 0000000..066fde4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem32.Asm

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem32):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movl    16(%esp), %eax

+    repne   scasl

+    leal    -4(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.asm
new file mode 100644
index 0000000..adbf295
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem32.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     eax, [esp + 16]

+    repne   scasd

+    lea     eax, [edi - 4]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.S
new file mode 100644
index 0000000..b3435d7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.S
@@ -0,0 +1,61 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem64.Asm

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem64):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    16(%esp), %eax

+    movl    20(%esp), %edx

+    movl    8(%esp), %edi

+L0:

+    cmpl    (%edi), %eax

+    leal    8(%edi), %edi

+    loopne  L0

+    jne     L1

+    cmpl    -4(%edi), %edx

+    jecxz   L1

+    jne     L0

+L1:

+    leal    -8(%edi), %eax

+    cmovne  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.asm
new file mode 100644
index 0000000..0a0f5d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     edi, [esp + 8]

+@@:

+    cmp     eax, [edi]

+    lea     edi, [edi + 8]

+    loopne  @B

+    jne     @F

+    cmp     edx, [edi - 4]

+    jecxz   @F

+    jne     @B

+@@:

+    lea     eax, [edi - 8]

+    cmovne  eax, ecx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.S
new file mode 100644
index 0000000..5e451fd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.S
@@ -0,0 +1,52 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ScanMem8.Asm

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemScanMem8):

+    push    %edi

+    movl    12(%esp), %ecx

+    movl    8(%esp), %edi

+    movb    16(%esp), %al

+    repne   scasb

+    leal    -1(%edi), %eax

+    cmovnz  %ecx, %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.asm
new file mode 100644
index 0000000..c64d41d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ScanMem8.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    edi

+    mov     ecx, [esp + 12]

+    mov     edi, [esp + 8]

+    mov     al, [esp + 16]

+    repne   scasb

+    lea     eax, [edi - 1]

+    cmovnz  eax, ecx

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.S
new file mode 100644
index 0000000..63e2a99
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.S
@@ -0,0 +1,76 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem.asm

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+    #.MODEL flat,C

+    .xmm:

+    .code:

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  _mem_SetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+ASM_PFX(InternalMemSetMem):

+    push    %edi

+    movl    12(%esp), %edx              # edx <- Count

+    movl    8(%esp), %edi               # edi <- Buffer

+    movb    16(%esp), %al               # al <- Value

+    xorl    %ecx, %ecx

+    subl    %edi, %ecx

+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary

+    jz      L0

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx

+    rep

+    stosb

+L0:

+    movl    %edx, %ecx

+    andl    $15, %edx

+    shrl    $4, %ecx                    # ecx <- # of DQwords to set

+    jz      L_SetBytes

+    movb    %al, %ah                    # ax <- Value | (Value << 8)

+    addl    $-16, %esp

+    movdqu  %xmm0, (%esp)

+    movd    %eax, %xmm0

+    pshuflw $0, %xmm0, %xmm0

+    movlhps %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%edi)

+    addl    $16, %edi

+    loop   L1

+    mfence

+    movdqu  (%esp), %xmm0

+    addl    $16, %esp                   # stack cleanup

+L_SetBytes:

+    movl    %edx, %ecx

+    rep

+    stosb

+    movl    8(%esp), %eax               # eax <- Buffer as return value

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.asm
new file mode 100644
index 0000000..369cc00
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem.asm
@@ -0,0 +1,75 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    edi

+    mov     edx, [esp + 12]             ; edx <- Count

+    mov     edi, [esp + 8]              ; edi <- Buffer

+    mov     al, [esp + 16]              ; al <- Value

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4                      ; ecx <- # of DQwords to set

+    jz      @SetBytes

+    mov     ah, al                      ; ax <- Value | (Value << 8)

+    add     esp, -16

+    movdqu  [esp], xmm0                 ; save xmm0

+    movd    xmm0, eax

+    pshuflw xmm0, xmm0, 0               ; xmm0[0..63] <- Value repeats 8 times

+    movlhps xmm0, xmm0                  ; xmm0 <- Value repeats 16 times

+@@:

+    movntdq [edi], xmm0                 ; edi should be 16-byte aligned

+    add     edi, 16

+    loop    @B

+    mfence

+    movdqu  xmm0, [esp]                 ; restore xmm0

+    add     esp, 16                     ; stack cleanup

+@SetBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]              ; eax <- Buffer as return value

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.S
new file mode 100644
index 0000000..9222a18
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.S
@@ -0,0 +1,69 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem16.asm

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem16):

+    push    %edi

+    movl    12(%esp), %edx

+    movl    8(%esp), %edi

+    xorl    %ecx, %ecx

+    subl    %edi, %ecx

+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary

+    movl    16(%esp), %eax

+    jz      L0

+    shrl    %ecx

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx

+    rep

+    stosw

+L0:

+    movl    %edx, %ecx

+    andl    $7, %edx

+    shrl    $3, %ecx

+    jz      L_SetWords

+    movd    %eax, %xmm0

+    pshuflw $0, %xmm0, %xmm0

+    movlhps %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%edi)

+    addl    $16, %edi

+    loop    L1

+    mfence

+L_SetWords:

+    movl    %edx, %ecx

+    rep

+    stosw

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.asm
new file mode 100644
index 0000000..3725512
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem16.asm
@@ -0,0 +1,71 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    edi

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    mov     eax, [esp + 16]

+    jz      @F

+    shr     ecx, 1

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosw

+@@:

+    mov     ecx, edx

+    and     edx, 7

+    shr     ecx, 3

+    jz      @SetWords

+    movd    xmm0, eax

+    pshuflw xmm0, xmm0, 0

+    movlhps xmm0, xmm0

+@@:

+    movntdq [edi], xmm0                 ; edi should be 16-byte aligned

+    add     edi, 16

+    loop    @B

+    mfence

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.S
new file mode 100644
index 0000000..0edbaa2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.S
@@ -0,0 +1,68 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   SetMem32.asm

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem32):

+    push    %edi

+    movl    12(%esp), %edx

+    movl    8(%esp), %edi

+    xorl    %ecx, %ecx

+    subl    %edi, %ecx

+    andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary

+    movl    16(%esp), %eax

+    jz      L0

+    shrl    $2, %ecx

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx

+    rep

+    stosl

+L0:

+    movl    %edx, %ecx

+    andl    $3, %edx

+    shrl    $2, %ecx

+    jz      L_SetDwords

+    movd    %eax, %xmm0

+    pshufd  $0, %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%edi)

+    addl    $16, %edi

+    loop    L1

+    mfence

+L_SetDwords:

+    movl    %edx, %ecx

+    rep

+    stosl

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.asm
new file mode 100644
index 0000000..4c3aa42
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem32.asm
@@ -0,0 +1,70 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT32 Value

+;    );

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    edi

+    mov     edx, [esp + 12]

+    mov     edi, [esp + 8]

+    xor     ecx, ecx

+    sub     ecx, edi

+    and     ecx, 15                     ; ecx + edi aligns on 16-byte boundary

+    mov     eax, [esp + 16]

+    jz      @F

+    shr     ecx, 2

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosd

+@@:

+    mov     ecx, edx

+    and     edx, 3

+    shr     ecx, 2

+    jz      @SetDwords

+    movd    xmm0, eax

+    pshufd  xmm0, xmm0, 0

+@@:

+    movntdq [edi], xmm0

+    add     edi, 16

+    loop    @B

+    mfence

+@SetDwords:

+    mov     ecx, edx

+    rep     stosd

+    mov     eax, [esp + 8]

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.S
new file mode 100644
index 0000000..c9e6d63
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.S
@@ -0,0 +1,58 @@
+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006, 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemSetMem64):

+    movl    4(%esp), %eax

+    movl    8(%esp), %ecx

+    testb   $8, %al

+    movl    %eax, %edx

+    movq    0xc(%esp), %xmm0

+    jz      L1

+    movq    %xmm0, (%edx)

+    addl    $8, %edx

+    decl    %ecx

+L1:

+    shrl    %ecx

+    jz      L_SetQwords

+    movlhps %xmm0, %xmm0

+L2:

+    movntdq %xmm0, (%edx)

+    leal    16(%edx), %edx

+    loop    L2

+    mfence

+L_SetQwords:

+    jnc     L3

+    movq    %xmm0, (%edx)

+L3:

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.asm
new file mode 100644
index 0000000..d6f52a0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/SetMem64.asm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC

+    mov     eax, [esp + 4]              ; eax <- Buffer

+    mov     ecx, [esp + 8]              ; ecx <- Count

+    test    al, 8

+    mov     edx, eax

+    movq    xmm0, qword ptr [esp + 12]

+    jz      @F

+    movq    qword ptr [edx], xmm0

+    add     edx, 8

+    dec     ecx

+@@:

+    shr     ecx, 1

+    jz      @SetQwords

+    movlhps xmm0, xmm0

+@@:

+    movntdq [edx], xmm0

+    lea     edx, [edx + 16]

+    loop    @B

+    mfence

+@SetQwords:

+    jnc     @F

+    movq    qword ptr [edx], xmm0

+@@:

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.S
new file mode 100644
index 0000000..fc9f059
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.S
@@ -0,0 +1,65 @@
+#------------------------------------------------------------------------------

+#

+# 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.

+#

+# Module Name:

+#

+#   ZeroMem.asm

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_PFX(InternalMemZeroMem):

+    push    %edi

+    movl    8(%esp), %edi

+    movl    12(%esp), %edx

+    xorl    %ecx, %ecx

+    subl    %edi, %ecx

+    xorl    %eax, %eax

+    andl    $15, %ecx

+    jz      L0

+    cmpl    %edx, %ecx

+    cmova   %edx, %ecx

+    subl    %ecx, %edx

+    rep

+    stosb

+L0:

+    movl    %edx, %ecx

+    andl    $15, %edx

+    shrl    $4, %ecx

+    jz      L_ZeroBytes

+    pxor    %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%edi)

+    addl    $16, %edi

+    loop    L1

+    mfence

+L_ZeroBytes:

+    movl    %edx, %ecx

+    rep

+    stosb

+    movl    8(%esp), %eax

+    pop     %edi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.asm
new file mode 100644
index 0000000..97252b1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/Ia32/ZeroMem.asm
@@ -0,0 +1,67 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .686

+    .model  flat,C

+    .xmm

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    edi

+    mov     edi, [esp + 8]

+    mov     edx, [esp + 12]

+    xor     ecx, ecx

+    sub     ecx, edi

+    xor     eax, eax

+    and     ecx, 15

+    jz      @F

+    cmp     ecx, edx

+    cmova   ecx, edx

+    sub     edx, ecx

+    rep     stosb

+@@:

+    mov     ecx, edx

+    and     edx, 15

+    shr     ecx, 4

+    jz      @ZeroBytes

+    pxor    xmm0, xmm0

+@@:

+    movntdq [edi], xmm0

+    add     edi, 16

+    loop    @B

+    mfence

+@ZeroBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     eax, [esp + 8]

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibGuid.c
new file mode 100644
index 0000000..c04af6e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibInternals.h
new file mode 100644
index 0000000..c8e80af
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/MemLibInternals.h
@@ -0,0 +1,234 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Copy Length bytes from Source to Destination.

+

+  @param  DestinationBuffer The target of the copy request.

+  @param  SourceBuffer      The place to copy from.

+  @param  Length            The number of bytes to copy.

+

+  @return Destination

+

+**/

+VOID *

+EFIAPI

+InternalMemCopyMem (

+  OUT     VOID                      *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Set Buffer to Value for Size bytes.

+

+  @param  Buffer   The memory to set.

+  @param  Length   The number of bytes to set.

+  @param  Value    The value of the set operation.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer.

+  @param  SourceBuffer      The second memory buffer.

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return A pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem16Wrapper.c
new file mode 100644
index 0000000..4fd75fa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem32Wrapper.c
new file mode 100644
index 0000000..fb30fa5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem64Wrapper.c
new file mode 100644
index 0000000..fceb6d1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem8Wrapper.c
new file mode 100644
index 0000000..efbbe20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem16Wrapper.c
new file mode 100644
index 0000000..0ecfdae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem32Wrapper.c
new file mode 100644
index 0000000..f7ce307
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem64Wrapper.c
new file mode 100644
index 0000000..13d4b05
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
new file mode 100644
index 0000000..8a33927
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CompareMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CompareMem.S
new file mode 100644
index 0000000..26ed8dd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CompareMem.S
@@ -0,0 +1,59 @@
+#

+# ConvertAsm.py: Automatically generated from CompareMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CompareMem.S

+#

+# Abstract:

+#

+#   CompareMem function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# INTN

+# EFIAPI

+# InternalMemCompareMem (

+#   IN      CONST VOID                *DestinationBuffer,

+#   IN      CONST VOID                *SourceBuffer,

+#   IN      UINTN                     Length

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCompareMem)

+ASM_PFX(InternalMemCompareMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rcx, %rsi

+    movq    %rdx, %rdi

+    movq    %r8, %rcx

+    repe    cmpsb

+    movzbq  -1(%rsi) , %rax

+    movzbq  -1(%rdi) , %rdx

+    subq    %rdx, %rax

+    popq    %rdi

+    popq    %rsi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CompareMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CompareMem.asm
new file mode 100644
index 0000000..0ef05b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CompareMem.asm
@@ -0,0 +1,54 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   CompareMem.Asm

+;

+; Abstract:

+;

+;   CompareMem function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; INTN

+; EFIAPI

+; InternalMemCompareMem (

+;   IN      CONST VOID                *DestinationBuffer,

+;   IN      CONST VOID                *SourceBuffer,

+;   IN      UINTN                     Length

+;   );

+;------------------------------------------------------------------------------

+InternalMemCompareMem   PROC    USES    rsi rdi

+    mov     rsi, rcx

+    mov     rdi, rdx

+    mov     rcx, r8

+    repe    cmpsb

+    movzx   rax, byte ptr [rsi - 1]

+    movzx   rdx, byte ptr [rdi - 1]

+    sub     rax, rdx

+    ret

+InternalMemCompareMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CopyMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CopyMem.S
new file mode 100644
index 0000000..d8a58a7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CopyMem.S
@@ -0,0 +1,83 @@
+#

+# ConvertAsm.py: Automatically generated from CopyMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   CopyMem.S

+#

+# Abstract:

+#

+#   CopyMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemCopyMem (

+#    IN VOID   *Destination,

+#    IN VOID   *Source,

+#    IN UINTN  Count

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemCopyMem)

+ASM_PFX(InternalMemCopyMem):

+    pushq   %rsi

+    pushq   %rdi

+    movq    %rdx, %rsi                  # rsi <- Source

+    movq    %rcx, %rdi                  # rdi <- Destination

+    leaq    -1(%rsi, %r8,), %r9         # r9 <- Last byte of Source

+    cmpq    %rdi, %rsi

+    movq    %rdi, %rax                  # rax <- Destination as return value

+    jae     L0                          # Copy forward if Source > Destination

+    cmpq    %rdi, %r9                   # Overlapped?

+    jae     L_CopyBackward              # Copy backward if overlapped

+L0:            

+    xorq    %rcx, %rcx                    

+    subq    %rdi, %rcx                  # rcx <- -rdi

+    andq    $15, %rcx                   # rcx + rsi should be 16 bytes aligned

+    jz      L1                          # skip if rcx == 0

+    cmpq    %r8, %rcx

+    cmova   %r8, %rcx

+    subq    %rcx, %r8

+    rep     movsb

+L1:

+    movq    %r8, %rcx

+    andq    $15, %r8

+    shrq    $4, %rcx                    # rcx <- # of DQwords to copy

+    jz      L_CopyBytes

+    movdqa  %xmm0, 0x18(%rsp)           # save xmm0 on stack

+L2:

+    movdqu  (%rsi), %xmm0               # rsi may not be 16-byte aligned

+    movntdq  %xmm0, (%rdi)              # rdi should be 16-byte aligned

+    addq    $16, %rsi

+    addq    $16, %rdi

+    loop    L2

+    mfence

+    movdqa  0x18(%rsp), %xmm0           # restore xmm0

+    jmp     L_CopyBytes                 # copy remaining bytes

+L_CopyBackward:

+    movq    %r9, %rsi                   # rsi <- Last byte of Source

+    leaq    -1(%rdi, %r8,), %rdi        # rdi <- Last byte of Destination

+    std

+L_CopyBytes:

+    movq    %r8, %rcx

+    rep     movsb

+    cld

+    popq    %rdi

+    popq    %rsi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CopyMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CopyMem.asm
new file mode 100644
index 0000000..8bcaca7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/CopyMem.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   CopyMem.asm

+;

+; Abstract:

+;

+;   CopyMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  EFIAPI

+;  InternalMemCopyMem (

+;    IN VOID   *Destination,

+;    IN VOID   *Source,

+;    IN UINTN  Count

+;    );

+;------------------------------------------------------------------------------

+InternalMemCopyMem  PROC    USES    rsi rdi

+    mov     rsi, rdx                    ; rsi <- Source

+    mov     rdi, rcx                    ; rdi <- Destination

+    lea     r9, [rsi + r8 - 1]          ; r9 <- Last byte of Source

+    cmp     rsi, rdi

+    mov     rax, rdi                    ; rax <- Destination as return value

+    jae     @F                          ; Copy forward if Source > Destination

+    cmp     r9, rdi                     ; Overlapped?

+    jae     @CopyBackward               ; Copy backward if overlapped

+@@:

+    xor     rcx, rcx

+    sub     rcx, rdi                    ; rcx <- -rdi

+    and     rcx, 15                     ; rcx + rsi should be 16 bytes aligned

+    jz      @F                          ; skip if rcx == 0

+    cmp     rcx, r8

+    cmova   rcx, r8

+    sub     r8, rcx

+    rep     movsb

+@@:

+    mov     rcx, r8

+    and     r8, 15

+    shr     rcx, 4                      ; rcx <- # of DQwords to copy

+    jz      @CopyBytes

+    movdqa  [rsp + 18h], xmm0           ; save xmm0 on stack

+@@:

+    movdqu  xmm0, [rsi]                 ; rsi may not be 16-byte aligned

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rsi, 16

+    add     rdi, 16

+    loop    @B

+    mfence

+    movdqa  xmm0, [rsp + 18h]           ; restore xmm0

+    jmp     @CopyBytes                  ; copy remaining bytes

+@CopyBackward:

+    mov     rsi, r9                     ; rsi <- Last byte of Source

+    lea     rdi, [rdi + r8 - 1]         ; rdi <- Last byte of Destination

+    std

+@CopyBytes:

+    mov     rcx, r8

+    rep     movsb

+    cld

+    ret

+InternalMemCopyMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem16.S
new file mode 100644
index 0000000..282dc3c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem16.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem16.S

+#

+# Abstract:

+#

+#   ScanMem16 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem16 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT16                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem16)

+ASM_PFX(InternalMemScanMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasw

+    leaq    -2(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem16.asm
new file mode 100644
index 0000000..a6114db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem16.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem16.Asm

+;

+; Abstract:

+;

+;   ScanMem16 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem16 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT16                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem16    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasw

+    lea     rax, [rdi - 2]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem16    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem32.S
new file mode 100644
index 0000000..eb91daf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem32.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem32.S

+#

+# Abstract:

+#

+#   ScanMem32 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem32 (

+#   IN      CONST VOID          *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT32                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem32)

+ASM_PFX(InternalMemScanMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasl

+    leaq    -4(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem32.asm
new file mode 100644
index 0000000..40ff6c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem32.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem32.Asm

+;

+; Abstract:

+;

+;   ScanMem32 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem32 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT32                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem32    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasd

+    lea     rax, [rdi - 4]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem32    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem64.S
new file mode 100644
index 0000000..20d20aa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem64.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem64.S

+#

+# Abstract:

+#

+#   ScanMem64 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem64 (

+#   IN      CONST VOID          *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT64                    Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem64)

+ASM_PFX(InternalMemScanMem64):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasq

+    leaq    -8(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem64.asm
new file mode 100644
index 0000000..e78da7d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem64.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem64.Asm

+;

+; Abstract:

+;

+;   ScanMem64 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem64 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT64                    Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem64    PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rax, r8

+    mov     rcx, rdx

+    repne   scasq

+    lea     rax, [rdi - 8]

+    cmovnz  rax, rcx

+    ret

+InternalMemScanMem64    ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem8.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem8.S
new file mode 100644
index 0000000..b1715ea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem8.S
@@ -0,0 +1,56 @@
+#

+# ConvertAsm.py: Automatically generated from ScanMem8.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ScanMem8.S

+#

+# Abstract:

+#

+#   ScanMem8 function

+#

+# Notes:

+#

+#   The following BaseMemoryLib instances contain the same copy of this file:

+#

+#       BaseMemoryLibRepStr

+#       BaseMemoryLibMmx

+#       BaseMemoryLibSse2

+#       BaseMemoryLibOptDxe

+#       BaseMemoryLibOptPei

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+# CONST VOID *

+# EFIAPI

+# InternalMemScanMem8 (

+#   IN      CONST VOID                *Buffer,

+#   IN      UINTN                     Length,

+#   IN      UINT8                     Value

+#   );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemScanMem8)

+ASM_PFX(InternalMemScanMem8):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdx, %rcx

+    movq    %r8, %rax

+    repne   scasb

+    leaq    -1(%rdi), %rax

+    cmovnz  %rcx, %rax                    # set rax to 0 if not found

+    popq    %rdi

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem8.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem8.asm
new file mode 100644
index 0000000..fee2397
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ScanMem8.asm
@@ -0,0 +1,53 @@
+;------------------------------------------------------------------------------

+;

+; 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.

+;

+; Module Name:

+;

+;   ScanMem8.Asm

+;

+; Abstract:

+;

+;   ScanMem8 function

+;

+; Notes:

+;

+;   The following BaseMemoryLib instances contain the same copy of this file:

+;

+;       BaseMemoryLibRepStr

+;       BaseMemoryLibMmx

+;       BaseMemoryLibSse2

+;       BaseMemoryLibOptDxe

+;       BaseMemoryLibOptPei

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; CONST VOID *

+; EFIAPI

+; InternalMemScanMem8 (

+;   IN      CONST VOID                *Buffer,

+;   IN      UINTN                     Length,

+;   IN      UINT8                     Value

+;   );

+;------------------------------------------------------------------------------

+InternalMemScanMem8 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     rcx, rdx

+    mov     rax, r8

+    repne   scasb

+    lea     rax, [rdi - 1]

+    cmovnz  rax, rcx                    ; set rax to 0 if not found

+    ret

+InternalMemScanMem8 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem.S
new file mode 100644
index 0000000..eb4ce80
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem.S
@@ -0,0 +1,72 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem.S

+#

+# Abstract:

+#

+#   SetMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT8  Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem)

+ASM_PFX(InternalMemSetMem):

+    pushq   %rdi

+    movq    %rcx, %rdi                  # rdi <- Buffer

+    movb    %r8b, %al                   # al <- Value

+    movq    %rdi, %r9                   # r9 <- Buffer as return value

+    xorq    %rcx, %rcx

+    subq    %rdi, %rcx

+    andq    $15, %rcx                   # rcx + rdi aligns on 16-byte boundary

+    jz      L0

+    cmpq    %rdx, %rcx

+    cmova   %rdx, %rcx

+    subq    %rcx, %rdx

+    rep     stosb

+L0:

+    movq    %rdx, %rcx

+    andq    $15, %rdx

+    shrq    $4, %rcx

+    jz      L_SetBytes

+    movb    %al, %ah                    # ax <- Value repeats twice

+    movdqa  %xmm0, 0x10(%rsp)           # save xmm0

+    movd    %eax, %xmm0                 # xmm0[0..16] <- Value repeats twice

+    pshuflw $0, %xmm0, %xmm0            # xmm0[0..63] <- Value repeats 8 times

+    movlhps %xmm0, %xmm0                # xmm0 <- Value repeats 16 times

+L1:

+    movntdq %xmm0, (%rdi)               # rdi should be 16-byte aligned

+    add     $16, %rdi

+    loop    L1

+    mfence

+    movdqa  0x10(%rsp), %xmm0           # restore xmm0

+L_SetBytes:

+    movl    %edx, %ecx                  # high 32 bits of rcx are always zero

+    rep     stosb

+    movq    %r9, %rax                   # rax <- Return value

+    popq    %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem.asm
new file mode 100644
index 0000000..52b069c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem.asm
@@ -0,0 +1,69 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem.asm

+;

+; Abstract:

+;

+;   SetMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem   PROC    USES    rdi

+    mov     rdi, rcx                    ; rdi <- Buffer

+    mov     al, r8b                     ; al <- Value

+    mov     r9, rdi                     ; r9 <- Buffer as return value

+    xor     rcx, rcx

+    sub     rcx, rdi

+    and     rcx, 15                     ; rcx + rdi aligns on 16-byte boundary

+    jz      @F

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosb

+@@:

+    mov     rcx, rdx

+    and     rdx, 15

+    shr     rcx, 4

+    jz      @SetBytes

+    mov     ah, al                      ; ax <- Value repeats twice

+    movdqa  [rsp + 10h], xmm0           ; save xmm0

+    movd    xmm0, eax                   ; xmm0[0..16] <- Value repeats twice

+    pshuflw xmm0, xmm0, 0               ; xmm0[0..63] <- Value repeats 8 times

+    movlhps xmm0, xmm0                  ; xmm0 <- Value repeats 16 times

+@@:

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rdi, 16

+    loop    @B

+    mfence

+    movdqa  xmm0, [rsp + 10h]           ; restore xmm0

+@SetBytes:

+    mov     ecx, edx                    ; high 32 bits of rcx are always zero

+    rep     stosb

+    mov     rax, r9                     ; rax <- Return value

+    ret

+InternalMemSetMem   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem16.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem16.S
new file mode 100644
index 0000000..74fef09
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem16.S
@@ -0,0 +1,70 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem16.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem16.S

+#

+# Abstract:

+#

+#   SetMem16 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem16 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT16 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem16)

+ASM_PFX(InternalMemSetMem16):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdi, %r9

+    xorq    %rcx, %rcx

+    subq    %rdi, %rcx

+    andq    $15, %rcx

+    movq    %r8, %rax

+    jz      L0

+    shrq    $1, %rcx

+    cmpq    %rdx, %rcx

+    cmova   %rdx, %rcx

+    subq    %rcx, %rdx

+    rep     stosw

+L0:

+    movq    %rdx, %rcx

+    andl    $7, %edx

+    shrq    $3, %rcx

+    jz      L_SetWords

+    movd    %eax, %xmm0

+    pshuflw $0, %xmm0, %xmm0

+    movlhps %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%rdi)

+    addq    $16, %rdi

+    loop    L1

+    mfence

+L_SetWords:

+    movl    %edx, %ecx

+    rep     stosw

+    movq    %r9, %rax

+    popq    %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem16.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem16.asm
new file mode 100644
index 0000000..8cb09ac
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem16.asm
@@ -0,0 +1,67 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem16.asm

+;

+; Abstract:

+;

+;   SetMem16 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem16 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT16 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem16 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     r9, rdi

+    xor     rcx, rcx

+    sub     rcx, rdi

+    and     rcx, 15

+    mov     rax, r8

+    jz      @F

+    shr     rcx, 1

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosw

+@@:

+    mov     rcx, rdx

+    and     edx, 7

+    shr     rcx, 3

+    jz      @SetWords

+    movd    xmm0, eax

+    pshuflw xmm0, xmm0, 0

+    movlhps xmm0, xmm0

+@@:

+    movntdq [rdi], xmm0

+    add     rdi, 16

+    loop    @B

+    mfence

+@SetWords:

+    mov     ecx, edx

+    rep     stosw

+    mov     rax, r9

+    ret

+InternalMemSetMem16 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem32.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem32.S
new file mode 100644
index 0000000..24103cf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem32.S
@@ -0,0 +1,69 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem32.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem32.S

+#

+# Abstract:

+#

+#   SetMem32 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  EFIAPI

+#  InternalMemSetMem32 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT32 Value

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem32)

+ASM_PFX(InternalMemSetMem32):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    movq    %rdi, %r9

+    xorq    %rcx, %rcx

+    subq    %rdi, %rcx

+    andq    $15, %rcx

+    movq    %r8, %rax

+    jz      L0

+    shrq    $2, %rcx

+    cmpq    %rdx, %rcx

+    cmova   %rdx, %rcx

+    subq    %rcx, %rdx

+    rep     stosl

+L0:

+    movq    %rdx, %rcx

+    andl    $3, %edx

+    shrq    $2, %rcx

+    jz      L_SetDwords

+    movd    %eax, %xmm0

+    pshufd  $0, %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%rdi)

+    addq    $16, %rdi

+    loop    L1

+    mfence

+L_SetDwords:

+    movl    %edx, %ecx

+    rep     stosl

+    movq    %r9, %rax

+    popq    %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem32.asm
new file mode 100644
index 0000000..92404a0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem32.asm
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem32.asm

+;

+; Abstract:

+;

+;   SetMem32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem32 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT8  Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem32 PROC    USES    rdi

+    mov     rdi, rcx

+    mov     r9, rdi

+    xor     rcx, rcx

+    sub     rcx, rdi

+    and     rcx, 15

+    mov     rax, r8

+    jz      @F

+    shr     rcx, 2

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosd

+@@:

+    mov     rcx, rdx

+    and     edx, 3

+    shr     rcx, 2

+    jz      @SetDwords

+    movd    xmm0, eax

+    pshufd  xmm0, xmm0, 0

+@@:

+    movntdq [rdi], xmm0

+    add     rdi, 16

+    loop    @B

+    mfence

+@SetDwords:

+    mov     ecx, edx

+    rep     stosd

+    mov     rax, r9

+    ret

+InternalMemSetMem32 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem64.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem64.S
new file mode 100644
index 0000000..c44ec08
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem64.S
@@ -0,0 +1,60 @@
+#

+# ConvertAsm.py: Automatically generated from SetMem64.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   SetMem64.S

+#

+# Abstract:

+#

+#   SetMem64 function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemSetMem64 (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count,

+#    IN UINT64 Value

+#    )

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemSetMem64)

+ASM_PFX(InternalMemSetMem64):

+    movq    %rcx, %rax                    # rax <- Buffer

+    xchgq   %rdx, %rcx                    # rcx <- Count & rdx <- Buffer

+    testb   $8, %dl

+    movd    %r8, %xmm0

+    jz      L0

+    movq    %r8, (%rdx)

+    addq    $8, %rdx

+    decq    %rcx

+L0:

+    shrq    $1, %rcx

+    jz      L_SetQwords

+    movlhps %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%rdx)

+    leaq    16(%rdx), %rdx

+    loop    L1

+    mfence

+L_SetQwords:

+    jnc     L2

+    movq    %r8, (%rdx)

+L2:

+    ret

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem64.asm
new file mode 100644
index 0000000..5071f67
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/SetMem64.asm
@@ -0,0 +1,59 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   SetMem64.asm

+;

+; Abstract:

+;

+;   SetMem64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemSetMem64 (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count,

+;    IN UINT64 Value

+;    )

+;------------------------------------------------------------------------------

+InternalMemSetMem64 PROC

+    mov     rax, rcx                    ; rax <- Buffer

+    xchg    rcx, rdx                    ; rcx <- Count & rdx <- Buffer

+    test    dl, 8

+    movd    xmm0, r8

+    jz      @F

+    mov     [rdx], r8

+    add     rdx, 8

+    dec     rcx

+@@:

+    shr     rcx, 1

+    jz      @SetQwords

+    movlhps xmm0, xmm0

+@@:

+    movntdq [rdx], xmm0

+    lea     rdx, [rdx + 16]

+    loop    @B

+    mfence

+@SetQwords:

+    jnc     @F

+    mov     [rdx], r8

+@@:

+    ret

+InternalMemSetMem64 ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ZeroMem.S b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ZeroMem.S
new file mode 100644
index 0000000..3b00ce7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ZeroMem.S
@@ -0,0 +1,65 @@
+#

+# ConvertAsm.py: Automatically generated from ZeroMem.asm

+#

+#------------------------------------------------------------------------------

+#

+# Copyright (c) 2006 - 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.

+#

+# Module Name:

+#

+#   ZeroMem.S

+#

+# Abstract:

+#

+#   ZeroMem function

+#

+# Notes:

+#

+#------------------------------------------------------------------------------

+

+

+#------------------------------------------------------------------------------

+#  VOID *

+#  InternalMemZeroMem (

+#    IN VOID   *Buffer,

+#    IN UINTN  Count

+#    );

+#------------------------------------------------------------------------------

+ASM_GLOBAL ASM_PFX(InternalMemZeroMem)

+ASM_PFX(InternalMemZeroMem):

+    pushq   %rdi

+    movq    %rcx, %rdi

+    xorq    %rcx, %rcx

+    xorl    %eax, %eax

+    subq    %rdi, %rcx

+    andq    $15, %rcx

+    movq    %rdi, %r8

+    jz      L0

+    cmpq    %rdx, %rcx

+    cmova   %rdx, %rcx

+    subq    %rcx, %rdx

+    rep     stosb

+L0:

+    movq    %rdx, %rcx

+    andl    $15, %edx

+    shrq    $4, %rcx

+    jz      L_ZeroBytes

+    pxor    %xmm0, %xmm0

+L1:

+    movntdq %xmm0, (%rdi)                 # rdi should be 16-byte aligned

+    addq    $16, %rdi

+    loop    L1

+    mfence

+L_ZeroBytes:

+    movl    %edx, %ecx

+    rep     stosb

+    movq    %r8, %rax

+    popq    %rdi

+    ret

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ZeroMem.asm b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ZeroMem.asm
new file mode 100644
index 0000000..d304729
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/X64/ZeroMem.asm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   ZeroMem.asm

+;

+; Abstract:

+;

+;   ZeroMem function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+;  VOID *

+;  InternalMemZeroMem (

+;    IN VOID   *Buffer,

+;    IN UINTN  Count

+;    )

+;------------------------------------------------------------------------------

+InternalMemZeroMem  PROC    USES    rdi

+    mov     rdi, rcx

+    xor     rcx, rcx

+    xor     eax, eax

+    sub     rcx, rdi

+    and     rcx, 15

+    mov     r8, rdi

+    jz      @F

+    cmp     rcx, rdx

+    cmova   rcx, rdx

+    sub     rdx, rcx

+    rep     stosb

+@@:

+    mov     rcx, rdx

+    and     edx, 15

+    shr     rcx, 4

+    jz      @ZeroBytes

+    pxor    xmm0, xmm0

+@@:

+    movntdq [rdi], xmm0                 ; rdi should be 16-byte aligned

+    add     rdi, 16

+    loop    @B

+    mfence

+@ZeroBytes:

+    mov     ecx, edx

+    rep     stosb

+    mov     rax, r8

+    ret

+InternalMemZeroMem  ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ZeroMemWrapper.c
new file mode 100644
index 0000000..2a0a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseMemoryLibSse2/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.c
new file mode 100644
index 0000000..8d18a4b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.c
@@ -0,0 +1,1454 @@
+/** @file

+  An OrderedCollectionLib instance that provides a red-black tree

+  implementation, and allocates and releases tree nodes with

+  MemoryAllocationLib.

+

+  This library instance is useful when a fast associative container is needed.

+  Worst case time complexity is O(log n) for Find(), Next(), Prev(), Min(),

+  Max(), Insert(), and Delete(), where "n" is the number of elements in the

+  tree. Complete ordered traversal takes O(n) time.

+

+  The implementation is also useful as a fast priority queue.

+

+  Copyright (C) 2014, Red Hat, Inc.

+  Copyright (c) 2014, 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.

+**/

+

+#include <Library/OrderedCollectionLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+

+typedef enum {

+  RedBlackTreeRed,

+  RedBlackTreeBlack

+} RED_BLACK_TREE_COLOR;

+

+//

+// Incomplete types and convenience typedefs are present in the library class

+// header. Beside completing the types, we introduce typedefs here that reflect

+// the implementation closely.

+//

+typedef ORDERED_COLLECTION              RED_BLACK_TREE;

+typedef ORDERED_COLLECTION_ENTRY        RED_BLACK_TREE_NODE;

+typedef ORDERED_COLLECTION_USER_COMPARE RED_BLACK_TREE_USER_COMPARE;

+typedef ORDERED_COLLECTION_KEY_COMPARE  RED_BLACK_TREE_KEY_COMPARE;

+

+struct ORDERED_COLLECTION {

+  RED_BLACK_TREE_NODE         *Root;

+  RED_BLACK_TREE_USER_COMPARE UserStructCompare;

+  RED_BLACK_TREE_KEY_COMPARE  KeyCompare;

+};

+

+struct ORDERED_COLLECTION_ENTRY {

+  VOID                 *UserStruct;

+  RED_BLACK_TREE_NODE  *Parent;

+  RED_BLACK_TREE_NODE  *Left;

+  RED_BLACK_TREE_NODE  *Right;

+  RED_BLACK_TREE_COLOR Color;

+};

+

+

+/**

+  Retrieve the user structure linked by the specified tree node.

+

+  Read-only operation.

+

+  @param[in] Node  Pointer to the tree node whose associated user structure we

+                   want to retrieve. The caller is responsible for passing a

+                   non-NULL argument.

+

+  @return  Pointer to user structure linked by Node.

+**/

+VOID *

+EFIAPI

+OrderedCollectionUserStruct (

+  IN CONST RED_BLACK_TREE_NODE *Node

+  )

+{

+  return Node->UserStruct;

+}

+

+/**

+  A slow function that asserts that the tree is a valid red-black tree, and

+  that it orders user structures correctly.

+

+  Read-only operation.

+

+  This function uses the stack for recursion and is not recommended for

+  "production use".

+

+  @param[in] Tree  The tree to validate.

+**/

+VOID

+RedBlackTreeValidate (

+  IN CONST RED_BLACK_TREE *Tree

+  );

+

+

+/**

+  Allocate and initialize the RED_BLACK_TREE structure.

+

+  Allocation occurs via MemoryAllocationLib's AllocatePool() function.

+

+  @param[in]  UserStructCompare  This caller-provided function will be used to

+                                 order two user structures linked into the

+                                 tree, during the insertion procedure.

+

+  @param[in]  KeyCompare         This caller-provided function will be used to

+                                 order the standalone search key against user

+                                 structures linked into the tree, during the

+                                 lookup procedure.

+

+  @retval NULL  If allocation failed.

+

+  @return       Pointer to the allocated, initialized RED_BLACK_TREE structure,

+                otherwise.

+**/

+RED_BLACK_TREE *

+EFIAPI

+OrderedCollectionInit (

+  IN RED_BLACK_TREE_USER_COMPARE UserStructCompare,

+  IN RED_BLACK_TREE_KEY_COMPARE  KeyCompare

+  )

+{

+  RED_BLACK_TREE *Tree;

+

+  Tree = AllocatePool (sizeof *Tree);

+  if (Tree == NULL) {

+    return NULL;

+  }

+

+  Tree->Root              = NULL;

+  Tree->UserStructCompare = UserStructCompare;

+  Tree->KeyCompare        = KeyCompare;

+

+  if (FeaturePcdGet (PcdValidateOrderedCollection)) {

+    RedBlackTreeValidate (Tree);

+  }

+  return Tree;

+}

+

+

+/**

+  Check whether the tree is empty (has no nodes).

+

+  Read-only operation.

+

+  @param[in] Tree  The tree to check for emptiness.

+

+  @retval TRUE   The tree is empty.

+

+  @retval FALSE  The tree is not empty.

+**/

+BOOLEAN

+EFIAPI

+OrderedCollectionIsEmpty (

+  IN CONST RED_BLACK_TREE *Tree

+  )

+{

+  return (BOOLEAN)(Tree->Root == NULL);

+}

+

+

+/**

+  Uninitialize and release an empty RED_BLACK_TREE structure.

+

+  Read-write operation.

+

+  Release occurs via MemoryAllocationLib's FreePool() function.

+

+  It is the caller's responsibility to delete all nodes from the tree before

+  calling this function.

+

+  @param[in] Tree  The empty tree to uninitialize and release.

+**/

+VOID

+EFIAPI

+OrderedCollectionUninit (

+  IN RED_BLACK_TREE *Tree

+  )

+{

+  ASSERT (OrderedCollectionIsEmpty (Tree));

+  FreePool (Tree);

+}

+

+

+/**

+  Look up the tree node that links the user structure that matches the

+  specified standalone key.

+

+  Read-only operation.

+

+  @param[in] Tree           The tree to search for StandaloneKey.

+

+  @param[in] StandaloneKey  The key to locate among the user structures linked

+                            into Tree. StandaloneKey will be passed to

+                            Tree->KeyCompare().

+

+  @retval NULL  StandaloneKey could not be found.

+

+  @return       The tree node that links to the user structure matching

+                StandaloneKey, otherwise.

+**/

+RED_BLACK_TREE_NODE *

+EFIAPI

+OrderedCollectionFind (

+  IN CONST RED_BLACK_TREE *Tree,

+  IN CONST VOID           *StandaloneKey

+  )

+{

+  RED_BLACK_TREE_NODE *Node;

+

+  Node = Tree->Root;

+  while (Node != NULL) {

+    INTN Result;

+

+    Result = Tree->KeyCompare (StandaloneKey, Node->UserStruct);

+    if (Result == 0) {

+      break;

+    }

+    Node = (Result < 0) ? Node->Left : Node->Right;

+  }

+  return Node;

+}

+

+

+/**

+  Find the tree node of the minimum user structure stored in the tree.

+

+  Read-only operation.

+

+  @param[in] Tree  The tree to return the minimum node of. The user structure

+                   linked by the minimum node compares less than all other user

+                   structures in the tree.

+

+  @retval NULL  If Tree is empty.

+

+  @return       The tree node that links the minimum user structure, otherwise.

+**/

+RED_BLACK_TREE_NODE *

+EFIAPI

+OrderedCollectionMin (

+  IN CONST RED_BLACK_TREE *Tree

+  )

+{

+  RED_BLACK_TREE_NODE *Node;

+

+  Node = Tree->Root;

+  if (Node == NULL) {

+    return NULL;

+  }

+  while (Node->Left != NULL) {

+    Node = Node->Left;

+  }

+  return Node;

+}

+

+

+/**

+  Find the tree node of the maximum user structure stored in the tree.

+

+  Read-only operation.

+

+  @param[in] Tree  The tree to return the maximum node of. The user structure

+                   linked by the maximum node compares greater than all other

+                   user structures in the tree.

+

+  @retval NULL  If Tree is empty.

+

+  @return       The tree node that links the maximum user structure, otherwise.

+**/

+RED_BLACK_TREE_NODE *

+EFIAPI

+OrderedCollectionMax (

+  IN CONST RED_BLACK_TREE *Tree

+  )

+{

+  RED_BLACK_TREE_NODE *Node;

+

+  Node = Tree->Root;

+  if (Node == NULL) {

+    return NULL;

+  }

+  while (Node->Right != NULL) {

+    Node = Node->Right;

+  }

+  return Node;

+}

+

+

+/**

+  Get the tree node of the least user structure that is greater than the one

+  linked by Node.

+

+  Read-only operation.

+

+  @param[in] Node  The node to get the successor node of.

+

+  @retval NULL  If Node is NULL, or Node is the maximum node of its containing

+                tree (ie. Node has no successor node).

+

+  @return       The tree node linking the least user structure that is greater

+                than the one linked by Node, otherwise.

+**/

+RED_BLACK_TREE_NODE *

+EFIAPI

+OrderedCollectionNext (

+  IN CONST RED_BLACK_TREE_NODE *Node

+  )

+{

+  RED_BLACK_TREE_NODE       *Walk;

+  CONST RED_BLACK_TREE_NODE *Child;

+

+  if (Node == NULL) {

+    return NULL;

+  }

+

+  //

+  // If Node has a right subtree, then the successor is the minimum node of

+  // that subtree.

+  //

+  Walk = Node->Right;

+  if (Walk != NULL) {

+    while (Walk->Left != NULL) {

+      Walk = Walk->Left;

+    }

+    return Walk;

+  }

+

+  //

+  // Otherwise we have to ascend as long as we're our parent's right child (ie.

+  // ascending to the left).

+  //

+  Child = Node;

+  Walk = Child->Parent;

+  while (Walk != NULL && Child == Walk->Right) {

+    Child = Walk;

+    Walk = Child->Parent;

+  }

+  return Walk;

+}

+

+

+/**

+  Get the tree node of the greatest user structure that is less than the one

+  linked by Node.

+

+  Read-only operation.

+

+  @param[in] Node  The node to get the predecessor node of.

+

+  @retval NULL  If Node is NULL, or Node is the minimum node of its containing

+                tree (ie. Node has no predecessor node).

+

+  @return       The tree node linking the greatest user structure that is less

+                than the one linked by Node, otherwise.

+**/

+RED_BLACK_TREE_NODE *

+EFIAPI

+OrderedCollectionPrev (

+  IN CONST RED_BLACK_TREE_NODE *Node

+  )

+{

+  RED_BLACK_TREE_NODE       *Walk;

+  CONST RED_BLACK_TREE_NODE *Child;

+

+  if (Node == NULL) {

+    return NULL;

+  }

+

+  //

+  // If Node has a left subtree, then the predecessor is the maximum node of

+  // that subtree.

+  //

+  Walk = Node->Left;

+  if (Walk != NULL) {

+    while (Walk->Right != NULL) {

+      Walk = Walk->Right;

+    }

+    return Walk;

+  }

+

+  //

+  // Otherwise we have to ascend as long as we're our parent's left child (ie.

+  // ascending to the right).

+  //

+  Child = Node;

+  Walk = Child->Parent;

+  while (Walk != NULL && Child == Walk->Left) {

+    Child = Walk;

+    Walk = Child->Parent;

+  }

+  return Walk;

+}

+

+

+/**

+  Rotate tree nodes around Pivot to the right.

+

+                Parent                       Parent

+                  |                            |

+                Pivot                      LeftChild

+               /     .                    .         \_

+      LeftChild       Node1   --->   Node2           Pivot

+         . \                                          / .

+    Node2   LeftRightChild              LeftRightChild   Node1

+

+  The ordering Node2 < LeftChild < LeftRightChild < Pivot < Node1 is kept

+  intact. Parent (if any) is either at the left extreme or the right extreme of

+  this ordering, and that relation is also kept intact.

+

+  Edges marked with a dot (".") don't change during rotation.

+

+  Internal read-write operation.

+

+  @param[in,out] Pivot    The tree node to rotate other nodes right around. It

+                          is the caller's responsibility to ensure that

+                          Pivot->Left is not NULL.

+

+  @param[out]    NewRoot  If Pivot has a parent node on input, then the

+                          function updates Pivot's original parent on output

+                          according to the rotation, and NewRoot is not

+                          accessed.

+

+                          If Pivot has no parent node on input (ie. Pivot is

+                          the root of the tree), then the function stores the

+                          new root node of the tree in NewRoot.

+**/

+VOID

+RedBlackTreeRotateRight (

+  IN OUT RED_BLACK_TREE_NODE *Pivot,

+  OUT    RED_BLACK_TREE_NODE **NewRoot

+  )

+{

+  RED_BLACK_TREE_NODE *Parent;

+  RED_BLACK_TREE_NODE *LeftChild;

+  RED_BLACK_TREE_NODE *LeftRightChild;

+

+  Parent         = Pivot->Parent;

+  LeftChild      = Pivot->Left;

+  LeftRightChild = LeftChild->Right;

+

+  Pivot->Left = LeftRightChild;

+  if (LeftRightChild != NULL) {

+    LeftRightChild->Parent = Pivot;

+  }

+  LeftChild->Parent = Parent;

+  if (Parent == NULL) {

+    *NewRoot = LeftChild;

+  } else {

+    if (Pivot == Parent->Left) {

+      Parent->Left = LeftChild;

+    } else {

+      Parent->Right = LeftChild;

+    }

+  }

+  LeftChild->Right = Pivot;

+  Pivot->Parent = LeftChild;

+}

+

+

+/**

+  Rotate tree nodes around Pivot to the left.

+

+          Parent                                 Parent

+            |                                      |

+          Pivot                                RightChild

+         .     \                              /          .

+    Node1       RightChild    --->       Pivot            Node2

+                    /.                    . \_

+      RightLeftChild  Node2          Node1   RightLeftChild

+

+  The ordering Node1 < Pivot < RightLeftChild < RightChild < Node2 is kept

+  intact. Parent (if any) is either at the left extreme or the right extreme of

+  this ordering, and that relation is also kept intact.

+

+  Edges marked with a dot (".") don't change during rotation.

+

+  Internal read-write operation.

+

+  @param[in,out] Pivot    The tree node to rotate other nodes left around. It

+                          is the caller's responsibility to ensure that

+                          Pivot->Right is not NULL.

+

+  @param[out]    NewRoot  If Pivot has a parent node on input, then the

+                          function updates Pivot's original parent on output

+                          according to the rotation, and NewRoot is not

+                          accessed.

+

+                          If Pivot has no parent node on input (ie. Pivot is

+                          the root of the tree), then the function stores the

+                          new root node of the tree in NewRoot.

+**/

+VOID

+RedBlackTreeRotateLeft (

+  IN OUT RED_BLACK_TREE_NODE *Pivot,

+  OUT    RED_BLACK_TREE_NODE **NewRoot

+  )

+{

+  RED_BLACK_TREE_NODE *Parent;

+  RED_BLACK_TREE_NODE *RightChild;

+  RED_BLACK_TREE_NODE *RightLeftChild;

+

+  Parent         = Pivot->Parent;

+  RightChild     = Pivot->Right;

+  RightLeftChild = RightChild->Left;

+

+  Pivot->Right = RightLeftChild;

+  if (RightLeftChild != NULL) {

+    RightLeftChild->Parent = Pivot;

+  }

+  RightChild->Parent = Parent;

+  if (Parent == NULL) {

+    *NewRoot = RightChild;

+  } else {

+    if (Pivot == Parent->Left) {

+      Parent->Left = RightChild;

+    } else {

+      Parent->Right = RightChild;

+    }

+  }

+  RightChild->Left = Pivot;

+  Pivot->Parent = RightChild;

+}

+

+

+/**

+  Insert (link) a user structure into the tree.

+

+  Read-write operation.

+

+  This function allocates the new tree node with MemoryAllocationLib's

+  AllocatePool() function.

+

+  @param[in,out] Tree        The tree to insert UserStruct into.

+

+  @param[out]    Node        The meaning of this optional, output-only

+                             parameter depends on the return value of the

+                             function.

+

+                             When insertion is successful (RETURN_SUCCESS),

+                             Node is set on output to the new tree node that

+                             now links UserStruct.

+

+                             When insertion fails due to lack of memory

+                             (RETURN_OUT_OF_RESOURCES), Node is not changed.

+

+                             When insertion fails due to key collision (ie.

+                             another user structure is already in the tree that

+                             compares equal to UserStruct), with return value

+                             RETURN_ALREADY_STARTED, then Node is set on output

+                             to the node that links the colliding user

+                             structure. This enables "find-or-insert" in one

+                             function call, or helps with later removal of the

+                             colliding element.

+

+  @param[in]     UserStruct  The user structure to link into the tree.

+                             UserStruct is ordered against in-tree user

+                             structures with the Tree->UserStructCompare()

+                             function.

+

+  @retval RETURN_SUCCESS           Insertion successful. A new tree node has

+                                   been allocated, linking UserStruct. The new

+                                   tree node is reported back in Node (if the

+                                   caller requested it).

+

+                                   Existing RED_BLACK_TREE_NODE pointers into

+                                   Tree remain valid. For example, on-going

+                                   iterations in the caller can continue with

+                                   OrderedCollectionNext() /

+                                   OrderedCollectionPrev(), and they will

+                                   return the new node at some point if user

+                                   structure order dictates it.

+

+  @retval RETURN_OUT_OF_RESOURCES  AllocatePool() failed to allocate memory for

+                                   the new tree node. The tree has not been

+                                   changed. Existing RED_BLACK_TREE_NODE

+                                   pointers into Tree remain valid.

+

+  @retval RETURN_ALREADY_STARTED   A user structure has been found in the tree

+                                   that compares equal to UserStruct. The node

+                                   linking the colliding user structure is

+                                   reported back in Node (if the caller

+                                   requested it). The tree has not been

+                                   changed. Existing RED_BLACK_TREE_NODE

+                                   pointers into Tree remain valid.

+**/

+RETURN_STATUS

+EFIAPI

+OrderedCollectionInsert (

+  IN OUT RED_BLACK_TREE      *Tree,

+  OUT    RED_BLACK_TREE_NODE **Node      OPTIONAL,

+  IN     VOID                *UserStruct

+  )

+{

+  RED_BLACK_TREE_NODE *Tmp;

+  RED_BLACK_TREE_NODE *Parent;

+  INTN                Result;

+  RETURN_STATUS       Status;

+  RED_BLACK_TREE_NODE *NewRoot;

+

+  Tmp = Tree->Root;

+  Parent = NULL;

+  Result = 0;

+

+  //

+  // First look for a collision, saving the last examined node for the case

+  // when there's no collision.

+  //

+  while (Tmp != NULL) {

+    Result = Tree->UserStructCompare (UserStruct, Tmp->UserStruct);

+    if (Result == 0) {

+      break;

+    }

+    Parent = Tmp;

+    Tmp = (Result < 0) ? Tmp->Left : Tmp->Right;

+  }

+

+  if (Tmp != NULL) {

+    if (Node != NULL) {

+      *Node = Tmp;

+    }

+    Status = RETURN_ALREADY_STARTED;

+    goto Done;

+  }

+

+  //

+  // no collision, allocate a new node

+  //

+  Tmp = AllocatePool (sizeof *Tmp);

+  if (Tmp == NULL) {

+    Status = RETURN_OUT_OF_RESOURCES;

+    goto Done;

+  }

+  if (Node != NULL) {

+    *Node = Tmp;

+  }

+

+  //

+  // reference the user structure from the node

+  //

+  Tmp->UserStruct = UserStruct;

+

+  //

+  // Link the node as a child to the correct side of the parent.

+  // If there's no parent, the new node is the root node in the tree.

+  //

+  Tmp->Parent = Parent;

+  Tmp->Left = NULL;

+  Tmp->Right = NULL;

+  if (Parent == NULL) {

+    Tree->Root = Tmp;

+    Tmp->Color = RedBlackTreeBlack;

+    Status = RETURN_SUCCESS;

+    goto Done;

+  }

+  if (Result < 0) {

+    Parent->Left = Tmp;

+  } else {

+    Parent->Right = Tmp;

+  }

+  Tmp->Color = RedBlackTreeRed;

+

+  //

+  // Red-black tree properties:

+  //

+  // #1 Each node is either red or black (RED_BLACK_TREE_NODE.Color).

+  //

+  // #2 Each leaf (ie. a pseudo-node pointed-to by a NULL valued

+  //    RED_BLACK_TREE_NODE.Left or RED_BLACK_TREE_NODE.Right field) is black.

+  //

+  // #3 Each red node has two black children.

+  //

+  // #4 For any node N, and for any leaves L1 and L2 reachable from N, the

+  //    paths N..L1 and N..L2 contain the same number of black nodes.

+  //

+  // #5 The root node is black.

+  //

+  // By replacing a leaf with a red node above, only property #3 may have been

+  // broken. (Note that this is the only edge across which property #3 might

+  // not hold in the entire tree.) Restore property #3.

+  //

+

+  NewRoot = Tree->Root;

+  while (Tmp != NewRoot && Parent->Color == RedBlackTreeRed) {

+    RED_BLACK_TREE_NODE *GrandParent;

+    RED_BLACK_TREE_NODE *Uncle;

+

+    //

+    // Tmp is not the root node. Tmp is red. Tmp's parent is red. (Breaking

+    // property #3.)

+    //

+    // Due to property #5, Tmp's parent cannot be the root node, hence Tmp's

+    // grandparent exists.

+    //

+    // Tmp's grandparent is black, because property #3 is only broken between

+    // Tmp and Tmp's parent.

+    //

+    GrandParent = Parent->Parent;

+

+    if (Parent == GrandParent->Left) {

+      Uncle = GrandParent->Right;

+      if (Uncle != NULL && Uncle->Color == RedBlackTreeRed) {

+        //

+        //             GrandParent (black)

+        //            /                   \_

+        // Parent (red)                    Uncle (red)

+        //      |

+        //  Tmp (red)

+        //

+

+        Parent->Color = RedBlackTreeBlack;

+        Uncle->Color = RedBlackTreeBlack;

+        GrandParent->Color = RedBlackTreeRed;

+

+        //

+        //                GrandParent (red)

+        //               /                 \_

+        // Parent (black)                   Uncle (black)

+        //       |

+        //   Tmp (red)

+        //

+        // We restored property #3 between Tmp and Tmp's parent, without

+        // breaking property #4. However, we may have broken property #3

+        // between Tmp's grandparent and Tmp's great-grandparent (if any), so

+        // repeat the loop for Tmp's grandparent.

+        //

+        // If Tmp's grandparent has no parent, then the loop will terminate,

+        // and we will have broken property #5, by coloring the root red. We'll

+        // restore property #5 after the loop, without breaking any others.

+        //

+        Tmp = GrandParent;

+        Parent = Tmp->Parent;

+      } else {

+        //

+        // Tmp's uncle is black (satisfied by the case too when Tmp's uncle is

+        // NULL, see property #2).

+        //

+

+        if (Tmp == Parent->Right) {

+          //

+          //                 GrandParent (black): D

+          //                /                      \_

+          // Parent (red): A                        Uncle (black): E

+          //      \_

+          //       Tmp (red): B

+          //            \_

+          //             black: C

+          //

+          // Rotate left, pivoting on node A. This keeps the breakage of

+          // property #3 in the same spot, and keeps other properties intact

+          // (because both Tmp and its parent are red).

+          //

+          Tmp = Parent;

+          RedBlackTreeRotateLeft (Tmp, &NewRoot);

+          Parent = Tmp->Parent;

+

+          //

+          // With the rotation we reached the same configuration as if Tmp had

+          // been a left child to begin with.

+          //

+          //                       GrandParent (black): D

+          //                      /                      \_

+          //       Parent (red): B                        Uncle (black): E

+          //             / \_

+          // Tmp (red): A   black: C

+          //

+          ASSERT (GrandParent == Parent->Parent);

+        }

+

+        Parent->Color = RedBlackTreeBlack;

+        GrandParent->Color = RedBlackTreeRed;

+

+        //

+        // Property #3 is now restored, but we've broken property #4. Namely,

+        // paths going through node E now see a decrease in black count, while

+        // paths going through node B don't.

+        //

+        //                        GrandParent (red): D

+        //                       /                    \_

+        //      Parent (black): B                      Uncle (black): E

+        //             / \_

+        // Tmp (red): A   black: C

+        //

+

+        RedBlackTreeRotateRight (GrandParent, &NewRoot);

+

+        //

+        // Property #4 has been restored for node E, and preserved for others.

+        //

+        //              Parent (black): B

+        //             /                 \_

+        // Tmp (red): A                   [GrandParent] (red): D

+        //                                         / \_

+        //                                 black: C   [Uncle] (black): E

+        //

+        // This configuration terminates the loop because Tmp's parent is now

+        // black.

+        //

+      }

+    } else {

+      //

+      // Symmetrical to the other branch.

+      //

+      Uncle = GrandParent->Left;

+      if (Uncle != NULL && Uncle->Color == RedBlackTreeRed) {

+        Parent->Color = RedBlackTreeBlack;

+        Uncle->Color = RedBlackTreeBlack;

+        GrandParent->Color = RedBlackTreeRed;

+        Tmp = GrandParent;

+        Parent = Tmp->Parent;

+      } else {

+        if (Tmp == Parent->Left) {

+          Tmp = Parent;

+          RedBlackTreeRotateRight (Tmp, &NewRoot);

+          Parent = Tmp->Parent;

+          ASSERT (GrandParent == Parent->Parent);

+        }

+        Parent->Color = RedBlackTreeBlack;

+        GrandParent->Color = RedBlackTreeRed;

+        RedBlackTreeRotateLeft (GrandParent, &NewRoot);

+      }

+    }

+  }

+

+  NewRoot->Color = RedBlackTreeBlack;

+  Tree->Root = NewRoot;

+  Status = RETURN_SUCCESS;

+

+Done:

+  if (FeaturePcdGet (PcdValidateOrderedCollection)) {

+    RedBlackTreeValidate (Tree);

+  }

+  return Status;

+}

+

+

+/**

+  Check if a node is black, allowing for leaf nodes (see property #2).

+

+  This is a convenience shorthand.

+

+  param[in] Node  The node to check. Node may be NULL, corresponding to a leaf.

+

+  @return  If Node is NULL or colored black.

+**/

+BOOLEAN

+NodeIsNullOrBlack (

+  IN CONST RED_BLACK_TREE_NODE *Node

+  )

+{

+  return (BOOLEAN)(Node == NULL || Node->Color == RedBlackTreeBlack);

+}

+

+

+/**

+  Delete a node from the tree, unlinking the associated user structure.

+

+  Read-write operation.

+

+  @param[in,out] Tree        The tree to delete Node from.

+

+  @param[in]     Node        The tree node to delete from Tree. The caller is

+                             responsible for ensuring that Node belongs to

+                             Tree, and that Node is non-NULL and valid. Node is

+                             typically an earlier return value, or output

+                             parameter, of:

+

+                             - OrderedCollectionFind(), for deleting a node by

+                               user structure key,

+

+                             - OrderedCollectionMin() / OrderedCollectionMax(),

+                               for deleting the minimum / maximum node,

+

+                             - OrderedCollectionNext() /

+                               OrderedCollectionPrev(), for deleting a node

+                               found during an iteration,

+

+                             - OrderedCollectionInsert() with return value

+                               RETURN_ALREADY_STARTED, for deleting a node

+                               whose linked user structure caused collision

+                               during insertion.

+

+                             Given a non-empty Tree, Tree->Root is also a valid

+                             Node argument (typically used for simplicity in

+                             loops that empty the tree completely).

+

+                             Node is released with MemoryAllocationLib's

+                             FreePool() function.

+

+                             Existing RED_BLACK_TREE_NODE pointers (ie.

+                             iterators) *different* from Node remain valid. For

+                             example:

+

+                             - OrderedCollectionNext() /

+                               OrderedCollectionPrev() iterations in the caller

+                               can be continued from Node, if

+                               OrderedCollectionNext() or

+                               OrderedCollectionPrev() is called on Node

+                               *before* OrderedCollectionDelete() is. That is,

+                               fetch the successor / predecessor node first,

+                               then delete Node.

+

+                             - On-going iterations in the caller that would

+                               have otherwise returned Node at some point, as

+                               dictated by user structure order, will correctly

+                               reflect the absence of Node after

+                               OrderedCollectionDelete() is called

+                               mid-iteration.

+

+  @param[out]    UserStruct  If the caller provides this optional output-only

+                             parameter, then on output it is set to the user

+                             structure originally linked by Node (which is now

+                             freed).

+

+                             This is a convenience that may save the caller a

+                             OrderedCollectionUserStruct() invocation before

+                             calling OrderedCollectionDelete(), in order to

+                             retrieve the user structure being unlinked.

+**/

+VOID

+EFIAPI

+OrderedCollectionDelete (

+  IN OUT RED_BLACK_TREE      *Tree,

+  IN     RED_BLACK_TREE_NODE *Node,

+  OUT    VOID                **UserStruct OPTIONAL

+  )

+{

+  RED_BLACK_TREE_NODE  *NewRoot;

+  RED_BLACK_TREE_NODE  *OrigLeftChild;

+  RED_BLACK_TREE_NODE  *OrigRightChild;

+  RED_BLACK_TREE_NODE  *OrigParent;

+  RED_BLACK_TREE_NODE  *Child;

+  RED_BLACK_TREE_NODE  *Parent;

+  RED_BLACK_TREE_COLOR ColorOfUnlinked;

+

+  NewRoot        = Tree->Root;

+  OrigLeftChild  = Node->Left,

+  OrigRightChild = Node->Right,

+  OrigParent     = Node->Parent;

+

+  if (UserStruct != NULL) {

+    *UserStruct = Node->UserStruct;

+  }

+

+  //

+  // After this block, no matter which branch we take:

+  // - Child will point to the unique (or NULL) original child of the node that

+  //   we will have unlinked,

+  // - Parent will point to the *position* of the original parent of the node

+  //   that we will have unlinked.

+  //

+  if (OrigLeftChild == NULL || OrigRightChild == NULL) {

+    //

+    // Node has at most one child. We can connect that child (if any) with

+    // Node's parent (if any), unlinking Node. This will preserve ordering

+    // because the subtree rooted in Node's child (if any) remains on the same

+    // side of Node's parent (if any) that Node was before.

+    //

+    Parent = OrigParent;

+    Child = (OrigLeftChild != NULL) ? OrigLeftChild : OrigRightChild;

+    ColorOfUnlinked = Node->Color;

+

+    if (Child != NULL) {

+      Child->Parent = Parent;

+    }

+    if (OrigParent == NULL) {

+      NewRoot = Child;

+    } else {

+      if (Node == OrigParent->Left) {

+        OrigParent->Left = Child;

+      } else {

+        OrigParent->Right = Child;

+      }

+    }

+  } else {

+    //

+    // Node has two children. We unlink Node's successor, and then link it into

+    // Node's place, keeping Node's original color. This preserves ordering

+    // because:

+    // - Node's left subtree is less than Node, hence less than Node's

+    //   successor.

+    // - Node's right subtree is greater than Node. Node's successor is the

+    //   minimum of that subtree, hence Node's successor is less than Node's

+    //   right subtree with its minimum removed.

+    // - Node's successor is in Node's subtree, hence it falls on the same side

+    //   of Node's parent as Node itself. The relinking doesn't change this

+    //   relation.

+    //

+    RED_BLACK_TREE_NODE *ToRelink;

+

+    ToRelink = OrigRightChild;

+    if (ToRelink->Left == NULL) {

+      //

+      // OrigRightChild itself is Node's successor, it has no left child:

+      //

+      //                OrigParent

+      //                    |

+      //                  Node: B

+      //                 /       \_

+      // OrigLeftChild: A         OrigRightChild: E <--- Parent, ToRelink

+      //                                           \_

+      //                                            F <--- Child

+      //

+      Parent = OrigRightChild;

+      Child = OrigRightChild->Right;

+    } else {

+      do {

+        ToRelink = ToRelink->Left;

+      } while (ToRelink->Left != NULL);

+

+      //

+      // Node's successor is the minimum of OrigRightChild's proper subtree:

+      //

+      //                OrigParent

+      //                    |

+      //                  Node: B

+      //                 /       \_

+      // OrigLeftChild: A         OrigRightChild: E <--- Parent

+      //                                  /

+      //                                 C <--- ToRelink

+      //                                  \_

+      //                                   D <--- Child

+      Parent = ToRelink->Parent;

+      Child = ToRelink->Right;

+

+      //

+      // Unlink Node's successor (ie. ToRelink):

+      //

+      //                OrigParent

+      //                    |

+      //                  Node: B

+      //                 /       \_

+      // OrigLeftChild: A         OrigRightChild: E <--- Parent

+      //                                  /

+      //                                 D <--- Child

+      //

+      //                                 C <--- ToRelink

+      //

+      Parent->Left = Child;

+      if (Child != NULL) {

+        Child->Parent = Parent;

+      }

+

+      //

+      // We start to link Node's unlinked successor into Node's place:

+      //

+      //                OrigParent

+      //                    |

+      //                  Node: B     C <--- ToRelink

+      //                 /             \_

+      // OrigLeftChild: A               OrigRightChild: E <--- Parent

+      //                                        /

+      //                                       D <--- Child

+      //

+      //

+      //

+      ToRelink->Right = OrigRightChild;

+      OrigRightChild->Parent = ToRelink;

+    }

+

+    //

+    // The rest handles both cases, attaching ToRelink (Node's original

+    // successor) to OrigLeftChild and OrigParent.

+    //

+    //                           Parent,

+    //              OrigParent   ToRelink             OrigParent

+    //                  |        |                        |

+    //                Node: B    |                      Node: B          Parent

+    //                           v                                          |

+    //           OrigRightChild: E                        C <--- ToRelink   |

+    //                 / \                               / \                v

+    // OrigLeftChild: A   F              OrigLeftChild: A   OrigRightChild: E

+    //                    ^                                         /

+    //                    |                                        D <--- Child

+    //                  Child

+    //

+    ToRelink->Left = OrigLeftChild;

+    OrigLeftChild->Parent = ToRelink;

+

+    //

+    // Node's color must be preserved in Node's original place.

+    //

+    ColorOfUnlinked = ToRelink->Color;

+    ToRelink->Color = Node->Color;

+

+    //

+    // Finish linking Node's unlinked successor into Node's place.

+    //

+    //                           Parent,

+    //                Node: B    ToRelink               Node: B

+    //                           |

+    //              OrigParent   |                    OrigParent         Parent

+    //                  |        v                        |                 |

+    //           OrigRightChild: E                        C <--- ToRelink   |

+    //                 / \                               / \                v

+    // OrigLeftChild: A   F              OrigLeftChild: A   OrigRightChild: E

+    //                    ^                                         /

+    //                    |                                        D <--- Child

+    //                  Child

+    //

+    ToRelink->Parent = OrigParent;

+    if (OrigParent == NULL) {

+      NewRoot = ToRelink;

+    } else {

+      if (Node == OrigParent->Left) {

+        OrigParent->Left = ToRelink;

+      } else {

+        OrigParent->Right = ToRelink;

+      }

+    }

+  }

+

+  FreePool (Node);

+

+  //

+  // If the node that we unlinked from its original spot (ie. Node itself, or

+  // Node's successor), was red, then we broke neither property #3 nor property

+  // #4: we didn't create any red-red edge between Child and Parent, and we

+  // didn't change the black count on any path.

+  //

+  if (ColorOfUnlinked == RedBlackTreeBlack) {

+    //

+    // However, if the unlinked node was black, then we have to transfer its

+    // "black-increment" to its unique child (pointed-to by Child), lest we

+    // break property #4 for its ancestors.

+    //

+    // If Child is red, we can simply color it black. If Child is black

+    // already, we can't technically transfer a black-increment to it, due to

+    // property #1.

+    //

+    // In the following loop we ascend searching for a red node to color black,

+    // or until we reach the root (in which case we can drop the

+    // black-increment). Inside the loop body, Child has a black value of 2,

+    // transitorily breaking property #1 locally, but maintaining property #4

+    // globally.

+    //

+    // Rotations in the loop preserve property #4.

+    //

+    while (Child != NewRoot && NodeIsNullOrBlack (Child)) {

+      RED_BLACK_TREE_NODE *Sibling;

+      RED_BLACK_TREE_NODE *LeftNephew;

+      RED_BLACK_TREE_NODE *RightNephew;

+

+      if (Child == Parent->Left) {

+        Sibling = Parent->Right;

+        //

+        // Sibling can never be NULL (ie. a leaf).

+        //

+        // If Sibling was NULL, then the black count on the path from Parent to

+        // Sibling would equal Parent's black value, plus 1 (due to property

+        // #2). Whereas the black count on the path from Parent to any leaf via

+        // Child would be at least Parent's black value, plus 2 (due to Child's

+        // black value of 2). This would clash with property #4.

+        //

+        // (Sibling can be black of course, but it has to be an internal node.

+        // Internality allows Sibling to have children, bumping the black

+        // counts of paths that go through it.)

+        //

+        ASSERT (Sibling != NULL);

+        if (Sibling->Color == RedBlackTreeRed) {

+          //

+          // Sibling's red color implies its children (if any), node C and node

+          // E, are black (property #3). It also implies that Parent is black.

+          //

+          //           grandparent                                 grandparent

+          //                |                                           |

+          //            Parent,b:B                                     b:D

+          //           /          \                                   /   \_

+          // Child,2b:A            Sibling,r:D  --->        Parent,r:B     b:E

+          //                           /\                       /\_

+          //                        b:C  b:E          Child,2b:A  Sibling,b:C

+          //

+          Sibling->Color = RedBlackTreeBlack;

+          Parent->Color = RedBlackTreeRed;

+          RedBlackTreeRotateLeft (Parent, &NewRoot);

+          Sibling = Parent->Right;

+          //

+          // Same reasoning as above.

+          //

+          ASSERT (Sibling != NULL);

+        }

+

+        //

+        // Sibling is black, and not NULL. (Ie. Sibling is a black internal

+        // node.)

+        //

+        ASSERT (Sibling->Color == RedBlackTreeBlack);

+        LeftNephew = Sibling->Left;

+        RightNephew = Sibling->Right;

+        if (NodeIsNullOrBlack (LeftNephew) &&

+            NodeIsNullOrBlack (RightNephew)) {

+          //

+          // In this case we can "steal" one black value from Child and Sibling

+          // each, and pass it to Parent. "Stealing" means that Sibling (black

+          // value 1) becomes red, Child (black value 2) becomes singly-black,

+          // and Parent will have to be examined if it can eat the

+          // black-increment.

+          //

+          // Sibling is allowed to become red because both of its children are

+          // black (property #3).

+          //

+          //           grandparent                             Parent

+          //                |                                     |

+          //            Parent,x:B                            Child,x:B

+          //           /          \                          /         \_

+          // Child,2b:A            Sibling,b:D    --->    b:A           r:D

+          //                           /\                                /\_

+          //             LeftNephew,b:C  RightNephew,b:E              b:C  b:E

+          //

+          Sibling->Color = RedBlackTreeRed;

+          Child = Parent;

+          Parent = Parent->Parent;

+          //

+          // Continue ascending.

+          //

+        } else {

+          //

+          // At least one nephew is red.

+          //

+          if (NodeIsNullOrBlack (RightNephew)) {

+            //

+            // Since the right nephew is black, the left nephew is red. Due to

+            // property #3, LeftNephew has two black children, hence node E is

+            // black.

+            //

+            // Together with the rotation, this enables us to color node F red

+            // (because property #3 will be satisfied). We flip node D to black

+            // to maintain property #4.

+            //

+            //      grandparent                         grandparent

+            //           |                                   |

+            //       Parent,x:B                          Parent,x:B

+            //           /\                                  /\_

+            // Child,2b:A  Sibling,b:F     --->    Child,2b:A  Sibling,b:D

+            //                  /\                            /   \_

+            //    LeftNephew,r:D  RightNephew,b:G          b:C  RightNephew,r:F

+            //               /\                                       /\_

+            //            b:C  b:E                                 b:E  b:G

+            //

+            LeftNephew->Color = RedBlackTreeBlack;

+            Sibling->Color = RedBlackTreeRed;

+            RedBlackTreeRotateRight (Sibling, &NewRoot);

+            Sibling = Parent->Right;

+            RightNephew = Sibling->Right;

+            //

+            // These operations ensure that...

+            //

+          }

+          //

+          // ... RightNephew is definitely red here, plus Sibling is (still)

+          // black and non-NULL.

+          //

+          ASSERT (RightNephew != NULL);

+          ASSERT (RightNephew->Color == RedBlackTreeRed);

+          ASSERT (Sibling != NULL);

+          ASSERT (Sibling->Color == RedBlackTreeBlack);

+          //

+          // In this case we can flush the extra black-increment immediately,

+          // restoring property #1 for Child (node A): we color RightNephew

+          // (node E) from red to black.

+          //

+          // In order to maintain property #4, we exchange colors between

+          // Parent and Sibling (nodes B and D), and rotate left around Parent

+          // (node B). The transformation doesn't change the black count

+          // increase incurred by each partial path, eg.

+          // - ascending from node A: 2 + x     == 1 + 1 + x

+          // - ascending from node C: y + 1 + x == y + 1 + x

+          // - ascending from node E: 0 + 1 + x == 1 + x

+          //

+          // The color exchange is valid, because even if x stands for red,

+          // both children of node D are black after the transformation

+          // (preserving property #3).

+          //

+          //           grandparent                                  grandparent

+          //                |                                            |

+          //            Parent,x:B                                      x:D

+          //           /          \                                    /   \_

+          // Child,2b:A            Sibling,b:D              --->    b:B     b:E

+          //                         /     \                       /   \_

+          //                      y:C       RightNephew,r:E     b:A     y:C

+          //

+          //

+          Sibling->Color = Parent->Color;

+          Parent->Color = RedBlackTreeBlack;

+          RightNephew->Color = RedBlackTreeBlack;

+          RedBlackTreeRotateLeft (Parent, &NewRoot);

+          Child = NewRoot;

+          //

+          // This terminates the loop.

+          //

+        }

+      } else {

+        //

+        // Mirrors the other branch.

+        //

+        Sibling = Parent->Left;

+        ASSERT (Sibling != NULL);

+        if (Sibling->Color == RedBlackTreeRed) {

+          Sibling->Color = RedBlackTreeBlack;

+          Parent->Color = RedBlackTreeRed;

+          RedBlackTreeRotateRight (Parent, &NewRoot);

+          Sibling = Parent->Left;

+          ASSERT (Sibling != NULL);

+        }

+

+        ASSERT (Sibling->Color == RedBlackTreeBlack);

+        RightNephew = Sibling->Right;

+        LeftNephew = Sibling->Left;

+        if (NodeIsNullOrBlack (RightNephew) &&

+            NodeIsNullOrBlack (LeftNephew)) {

+          Sibling->Color = RedBlackTreeRed;

+          Child = Parent;

+          Parent = Parent->Parent;

+        } else {

+          if (NodeIsNullOrBlack (LeftNephew)) {

+            RightNephew->Color = RedBlackTreeBlack;

+            Sibling->Color = RedBlackTreeRed;

+            RedBlackTreeRotateLeft (Sibling, &NewRoot);

+            Sibling = Parent->Left;

+            LeftNephew = Sibling->Left;

+          }

+          ASSERT (LeftNephew != NULL);

+          ASSERT (LeftNephew->Color == RedBlackTreeRed);

+          ASSERT (Sibling != NULL);

+          ASSERT (Sibling->Color == RedBlackTreeBlack);

+          Sibling->Color = Parent->Color;

+          Parent->Color = RedBlackTreeBlack;

+          LeftNephew->Color = RedBlackTreeBlack;

+          RedBlackTreeRotateRight (Parent, &NewRoot);

+          Child = NewRoot;

+        }

+      }

+    }

+

+    if (Child != NULL) {

+      Child->Color = RedBlackTreeBlack;

+    }

+  }

+

+  Tree->Root = NewRoot;

+

+  if (FeaturePcdGet (PcdValidateOrderedCollection)) {

+    RedBlackTreeValidate (Tree);

+  }

+}

+

+

+/**

+  Recursively check the red-black tree properties #1 to #4 on a node.

+

+  @param[in] Node  The root of the subtree to validate.

+

+  @retval  The black-height of Node's parent.

+**/

+UINT32

+RedBlackTreeRecursiveCheck (

+  IN CONST RED_BLACK_TREE_NODE *Node

+  )

+{

+  UINT32 LeftHeight;

+  UINT32 RightHeight;

+

+  //

+  // property #2

+  //

+  if (Node == NULL) {

+    return 1;

+  }

+

+  //

+  // property #1

+  //

+  ASSERT (Node->Color == RedBlackTreeRed || Node->Color == RedBlackTreeBlack);

+

+  //

+  // property #3

+  //

+  if (Node->Color == RedBlackTreeRed) {

+    ASSERT (NodeIsNullOrBlack (Node->Left));

+    ASSERT (NodeIsNullOrBlack (Node->Right));

+  }

+

+  //

+  // property #4

+  //

+  LeftHeight = RedBlackTreeRecursiveCheck (Node->Left);

+  RightHeight = RedBlackTreeRecursiveCheck (Node->Right);

+  ASSERT (LeftHeight == RightHeight);

+

+  return (Node->Color == RedBlackTreeBlack) + LeftHeight;

+}

+

+

+/**

+  A slow function that asserts that the tree is a valid red-black tree, and

+  that it orders user structures correctly.

+

+  Read-only operation.

+

+  This function uses the stack for recursion and is not recommended for

+  "production use".

+

+  @param[in] Tree  The tree to validate.

+**/

+VOID

+RedBlackTreeValidate (

+  IN CONST RED_BLACK_TREE *Tree

+  )

+{

+  UINT32                    BlackHeight;

+  UINT32                    ForwardCount;

+  UINT32                    BackwardCount;

+  CONST RED_BLACK_TREE_NODE *Last;

+  CONST RED_BLACK_TREE_NODE *Node;

+

+  DEBUG ((DEBUG_VERBOSE, "%a: Tree=%p\n", __FUNCTION__, Tree));

+

+  //

+  // property #5

+  //

+  ASSERT (NodeIsNullOrBlack (Tree->Root));

+

+  //

+  // check the other properties

+  //

+  BlackHeight = RedBlackTreeRecursiveCheck (Tree->Root) - 1;

+

+  //

+  // forward ordering

+  //

+  Last = OrderedCollectionMin (Tree);

+  ForwardCount = (Last != NULL);

+  for (Node = OrderedCollectionNext (Last); Node != NULL;

+       Node = OrderedCollectionNext (Last)) {

+    ASSERT (Tree->UserStructCompare (Last->UserStruct, Node->UserStruct) < 0);

+    Last = Node;

+    ++ForwardCount;

+  }

+

+  //

+  // backward ordering

+  //

+  Last = OrderedCollectionMax (Tree);

+  BackwardCount = (Last != NULL);

+  for (Node = OrderedCollectionPrev (Last); Node != NULL;

+       Node = OrderedCollectionPrev (Last)) {

+    ASSERT (Tree->UserStructCompare (Last->UserStruct, Node->UserStruct) > 0);

+    Last = Node;

+    ++BackwardCount;

+  }

+

+  ASSERT (ForwardCount == BackwardCount);

+

+  DEBUG ((DEBUG_VERBOSE, "%a: Tree=%p BlackHeight=%Ld Count=%Ld\n",

+    __FUNCTION__, Tree, (INT64)BlackHeight, (INT64)ForwardCount));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
new file mode 100644
index 0000000..a68afc8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
@@ -0,0 +1,50 @@
+## @file

+#  An OrderedCollectionLib instance that provides a red-black tree

+#  implementation, and allocates and releases tree nodes with

+#  MemoryAllocationLib.

+#

+#  This library instance is useful when a fast associative container is needed.

+#  Worst case time complexity is O(log n) for Find(), Next(), Prev(), Min(),

+#  Max(), Insert(), and Delete(), where "n" is the number of elements in the

+#  tree. Complete ordered traversal takes O(n) time.

+#

+#  The implementation is also useful as a fast priority queue.

+#

+#  Copyright (C) 2014, Red Hat, Inc.

+#

+#  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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseOrderedCollectionRedBlackTreeLib

+  MODULE_UNI_FILE                = BaseOrderedCollectionRedBlackTreeLib.uni

+  FILE_GUID                      = 699F73C3-0058-484C-A9E5-61189276A985

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = OrderedCollectionLib

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BaseOrderedCollectionRedBlackTreeLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  MemoryAllocationLib

+

+[FeaturePcd]

+  gEfiMdePkgTokenSpaceGuid.PcdValidateOrderedCollection ## CONSUMES

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.uni
new file mode 100644
index 0000000..f9ad9c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/BasePalLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/BasePalLibNull.inf
new file mode 100644
index 0000000..927c6d3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/BasePalLibNull.inf
@@ -0,0 +1,40 @@
+## @file

+#  Null instance of PAL Library with empty functions.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePalLibNull

+  MODULE_UNI_FILE                = BasePalLibNull.uni

+  FILE_GUID                      = 632D5625-B73D-43b8-AF30-8D225D96168E

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PalLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  PalCall.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/BasePalLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/BasePalLibNull.uni
new file mode 100644
index 0000000..3974c33
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/BasePalLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/PalCall.c b/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/PalCall.c
new file mode 100644
index 0000000..174c28e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePalLibNull/PalCall.c
@@ -0,0 +1,59 @@
+/** @file

+  

+  Template and Sample instance of PalCallLib.

+  

+  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.

+     

+**/

+

+#include <Base.h>

+#include <Library/PalLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  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. 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 4 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.

+  This function is only available on IPF.

+

+  @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 The structure returned from the PAL Call procedure, including the status and return value.

+

+**/

+PAL_CALL_RETURN

+EFIAPI

+PalCall (

+  IN UINT64                  Index,

+  IN UINT64                  Arg2,

+  IN UINT64                  Arg3,

+  IN UINT64                  Arg4

+  )

+{

+  PAL_CALL_RETURN Ret;

+

+  Ret.Status = (UINT64) -1;

+  ASSERT (!RETURN_ERROR (RETURN_UNSUPPORTED));

+  return Ret;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
new file mode 100644
index 0000000..4b511b3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -0,0 +1,42 @@
+## @file

+#  Instance of PCD Library without support of dynamic PCD entries.

+#

+#  PCD Library that only provides access to Feature Flag, Fixed At Build,

+#  and Binary Patch typed PCD entries. Access to Dynamic PCD entries is ignored.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePcdLibNull

+  MODULE_UNI_FILE                = BasePcdLibNull.uni

+  FILE_GUID                      = 40096a3a-5c2a-4fbc-aef7-5475dd7ab334

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PcdLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PcdLib.c

+

+[LibraryClasses]

+  DebugLib

+  BaseMemoryLib

+

+[Packages]

+  MdePkg/MdePkg.dec

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.uni
new file mode 100644
index 0000000..c35dfbb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/PcdLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/PcdLib.c
new file mode 100644
index 0000000..e03c01d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePcdLibNull/PcdLib.c
@@ -0,0 +1,1004 @@
+/** @file

+  A emptry template implementation of PCD Library.

+

+  Copyright (c) 2006 - 2014, 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 <Base.h>

+

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseMemoryLib.h>

+

+

+/**

+  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[in]  SkuId The SKU value that will be used when the PCD service will retrieve and 

+                    set values associated with a PCD token.

+                    

+  If SkuId >= 0x100, then ASSERT().                  

+

+  @return Return the SKU ID that just be set.

+

+**/

+UINTN

+EFIAPI

+LibPcdSetSku (

+  IN UINTN   SkuId

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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 The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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 The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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          The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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          The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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          The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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          The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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,

+  or ASSERT() if the set operation was not corretly 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 been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetPtr (

+  IN        UINTN             TokenNumber,

+  IN OUT    UINTN             *SizeOfBuffer,

+  IN CONST  VOID              *Buffer

+  )

+{

+  ASSERT (FALSE);

+

+  return NULL;

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT (FALSE);

+

+  return FALSE;

+}

+

+

+

+/**

+  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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT32            Value

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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, or ASSERT() if the set operation was not corretly 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              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, out] SizeOfBuffer  The size, in bytes, of Buffer.

+  @param[in]  Buffer            A pointer to the buffer to set.

+

+  @return Return the pinter to the buffer been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN      CONST GUID        *Guid,

+  IN      UINTN             TokenNumber,

+  IN OUT  UINTN             *SizeOfBuffer,

+  IN      VOID              *Buffer

+  )

+{

+  ASSERT (FALSE);

+

+  return NULL;

+}

+

+

+

+/**

+  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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  ASSERT (FALSE);

+

+  return FALSE;

+}

+

+

+

+/**

+  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      The 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

+  )

+{

+  ASSERT (FALSE);

+}

+

+

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+}

+

+

+

+/**

+  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        The 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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

+

+

+/**

+  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  The pointer to a PCD token space GUID.

+

+  @return The next valid token namespace.

+

+**/

+GUID *           

+EFIAPI

+LibPcdGetNextTokenSpace (

+  IN CONST GUID  *TokenSpaceGuid

+  )

+{

+  ASSERT (FALSE);

+

+  return NULL;

+}

+

+

+/**

+  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[in] 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 (

+  IN        VOID        *PatchVariable,

+  IN        UINTN       MaximumDatumSize,

+  IN OUT    UINTN       *SizeOfBuffer,

+  IN CONST  VOID        *Buffer

+  )

+{

+  ASSERT (PatchVariable != NULL);

+  ASSERT (SizeOfBuffer  != NULL);

+  

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+

+  if ((*SizeOfBuffer > MaximumDatumSize) ||

+      (*SizeOfBuffer == MAX_ADDRESS)) {

+    *SizeOfBuffer = MaximumDatumSize;

+    return NULL;

+  }

+    

+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);

+  

+  return (VOID *) Buffer;

+}

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  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

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Retrieve the currently set SKU Id.

+

+  If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT (FALSE);

+

+  return 0;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf b/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
new file mode 100644
index 0000000..17b81e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
@@ -0,0 +1,42 @@
+## @file

+#  Instance of PCI CF8 Library using I/O ports 0xCF8 and 0xCFC.

+#

+#  PCI CF8 Library that uses I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.

+#  Layers on top of an I/O Library instance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePciCf8Lib

+  MODULE_UNI_FILE                = BasePciCf8Lib.uni

+  FILE_GUID                      = 472ab06d-9810-4c00-bb7f-dad1828fc1ab

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciCf8Lib 

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciCf8Lib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  IoLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.uni b/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.uni
new file mode 100644
index 0000000..e768922
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c b/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
new file mode 100644
index 0000000..828508b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
@@ -0,0 +1,1784 @@
+/** @file

+  PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.

+  Layers on top of an I/O Library instance.

+

+  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.

+

+**/

+

+

+#include <Base.h>

+

+#include <Library/BaseLib.h>

+#include <Library/PciCf8Lib.h>

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+

+//

+// Declare I/O Ports used to perform PCI Confguration Cycles

+//

+#define PCI_CONFIGURATION_ADDRESS_PORT  0xCF8

+#define PCI_CONFIGURATION_DATA_PORT     0xCFC

+

+/**

+  Convert a PCI Library address to PCI CF8 formatted address.

+

+  Declare macro to convert PCI Library address to PCI CF8 formatted address.

+  Bit fields of PCI Library and CF8 formatted address is as follows:

+  PCI Library formatted address    CF8 Formatted Address

+ =============================    ======================

+    Bits 00..11  Register           Bits 00..07  Register

+    Bits 12..14  Function           Bits 08..10  Function

+    Bits 15..19  Device             Bits 11..15  Device

+    Bits 20..27  Bus                Bits 16..23  Bus

+    Bits 28..31  Reserved(MBZ)      Bits 24..30  Reserved(MBZ)

+                                    Bits 31..31  Must be 1

+

+  @param  A The address to convert.

+

+  @retval The coverted address.

+

+**/

+#define PCI_TO_CF8_ADDRESS(A) \

+  ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))

+

+/**

+  Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's

+  only in the low 28 bits, excluding bits 08..11.

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \

+  ASSERT (((A) & (~0xffff0ff | (M))) == 0)

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration registers 

+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciCf8RegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  return RETURN_SUCCESS;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Read8 (

+  IN      UINTN                     Address

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Write8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoWrite8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             Value

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8Or8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoOr8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8And8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoAnd8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             AndData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8AndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoAndThenOr8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             AndData,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldRead8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             StartBit,

+             EndBit

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldWrite8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             StartBit,

+             EndBit,

+             Value

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldOr8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             StartBit,

+             EndBit,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldAnd8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             StartBit,

+             EndBit,

+             AndData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciCf8BitFieldAndThenOr8(

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT8    Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldAndThenOr8 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),

+             StartBit,

+             EndBit,

+             AndData,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Read16 (

+  IN      UINTN                     Address

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Write16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoWrite16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             Value

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8Or16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoOr16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8And16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoAnd16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             AndData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8AndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoAndThenOr16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             AndData,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldRead16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             StartBit,

+             EndBit

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldWrite16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             StartBit,

+             EndBit,

+             Value

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldOr16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             StartBit,

+             EndBit,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldAnd16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             StartBit,

+             EndBit,

+             AndData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciCf8BitFieldAndThenOr16(

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT16   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldAndThenOr16 (

+             PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),

+             StartBit,

+             EndBit,

+             AndData,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Read32 (

+  IN      UINTN                     Address

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Write32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoWrite32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             Value

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8Or32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoOr32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8And32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoAnd32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             AndData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8AndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoAndThenOr32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             AndData,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldRead32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             StartBit,

+             EndBit

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldWrite32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             StartBit,

+             EndBit,

+             Value

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldOr32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             StartBit,

+             EndBit,

+             OrData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldAnd32 (

+             PCI_CONFIGURATION_DATA_PORT,

+             StartBit,

+             EndBit,

+             AndData

+             );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  If the register specified by Address >= 0x100, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciCf8BitFieldAndThenOr32(

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  BOOLEAN  InterruptState;

+  UINT32   AddressPort;

+  UINT32   Result;

+  

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+  InterruptState = SaveAndDisableInterrupts ();

+  AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));

+  Result = IoBitFieldAndThenOr32 (

+               PCI_CONFIGURATION_DATA_PORT,

+               StartBit,

+               EndBit,

+               AndData,

+               OrData

+               );

+  IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);

+  SetInterruptState (InterruptState);

+  return Result;

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If the register specified by StartAddress >= 0x100, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size read from StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciCf8ReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN   ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));

+

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If the register specified by StartAddress >= 0x100, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciCf8WriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN   ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciCf8Write8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciCf8Write8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf b/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
new file mode 100644
index 0000000..4b14b5d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
@@ -0,0 +1,46 @@
+## @file

+#  Instance of PCI Express Library using the 256 MB PCI Express MMIO window.

+#

+#  PCI Express Library that uses the 256 MB PCI Express MMIO window to perform

+#  PCI Configuration cycles. Layers on top of an I/O Library instance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePciExpressLib

+  MODULE_UNI_FILE                = BasePciExpressLib.uni

+  FILE_GUID                      = 287e50f4-a188-4699-b907-3e4080ca5688

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciExpressLib 

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciExpressLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  PcdLib

+  DebugLib

+  IoLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.uni b/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.uni
new file mode 100644
index 0000000..77dad6c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/BasePciExpressLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/PciExpressLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/PciExpressLib.c
new file mode 100644
index 0000000..61be009
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciExpressLib/PciExpressLib.c
@@ -0,0 +1,1419 @@
+/** @file

+  Functions in this library instance make use of MMIO functions in IoLib to

+  access memory mapped PCI configuration space.

+

+  All assertions for I/O operations are handled in MMIO functions in the IoLib

+  Library.

+

+  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.

+

+**/

+

+

+#include <Base.h>

+

+#include <Library/BaseLib.h>

+#include <Library/PciExpressLib.h>

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A) \

+  ASSERT (((A) & ~0xfffffff) == 0)

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration 

+  registers associated with that PCI device may be accessed after SetVirtualAddressMap() 

+  is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciExpressRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Gets the base address of PCI Express.

+  

+  This internal functions retrieves PCI Express Base Address via a PCD entry

+  PcdPciExpressBaseAddress.

+  

+  @return The base address of PCI Express.

+

+**/

+VOID*

+GetPciExpressBaseAddress (

+  VOID

+  )

+{

+  return (VOID*)(UINTN) PcdGet64 (PcdPciExpressBaseAddress);

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressRead8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioWrite8 ((UINTN) GetPciExpressBaseAddress () + Address, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioOr8 ((UINTN) GetPciExpressBaseAddress () + Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAnd8 ((UINTN) GetPciExpressBaseAddress () + Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAndThenOr8 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldRead8 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldWrite8 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldOr8 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAnd8 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAndThenOr8 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioRead16 ((UINTN) GetPciExpressBaseAddress () + Address);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioWrite16 ((UINTN) GetPciExpressBaseAddress () + Address, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioOr16 ((UINTN) GetPciExpressBaseAddress () + Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAnd16 ((UINTN) GetPciExpressBaseAddress () + Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAndThenOr16 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldRead16 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldWrite16 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldOr16 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAnd16 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAndThenOr16 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioRead32 ((UINTN) GetPciExpressBaseAddress () + Address);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioWrite32 ((UINTN) GetPciExpressBaseAddress () + Address, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioOr32 ((UINTN) GetPciExpressBaseAddress () + Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAnd32 ((UINTN) GetPciExpressBaseAddress () + Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioAndThenOr32 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldRead32 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldWrite32 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldOr32 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAnd32 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address);

+  return MmioBitFieldAndThenOr32 (

+           (UINTN) GetPciExpressBaseAddress () + Address,

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size read data from StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciExpressReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN   ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));

+

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));

+

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciExpressWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf b/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
new file mode 100644
index 0000000..9409332
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
@@ -0,0 +1,40 @@
+## @file

+#  Instance of PCI Library based on PCI CF8 Library.

+#

+#  PCI Library that uses I/O ports 0xCF8 and 0xCFC to perform

+#  PCI Configuration cycles. Layers on top of one PCI CF8 Library instance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePciLibCf8

+  MODULE_UNI_FILE                = BasePciLibCf8.uni

+  FILE_GUID                      = 28bde99c-e8a7-4e3e-9a8a-e66cd64f31c6

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciLib 

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PciCf8Lib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.uni b/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.uni
new file mode 100644
index 0000000..9f7db22
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/BasePciLibCf8.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/PciLib.c
new file mode 100644
index 0000000..f5f2147
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -0,0 +1,1138 @@
+/** @file

+  PCI Library functions that use I/O ports 0xCF8 and 0xCFC to perform

+  PCI Configuration cycles. Layers on top of one PCI CF8 Library instance.

+

+  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.

+

+**/

+

+

+#include <Base.h>

+

+#include <Library/PciLib.h>

+#include <Library/PciCf8Lib.h>

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration registers 

+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  return PciCf8RegisterForRuntimeAccess (Address);

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return PciCf8Read8 (Address);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return PciCf8Write8 (Address, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8Or8 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciCf8And8 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8AndThenOr8 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciCf8BitFieldRead8 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  return PciCf8Read16 (Address);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  return PciCf8Write16 (Address, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8Or16 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciCf8And16 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8AndThenOr16 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciCf8BitFieldRead16 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  return PciCf8Read32 (Address);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  return PciCf8Write32 (Address, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8Or32 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciCf8And32 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8AndThenOr32 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciCf8BitFieldRead32 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  return PciCf8ReadBuffer (StartAddress, Size, Buffer);

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  return PciCf8WriteBuffer (StartAddress, Size, Buffer);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf b/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
new file mode 100644
index 0000000..9df8117
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
@@ -0,0 +1,41 @@
+## @file

+#  Instance of PCI Library based on PCI Express Library.

+#

+#  PCI Library that uses the 256 MB PCI Express MMIO window to perform PCI

+#  Configuration cycles. Layers on one PCI Express Library instance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePciLibPciExpress

+  MODULE_UNI_FILE                = BasePciLibPciExpress.uni

+  FILE_GUID                      = 8987081e-daeb-44a9-8bef-a195b22d9417

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PciExpressLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.uni b/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.uni
new file mode 100644
index 0000000..3e23802
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/PciLib.c
new file mode 100644
index 0000000..487a038
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePciLibPciExpress/PciLib.c
@@ -0,0 +1,1138 @@
+/** @file

+  PCI Library functions that use the 256 MB PCI Express MMIO window to perform PCI

+  Configuration cycles. Layers on PCI Express Library.

+

+  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.

+

+**/

+

+

+#include <Base.h>

+

+#include <Library/PciLib.h>

+#include <Library/PciExpressLib.h>

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration registers 

+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  return PciExpressRegisterForRuntimeAccess (Address);

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return PciExpressRead8 (Address);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return PciExpressWrite8 (Address, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressOr8 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciExpressAnd8 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressAndThenOr8 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciExpressBitFieldRead8 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  return PciExpressRead16 (Address);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  return PciExpressWrite16 (Address, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressOr16 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciExpressAnd16 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressAndThenOr16 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciExpressBitFieldRead16 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  return PciExpressRead32 (Address);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  return PciExpressWrite32 (Address, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressOr32 (Address, OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciExpressAnd32 (Address, AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressAndThenOr32 (Address, AndData, OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return PciExpressBitFieldRead32 (Address, StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData);

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData);

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  return PciExpressReadBuffer (StartAddress, Size, Buffer);

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  return PciExpressWriteBuffer (StartAddress, Size, Buffer);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
new file mode 100644
index 0000000..ecc770a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
@@ -0,0 +1,38 @@
+## @file

+#  Null PE/Coff Extra Action library instances with empty functions.

+#

+#  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeCoffExtraActionLibNull

+  MODULE_UNI_FILE                = PeCoffExtraActionLibNull.uni

+  FILE_GUID                      = 0EB84DA1-267A-40b4-8347-1F48694C8B47

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeCoffExtraActionLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PeCoffExtraActionLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/PeCoffExtraActionLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/PeCoffExtraActionLib.c
new file mode 100644
index 0000000..3fb2827
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/PeCoffExtraActionLib.c
@@ -0,0 +1,54 @@
+/** @file

+  Null PE/Coff Extra Action library instances with empty functions.

+

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/PeCoffExtraActionLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Performs additional actions after a PE/COFF image has been loaded and relocated.

+

+  If ImageContext is NULL, then ASSERT().

+

+  @param  ImageContext  The pointer to the image context structure that describes the

+                        PE/COFF image that has already been loaded and relocated.

+

+**/

+VOID

+EFIAPI

+PeCoffLoaderRelocateImageExtraAction (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  ASSERT (ImageContext != NULL);

+}  

+

+/**

+  Performs additional actions just before a PE/COFF image is unloaded.  Any resources

+  that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.

+  

+  If ImageContext is NULL, then ASSERT().

+  

+  @param  ImageContext  The pointer to the image context structure that describes the

+                        PE/COFF image that is being unloaded.

+

+**/

+VOID

+EFIAPI

+PeCoffLoaderUnloadImageExtraAction (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  ASSERT (ImageContext != NULL);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/PeCoffExtraActionLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/PeCoffExtraActionLibNull.uni
new file mode 100644
index 0000000..a95ab5d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffExtraActionLibNull/PeCoffExtraActionLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
new file mode 100644
index 0000000..b6eed82
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
@@ -0,0 +1,40 @@
+## @file

+#  PE/COFF Entry Point Library implementation.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePeCoffGetEntryPointLib

+  MODULE_UNI_FILE                = BasePeCoffGetEntryPointLib.uni

+  FILE_GUID                      = be490364-73d2-420d-950e-f6450ca75dfb

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeCoffGetEntryPointLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PeCoffGetEntryPoint.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.uni b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.uni
new file mode 100644
index 0000000..6e2a6a7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
new file mode 100644
index 0000000..0fb7e84
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c
@@ -0,0 +1,318 @@
+/** @file

+  Provides the services to get the entry point to a PE/COFF image that has either been 

+  loaded into memory or is executing at it's linked address.

+

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+

+#include <Base.h>

+

+#include <Library/PeCoffGetEntryPointLib.h>

+#include <Library/DebugLib.h>

+

+#include <IndustryStandard/PeImage.h>

+

+/**

+  Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded

+  into system memory with the PE/COFF Loader Library functions.

+

+  Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry

+  point in EntryPoint.  If the entry point could not be retrieved from the PE/COFF image, then

+  return RETURN_INVALID_PARAMETER.  Otherwise return RETURN_SUCCESS.

+  If Pe32Data is NULL, then ASSERT().

+  If EntryPoint is NULL, then ASSERT().

+

+  @param  Pe32Data                  The pointer to the PE/COFF image that is loaded in system memory.

+  @param  EntryPoint                The pointer to entry point to the PE/COFF image to return.

+

+  @retval RETURN_SUCCESS            EntryPoint was returned.

+  @retval RETURN_INVALID_PARAMETER  The entry point could not be found in the PE/COFF image.

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetEntryPoint (

+  IN  VOID  *Pe32Data,

+  OUT VOID  **EntryPoint

+  )

+{

+  EFI_IMAGE_DOS_HEADER                  *DosHdr;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;

+

+  ASSERT (Pe32Data   != NULL);

+  ASSERT (EntryPoint != NULL);

+

+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));

+  } else {

+    //

+    // DOS image header is not present, so PE header is at the image base.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;

+  }

+

+  //

+  // Calculate the entry point relative to the start of the image.

+  // AddressOfEntryPoint is common for PE32 & PE32+

+  //

+  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {

+    *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);

+    return RETURN_SUCCESS;

+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {

+    *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));

+    return RETURN_SUCCESS;

+  }

+

+  return RETURN_UNSUPPORTED;

+}

+

+

+/**

+  Returns the machine type of a PE/COFF image.

+

+  Returns the machine type from the PE/COFF image specified by Pe32Data.

+  If Pe32Data is NULL, then ASSERT().

+

+  @param  Pe32Data   The pointer to the PE/COFF image that is loaded in system

+                     memory.

+

+  @return Machine type or zero if not a valid image.

+

+**/

+UINT16

+EFIAPI

+PeCoffLoaderGetMachineType (

+  IN VOID  *Pe32Data

+  )

+{

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;

+  EFI_IMAGE_DOS_HEADER                 *DosHdr;

+

+  ASSERT (Pe32Data != NULL);

+

+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));

+  } else {

+    //

+    // DOS image header is not present, so PE header is at the image base.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;

+  }

+

+  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {

+    return Hdr.Te->Machine;

+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)  {

+    return Hdr.Pe32->FileHeader.Machine;

+  }

+

+  return 0x0000;

+}

+

+/**

+  Returns a pointer to the PDB file name for a PE/COFF image that has been

+  loaded into system memory with the PE/COFF Loader Library functions. 

+

+  Returns the PDB file name for the PE/COFF image specified by Pe32Data.  If

+  the PE/COFF image specified by Pe32Data is not a valid, then NULL is

+  returned.  If the PE/COFF image specified by Pe32Data does not contain a

+  debug directory entry, then NULL is returned.  If the debug directory entry

+  in the PE/COFF image specified by Pe32Data does not contain a PDB file name,

+  then NULL is returned.

+  If Pe32Data is NULL, then ASSERT().

+

+  @param  Pe32Data   The pointer to the PE/COFF image that is loaded in system

+                     memory.

+

+  @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL

+          if it cannot be retrieved.

+

+**/

+VOID *

+EFIAPI

+PeCoffLoaderGetPdbPointer (

+  IN VOID  *Pe32Data

+  )

+{

+  EFI_IMAGE_DOS_HEADER                  *DosHdr;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;

+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;

+  UINTN                                 DirCount;

+  VOID                                  *CodeViewEntryPointer;

+  INTN                                  TEImageAdjust;

+  UINT32                                NumberOfRvaAndSizes;

+  UINT16                                Magic;

+

+  ASSERT (Pe32Data   != NULL);

+

+  TEImageAdjust       = 0;

+  DirectoryEntry      = NULL;

+  DebugEntry          = NULL;

+  NumberOfRvaAndSizes = 0;

+

+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));

+  } else {

+    //

+    // DOS image header is not present, so PE header is at the image base.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;

+  }

+

+  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {

+    if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {

+      DirectoryEntry  = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];

+      TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;

+      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +

+                    Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +

+                    TEImageAdjust);

+    }

+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {

+    //

+    // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.

+    //       It is due to backward-compatibility, for some system might

+    //       generate PE32+ image with PE32 Magic.

+    //

+    switch (Hdr.Pe32->FileHeader.Machine) {

+    case IMAGE_FILE_MACHINE_I386:

+      //

+      // Assume PE32 image with IA32 Machine field.

+      //

+      Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;

+      break;

+    case IMAGE_FILE_MACHINE_X64:

+    case IMAGE_FILE_MACHINE_IA64:

+      //

+      // Assume PE32+ image with x64 or IA64 Machine field

+      //

+      Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;

+      break;

+    default:

+      //

+      // For unknow Machine field, use Magic in optional Header

+      //

+      Magic = Hdr.Pe32->OptionalHeader.Magic;

+    }

+

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset get Debug Directory Entry

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);

+    } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {

+      //

+      // Use PE32+ offset get Debug Directory Entry

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);

+    }

+

+    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+      DirectoryEntry = NULL;

+      DebugEntry = NULL;

+    }

+  } else {

+    return NULL;

+  }

+

+  if (DebugEntry == NULL || DirectoryEntry == NULL) {

+    return NULL;

+  }

+

+  //

+  // Scan the directory to find the debug entry.

+  // 

+  for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {

+    if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+      if (DebugEntry->SizeOfData > 0) {

+        CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);

+        switch (* (UINT32 *) CodeViewEntryPointer) {

+        case CODEVIEW_SIGNATURE_NB10:

+          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));

+        case CODEVIEW_SIGNATURE_RSDS:

+          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));

+        case CODEVIEW_SIGNATURE_MTOC:

+          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));

+        default:

+          break;

+        }

+      }

+    }

+  }

+

+  return NULL;

+}

+

+/**

+  Returns the size of the PE/COFF headers

+

+  Returns the size of the PE/COFF header specified by Pe32Data.

+  If Pe32Data is NULL, then ASSERT().

+

+  @param  Pe32Data   The pointer to the PE/COFF image that is loaded in system

+                     memory.

+

+  @return Size of PE/COFF header in bytes or zero if not a valid image.

+

+**/

+UINT32

+EFIAPI

+PeCoffGetSizeOfHeaders (

+  IN VOID     *Pe32Data

+  )

+{

+  EFI_IMAGE_DOS_HEADER                  *DosHdr;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;

+  UINTN                                 SizeOfHeaders;

+

+  ASSERT (Pe32Data   != NULL);

+ 

+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image header.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));

+  } else {

+    //

+    // DOS image header is not present, so PE header is at the image base.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;

+  }

+

+  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {

+    SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;

+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {

+    SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;

+  } else {

+    SizeOfHeaders = 0;

+  }

+

+  return (UINT32) SizeOfHeaders;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/AArch64/PeCoffLoaderEx.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/AArch64/PeCoffLoaderEx.c
new file mode 100644
index 0000000..7e4b4db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/AArch64/PeCoffLoaderEx.c
@@ -0,0 +1,127 @@
+/** @file

+  Specific relocation fixups for ARM architecture.

+

+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>

+  Portions copyright (c) 2011 - 2013, 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

+  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 "BasePeCoffLibInternals.h"

+#include <Library/BaseLib.h>

+

+// Note: Currently only large memory model is supported by UEFI relocation code.

+

+/**

+  Performs an AARCH64-based specific relocation fixup and is a no-op on other

+  instruction sets.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT64      *Fixup64;

+

+  switch ((*Reloc) >> 12) {

+

+    case EFI_IMAGE_REL_BASED_DIR64:

+      Fixup64 = (UINT64 *) Fixup;

+      *Fixup64 = *Fixup64 + (UINT64) Adjust;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *Fixup64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Returns TRUE if the machine type of PE/COFF image is supported. Supported

+  does not mean the image can be executed it means the PE/COFF loader supports

+  loading and relocating of the image type. It's up to the caller to support

+  the entry point.

+

+  @param  Machine   Machine type from the PE Header.

+

+  @return TRUE if this PE/COFF loader can load the image

+

+**/

+BOOLEAN

+PeCoffLoaderImageFormatSupported (

+  IN  UINT16  Machine

+  )

+{

+  if ((Machine == IMAGE_FILE_MACHINE_ARM64) || (Machine ==  IMAGE_FILE_MACHINE_EBC)) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+/**

+  Performs an ARM-based specific re-relocation fixup and is a no-op on other

+  instruction sets. This is used to re-relocated the image into the EFI virtual

+  space for runtime calls.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT64  *Fixup64;

+

+  switch ((*Reloc) >> 12) {

+  case EFI_IMAGE_REL_BASED_DIR64:

+    Fixup64     = (UINT64 *) Fixup;

+    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));

+    if (*(UINT64 *) (*FixupData) == *Fixup64) {

+      *Fixup64 = *Fixup64 + (UINT64) Adjust;

+    }

+

+    *FixupData = *FixupData + sizeof (UINT64);

+    break;

+

+  default:

+    DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));

+    return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c
new file mode 100644
index 0000000..d6bf427
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c
@@ -0,0 +1,249 @@
+/** @file

+  Specific relocation fixups for ARM architecture.

+

+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>

+  Portions copyright (c) 2008 - 2010, 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.

+

+**/

+

+#include "BasePeCoffLibInternals.h"

+#include <Library/BaseLib.h>

+

+

+/**

+  Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and 

+  return the immediate data encoded in the instruction.

+

+  @param  Instruction   Pointer to ARM MOVT or MOVW immediate instruction

+

+  @return Immediate address encoded in the instruction

+

+**/

+UINT16

+ThumbMovtImmediateAddress (

+  IN UINT16 *Instruction

+  )

+{

+  UINT32  Movt;

+  UINT16  Address;

+  

+  // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction

+  // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000

+  Movt = (*Instruction << 16) | (*(Instruction + 1)); 

+

+  // imm16 = imm4:i:imm3:imm8

+  //         imm4 -> Bit19:Bit16

+  //         i    -> Bit26

+  //         imm3 -> Bit14:Bit12

+  //         imm8 -> Bit7:Bit0

+  Address  = (UINT16)(Movt & 0x000000ff);         // imm8

+  Address |= (UINT16)((Movt >> 4) &  0x0000f700); // imm4 imm3

+  Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i

+  return Address;

+}

+

+

+/**

+  Update an ARM MOVT or MOVW immediate instruction immediate data.

+

+  @param  Instruction   Pointer to ARM MOVT or MOVW immediate instruction

+  @param  Address       New addres to patch into the instruction

+**/

+VOID

+ThumbMovtImmediatePatch (

+  IN OUT UINT16 *Instruction,

+  IN     UINT16 Address

+  )

+{

+  UINT16  Patch;

+

+  // First 16-bit chunk of instruciton

+  Patch  = ((Address >> 12) & 0x000f);            // imm4 

+  Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i

+  // Mask out instruction bits and or in address

+  *(Instruction) = (*Instruction & ~0x040f) | Patch;

+

+  // Second 16-bit chunk of instruction

+  Patch  =  Address & 0x000000ff;          // imm8

+  Patch |=  ((Address << 4) & 0x00007000); // imm3

+  // Mask out instruction bits and or in address

+  Instruction++;

+  *Instruction = (*Instruction & ~0x70ff) | Patch;

+}

+

+

+

+/**

+  Pass in a pointer to an ARM MOVW/MOVT instruciton pair and 

+  return the immediate data encoded in the two` instruction.

+

+  @param  Instructions  Pointer to ARM MOVW/MOVT insturction pair

+

+  @return Immediate address encoded in the instructions

+

+**/

+UINT32

+ThumbMovwMovtImmediateAddress (

+  IN UINT16 *Instructions

+  )

+{

+  UINT16  *Word;

+  UINT16  *Top;

+  

+  Word = Instructions;  // MOVW

+  Top  = Word + 2;      // MOVT

+  

+  return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);

+}

+

+

+/**

+  Update an ARM MOVW/MOVT immediate instruction instruction pair.

+

+  @param  Instructions  Pointer to ARM MOVW/MOVT instruction pair

+  @param  Address       New addres to patch into the instructions

+**/

+VOID

+ThumbMovwMovtImmediatePatch (

+  IN OUT UINT16 *Instructions,

+  IN     UINT32 Address

+  )

+{

+  UINT16  *Word;

+  UINT16  *Top;

+  

+  Word = Instructions;  // MOVW

+  Top  = Word + 2;      // MOVT

+

+  ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));

+  ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));

+}

+  

+  

+

+/**

+  Performs an ARM-based specific relocation fixup and is a no-op on other

+  instruction sets.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT16      *Fixup16;

+  UINT32      FixupVal;

+

+  Fixup16   = (UINT16 *) Fixup;

+

+  switch ((*Reloc) >> 12) {

+  

+  case EFI_IMAGE_REL_BASED_ARM_MOV32T:

+    FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;

+    ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);

+

+    if (*FixupData != NULL) {

+      *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+      // Fixup16 is not aligned so we must copy it. Thumb instructions are streams of 16 bytes. 

+      CopyMem (*FixupData, Fixup16, sizeof (UINT64));

+      *FixupData = *FixupData + sizeof(UINT64);

+    }

+    break;

+  

+  case EFI_IMAGE_REL_BASED_ARM_MOV32A:

+     ASSERT (FALSE);

+     // break omitted - ARM instruction encoding not implemented

+  default:

+    return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Returns TRUE if the machine type of PE/COFF image is supported. Supported

+  does not mean the image can be executed it means the PE/COFF loader supports

+  loading and relocating of the image type. It's up to the caller to support

+  the entry point.

+  

+  @param  Machine   Machine type from the PE Header.

+

+  @return TRUE if this PE/COFF loader can load the image

+

+**/

+BOOLEAN

+PeCoffLoaderImageFormatSupported (

+  IN  UINT16  Machine

+  )

+{

+  if ((Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || (Machine ==  IMAGE_FILE_MACHINE_EBC)) {

+    return TRUE; 

+  }

+

+  return FALSE;

+}

+

+/**

+  Performs an ARM-based specific re-relocation fixup and is a no-op on other

+  instruction sets. This is used to re-relocated the image into the EFI virtual

+  space for runtime calls.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT16  *Fixup16;

+  UINT32  FixupVal;

+

+  Fixup16 = (UINT16 *)Fixup;

+

+  switch ((*Reloc) >> 12) {

+

+  case EFI_IMAGE_REL_BASED_ARM_MOV32T:

+    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));

+    if (*(UINT64 *) (*FixupData) == ReadUnaligned64 ((UINT64 *)Fixup16)) {

+      FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;

+      ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);

+    }

+    break;

+  

+  case EFI_IMAGE_REL_BASED_ARM_MOV32A:

+    ASSERT (FALSE);

+    // break omitted - ARM instruction encoding not implemented

+  default:

+    DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));

+    return RETURN_UNSUPPORTED;

+  }

+  

+  return RETURN_SUCCESS;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
new file mode 100644
index 0000000..33cad23
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -0,0 +1,1959 @@
+/** @file

+  Base PE/COFF loader supports loading any PE32/PE32+ or TE image, but

+  only supports relocating IA32, x64, IPF, and EBC images.

+

+  Caution: This file requires additional review when modified.

+  This library will have external input - PE/COFF image.

+  This external input must be validated carefully to avoid security issue like

+  buffer overflow, integer overflow.

+

+  The basic guideline is that caller need provide ImageContext->ImageRead () with the

+  necessary data range check, to make sure when this library reads PE/COFF image, the

+  PE image buffer is always in valid range.

+  This library will also do some additional check for PE header fields.

+

+  PeCoffLoaderGetPeHeader() routine will do basic check for PE/COFF header.

+  PeCoffLoaderGetImageInfo() routine will do basic check for whole PE/COFF image.

+

+  Copyright (c) 2006 - 2014, 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.

+

+**/

+

+#include "BasePeCoffLibInternals.h"

+

+/**

+  Adjust some fields in section header for TE image.

+

+  @param  SectionHeader             Pointer to the section header.

+  @param  TeStrippedOffset          Size adjust for the TE image.

+

+**/

+VOID

+PeCoffLoaderAdjustOffsetForTeImage (

+  EFI_IMAGE_SECTION_HEADER              *SectionHeader,

+  UINT32                                TeStrippedOffset

+  )

+{

+  SectionHeader->VirtualAddress   -= TeStrippedOffset;

+  SectionHeader->PointerToRawData -= TeStrippedOffset;

+}

+

+/**

+  Retrieves the magic value from the PE/COFF header.

+

+  @param  Hdr             The buffer in which to return the PE32, PE32+, or TE header.

+

+  @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32

+  @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+

+

+**/

+UINT16

+PeCoffLoaderGetPeHeaderMagicValue (

+  IN  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr

+  )

+{

+  //

+  // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value 

+  //       in the PE/COFF Header.  If the MachineType is Itanium(IA64) and the 

+  //       Magic value in the OptionalHeader is  EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC

+  //       then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC

+  //

+  if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+    return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;

+  }

+  //

+  // Return the magic value from the PC/COFF Optional Header

+  //

+  return Hdr.Pe32->OptionalHeader.Magic;

+}

+

+

+/**

+  Retrieves the PE or TE Header from a PE/COFF or TE image. 

+

+  Caution: This function may receive untrusted input.

+  PE/COFF image is external input, so this routine will 

+  also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader, 

+  SizeOfHeader, Section Data Region and Security Data Region be in PE image range. 

+

+  @param  ImageContext    The context of the image being loaded.

+  @param  Hdr             The buffer in which to return the PE32, PE32+, or TE header.

+

+  @retval RETURN_SUCCESS  The PE or TE Header is read.

+  @retval Other           The error status from reading the PE/COFF or TE image using the ImageRead function.

+

+**/

+RETURN_STATUS

+PeCoffLoaderGetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext,

+  OUT    EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr

+  )

+{

+  RETURN_STATUS         Status;

+  EFI_IMAGE_DOS_HEADER  DosHdr;

+  UINTN                 Size;

+  UINTN                 ReadSize;

+  UINT16                Magic;

+  UINT32                SectionHeaderOffset;

+  UINT32                Index;

+  UINT32                HeaderWithoutDataDir;

+  CHAR8                 BufferData;

+  UINTN                 NumberOfSections;

+  EFI_IMAGE_SECTION_HEADER  SectionHeader;

+

+  //

+  // Read the DOS image header to check for its existence

+  //

+  Size = sizeof (EFI_IMAGE_DOS_HEADER);

+  ReadSize = Size;

+  Status = ImageContext->ImageRead (

+                           ImageContext->Handle,

+                           0,

+                           &Size,

+                           &DosHdr

+                           );

+  if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    if (Size != ReadSize) {

+      Status = RETURN_UNSUPPORTED;

+    }

+    return Status;

+  }

+

+  ImageContext->PeCoffHeaderOffset = 0;

+  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // DOS image header is present, so read the PE header after the DOS image

+    // header

+    //

+    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;

+  }

+

+  //

+  // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much

+  // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic

+  // determines if this is a PE32 or PE32+ image. The magic is in the same

+  // location in both images.

+  //

+  Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);

+  ReadSize = Size;

+  Status = ImageContext->ImageRead (

+                           ImageContext->Handle,

+                           ImageContext->PeCoffHeaderOffset,

+                           &Size,

+                           Hdr.Pe32

+                           );

+  if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    if (Size != ReadSize) {

+      Status = RETURN_UNSUPPORTED;

+    }

+    return Status;

+  }

+

+  //

+  // Use Signature to figure out if we understand the image format

+  //

+  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {

+    ImageContext->IsTeImage         = TRUE;

+    ImageContext->Machine           = Hdr.Te->Machine;

+    ImageContext->ImageType         = (UINT16)(Hdr.Te->Subsystem);

+    //

+    // For TeImage, SectionAlignment is undefined to be set to Zero

+    // ImageSize can be calculated.

+    //

+    ImageContext->ImageSize         = 0;

+    ImageContext->SectionAlignment  = 0;

+    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;

+

+    //

+    // Check the StrippedSize.

+    //

+    if (sizeof (EFI_TE_IMAGE_HEADER) >= (UINT32)Hdr.Te->StrippedSize) {

+      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+      return RETURN_UNSUPPORTED;

+    }

+

+    //

+    // Check the SizeOfHeaders field.

+    //

+    if (Hdr.Te->BaseOfCode <= Hdr.Te->StrippedSize) {

+      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+      return RETURN_UNSUPPORTED;

+    }

+

+    //

+    // Read last byte of Hdr.Te->SizeOfHeaders from the file.

+    //

+    Size = 1;

+    ReadSize = Size;

+    Status = ImageContext->ImageRead (

+                             ImageContext->Handle,

+                             ImageContext->SizeOfHeaders - 1,

+                             &Size,

+                             &BufferData

+                             );

+    if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+      if (Size != ReadSize) {

+        Status = RETURN_UNSUPPORTED;

+      }

+      return Status;

+    }

+

+    //

+    // TE Image Data Directory Entry size is non-zero, but the Data Directory Virtual Address is zero.

+    // This case is not a valid TE image. 

+    //

+    if ((Hdr.Te->DataDirectory[0].Size != 0 && Hdr.Te->DataDirectory[0].VirtualAddress == 0) ||

+        (Hdr.Te->DataDirectory[1].Size != 0 && Hdr.Te->DataDirectory[1].VirtualAddress == 0)) {

+      ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+      return RETURN_UNSUPPORTED;

+    }

+  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE)  {

+    ImageContext->IsTeImage = FALSE;

+    ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;

+

+    Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);

+

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // 1. Check OptionalHeader.NumberOfRvaAndSizes filed.

+      //

+      if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // 2. Check the FileHeader.SizeOfOptionalHeader field.

+      // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so 

+      // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow.

+      //

+      HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER32) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;

+      if (((UINT32)Hdr.Pe32->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=

+          Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32->FileHeader.SizeOfOptionalHeader;

+      //

+      // 3. Check the FileHeader.NumberOfSections field.

+      //

+      if (Hdr.Pe32->OptionalHeader.SizeOfImage <= SectionHeaderOffset) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      if ((Hdr.Pe32->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32->FileHeader.NumberOfSections) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // 4. Check the OptionalHeader.SizeOfHeaders field.

+      //

+      if (Hdr.Pe32->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      if (Hdr.Pe32->OptionalHeader.SizeOfHeaders >= Hdr.Pe32->OptionalHeader.SizeOfImage) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      if ((Hdr.Pe32->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32->FileHeader.NumberOfSections) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // 4.2 Read last byte of Hdr.Pe32.OptionalHeader.SizeOfHeaders from the file.

+      //

+      Size = 1;

+      ReadSize = Size;

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle,

+                               Hdr.Pe32->OptionalHeader.SizeOfHeaders - 1,

+                               &Size,

+                               &BufferData

+                               );

+      if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        if (Size != ReadSize) {

+          Status = RETURN_UNSUPPORTED;

+        }

+        return Status;

+      }

+

+      //

+      // Check the EFI_IMAGE_DIRECTORY_ENTRY_SECURITY data.

+      // Read the last byte to make sure the data is in the image region.

+      // The DataDirectory array begin with 1, not 0, so here use < to compare not <=.

+      //

+      if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) {

+        if (Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size != 0) {

+          //

+          // Check the member data to avoid overflow.

+          //

+          if ((UINT32) (~0) - Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <

+              Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {

+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+            return RETURN_UNSUPPORTED;

+          }

+

+          //

+          // Read last byte of section header from file

+          //

+          Size = 1;

+          ReadSize = Size;

+          Status = ImageContext->ImageRead (

+                                   ImageContext->Handle,

+                                   Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress +

+                                    Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - 1,

+                                   &Size,

+                                   &BufferData

+                                   );

+          if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            if (Size != ReadSize) {

+              Status = RETURN_UNSUPPORTED;

+            }

+            return Status;

+          }

+        }

+      }

+

+      //

+      // Use PE32 offset

+      //

+      ImageContext->ImageType         = Hdr.Pe32->OptionalHeader.Subsystem;

+      ImageContext->ImageSize         = (UINT64)Hdr.Pe32->OptionalHeader.SizeOfImage;

+      ImageContext->SectionAlignment  = Hdr.Pe32->OptionalHeader.SectionAlignment;

+      ImageContext->SizeOfHeaders     = Hdr.Pe32->OptionalHeader.SizeOfHeaders;

+

+    } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {

+      //

+      // 1. Check FileHeader.NumberOfRvaAndSizes filed.

+      //

+      if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      //

+      // 2. Check the FileHeader.SizeOfOptionalHeader field.

+      // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so 

+      // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow.

+      //

+      HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER64) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;

+      if (((UINT32)Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) !=

+          Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;

+      //

+      // 3. Check the FileHeader.NumberOfSections field.

+      //

+      if (Hdr.Pe32Plus->OptionalHeader.SizeOfImage <= SectionHeaderOffset) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      if ((Hdr.Pe32Plus->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32Plus->FileHeader.NumberOfSections) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // 4. Check the OptionalHeader.SizeOfHeaders field.

+      //

+      if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders >= Hdr.Pe32Plus->OptionalHeader.SizeOfImage) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+      if ((Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32Plus->FileHeader.NumberOfSections) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // 4.2 Read last byte of Hdr.Pe32Plus.OptionalHeader.SizeOfHeaders from the file.

+      //

+      Size = 1;

+      ReadSize = Size;

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle,

+                               Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - 1,

+                               &Size,

+                               &BufferData

+                               );

+      if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        if (Size != ReadSize) {

+          Status = RETURN_UNSUPPORTED;

+        }

+        return Status;

+      }

+

+      //

+      // Check the EFI_IMAGE_DIRECTORY_ENTRY_SECURITY data.

+      // Read the last byte to make sure the data is in the image region.

+      // The DataDirectory array begin with 1, not 0, so here use < to compare not <=.

+      //

+      if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) {

+        if (Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size != 0) {

+          //

+          // Check the member data to avoid overflow.

+          //

+          if ((UINT32) (~0) - Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress <

+              Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) {

+            ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+            return RETURN_UNSUPPORTED;

+          }

+

+          //

+          // Read last byte of section header from file

+          //

+          Size = 1;

+          ReadSize = Size;

+          Status = ImageContext->ImageRead (

+                                   ImageContext->Handle,

+                                   Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress +

+                                    Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - 1,

+                                   &Size,

+                                   &BufferData

+                                   );

+          if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            if (Size != ReadSize) {

+              Status = RETURN_UNSUPPORTED;

+            }

+            return Status;

+          }

+        }

+      }

+

+      //

+      // Use PE32+ offset

+      //

+      ImageContext->ImageType         = Hdr.Pe32Plus->OptionalHeader.Subsystem;

+      ImageContext->ImageSize         = (UINT64) Hdr.Pe32Plus->OptionalHeader.SizeOfImage;

+      ImageContext->SectionAlignment  = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;

+      ImageContext->SizeOfHeaders     = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;

+    } else {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;

+      return RETURN_UNSUPPORTED;

+    }

+  } else {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;

+    return RETURN_UNSUPPORTED;

+  }

+

+  if (!PeCoffLoaderImageFormatSupported (ImageContext->Machine)) {

+    //

+    // If the PE/COFF loader does not support the image type return

+    // unsupported. This library can support lots of types of images

+    // this does not mean the user of this library can call the entry

+    // point of the image.

+    //

+    return RETURN_UNSUPPORTED;

+  }

+

+  //

+  // Check each section field.

+  //

+  if (ImageContext->IsTeImage) {

+    SectionHeaderOffset = sizeof(EFI_TE_IMAGE_HEADER);

+    NumberOfSections    = (UINTN) (Hdr.Te->NumberOfSections);

+  } else {

+    SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32->FileHeader.SizeOfOptionalHeader;

+    NumberOfSections    = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);

+  }

+

+  for (Index = 0; Index < NumberOfSections; Index++) {

+    //

+    // Read section header from file

+    //

+    Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+    ReadSize = Size;

+    Status = ImageContext->ImageRead (

+                             ImageContext->Handle,

+                             SectionHeaderOffset,

+                             &Size,

+                             &SectionHeader

+                             );

+    if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+      if (Size != ReadSize) {

+        Status = RETURN_UNSUPPORTED;

+      }

+      return Status;

+    }

+

+    //

+    // Adjust some field in Section Header for TE image.

+    //

+    if (ImageContext->IsTeImage) {

+      PeCoffLoaderAdjustOffsetForTeImage (&SectionHeader, (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));

+    }

+

+    if (SectionHeader.SizeOfRawData > 0) {

+      //

+      // Section data should bigger than the Pe header.

+      //

+      if (SectionHeader.VirtualAddress < ImageContext->SizeOfHeaders || 

+          SectionHeader.PointerToRawData < ImageContext->SizeOfHeaders) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // Check the member data to avoid overflow.

+      //

+      if ((UINT32) (~0) - SectionHeader.PointerToRawData < SectionHeader.SizeOfRawData) {

+        ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+        return RETURN_UNSUPPORTED;

+      }

+

+      //

+      // Base on the ImageRead function to check the section data field.

+      // Read the last byte to make sure the data is in the image region.

+      //

+      Size = 1;

+      ReadSize = Size;

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle,

+                               SectionHeader.PointerToRawData + SectionHeader.SizeOfRawData - 1,

+                               &Size,

+                               &BufferData

+                               );

+      if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        if (Size != ReadSize) {

+          Status = RETURN_UNSUPPORTED;

+        }

+        return Status;

+      }

+    }

+

+    //

+    // Check next section.

+    //

+    SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+  }

+

+  return RETURN_SUCCESS;

+}

+

+

+/**

+  Retrieves information about a PE/COFF image.

+

+  Computes the PeCoffHeaderOffset, IsTeImage, ImageType, ImageAddress, ImageSize, 

+  DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders, and 

+  DebugDirectoryEntryRva fields of the ImageContext structure.  

+  If ImageContext is NULL, then return RETURN_INVALID_PARAMETER.  

+  If the PE/COFF image accessed through the ImageRead service in the ImageContext 

+  structure is not a supported PE/COFF image type, then return RETURN_UNSUPPORTED.  

+  If any errors occur while computing the fields of ImageContext, 

+  then the error status is returned in the ImageError field of ImageContext.  

+  If the image is a TE image, then SectionAlignment is set to 0.

+  The ImageRead and Handle fields of ImageContext structure must be valid prior 

+  to invoking this service.

+

+  Caution: This function may receive untrusted input.

+  PE/COFF image is external input, so this routine will 

+  also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader, 

+  SizeOfHeader, Section Data Region and Security Data Region be in PE image range. 

+

+  @param  ImageContext              The pointer to the image context structure that describes the PE/COFF

+                                    image that needs to be examined by this function.

+

+  @retval RETURN_SUCCESS            The information on the PE/COFF image was collected.

+  @retval RETURN_INVALID_PARAMETER  ImageContext is NULL.

+  @retval RETURN_UNSUPPORTED        The PE/COFF image is not supported.

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderGetImageInfo (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  RETURN_STATUS                         Status;

+  EFI_IMAGE_OPTIONAL_HEADER_UNION       HdrData;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;

+  EFI_IMAGE_DATA_DIRECTORY              *DebugDirectoryEntry;

+  UINTN                                 Size;

+  UINTN                                 ReadSize;

+  UINTN                                 Index;

+  UINTN                                 DebugDirectoryEntryRva;

+  UINTN                                 DebugDirectoryEntryFileOffset;

+  UINTN                                 SectionHeaderOffset;

+  EFI_IMAGE_SECTION_HEADER              SectionHeader;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       DebugEntry;

+  UINT32                                NumberOfRvaAndSizes;

+  UINT16                                Magic;

+  UINT32                                TeStrippedOffset;

+

+  if (ImageContext == NULL) {

+    return RETURN_INVALID_PARAMETER;

+  }

+  //

+  // Assume success

+  //

+  ImageContext->ImageError  = IMAGE_ERROR_SUCCESS;

+

+  Hdr.Union = &HdrData;

+  Status = PeCoffLoaderGetPeHeader (ImageContext, Hdr);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);

+

+  //

+  // Retrieve the base address of the image

+  //

+  if (!(ImageContext->IsTeImage)) {

+    TeStrippedOffset = 0;

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset

+      //

+      ImageContext->ImageAddress = Hdr.Pe32->OptionalHeader.ImageBase;

+    } else {

+      //

+      // Use PE32+ offset

+      //

+      ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;

+    }

+  } else {

+    TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);

+    ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + TeStrippedOffset);

+  }

+

+  //

+  // Initialize the alternate destination address to 0 indicating that it

+  // should not be used.

+  //

+  ImageContext->DestinationAddress = 0;

+

+  //

+  // Initialize the debug codeview pointer.

+  //

+  ImageContext->DebugDirectoryEntryRva = 0;

+  ImageContext->CodeView               = NULL;

+  ImageContext->PdbPointer             = NULL;

+

+  //

+  // Three cases with regards to relocations:

+  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable

+  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but

+  //   has no base relocs to apply

+  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.

+  //

+  // Look at the file header to determine if relocations have been stripped, and

+  // save this information in the image context for later use.

+  //

+  if ((!(ImageContext->IsTeImage)) && ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {

+    ImageContext->RelocationsStripped = TRUE;

+  } else if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size == 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {

+    ImageContext->RelocationsStripped = TRUE;

+  } else {

+    ImageContext->RelocationsStripped = FALSE;

+  }

+

+  if (!(ImageContext->IsTeImage)) {

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;

+      DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+    } else {

+      //

+      // Use PE32+ offset

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;

+      DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);

+    }

+

+    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {

+

+      DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;

+

+      //

+      // Determine the file offset of the debug directory...  This means we walk

+      // the sections to find which section contains the RVA of the debug

+      // directory

+      //

+      DebugDirectoryEntryFileOffset = 0;

+

+      SectionHeaderOffset = (UINTN)(

+                               ImageContext->PeCoffHeaderOffset +

+                               sizeof (UINT32) +

+                               sizeof (EFI_IMAGE_FILE_HEADER) +

+                               Hdr.Pe32->FileHeader.SizeOfOptionalHeader

+                               );

+

+      for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {

+        //

+        // Read section header from file

+        //

+        Size = sizeof (EFI_IMAGE_SECTION_HEADER);

+        ReadSize = Size;

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle,

+                                 SectionHeaderOffset,

+                                 &Size,

+                                 &SectionHeader

+                                 );

+        if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          if (Size != ReadSize) {

+            Status = RETURN_UNSUPPORTED;

+          }

+          return Status;

+        }

+

+        if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+            DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+

+          DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;

+          break;

+        }

+

+        SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+      }

+

+      if (DebugDirectoryEntryFileOffset != 0) {

+        for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {

+          //

+          // Read next debug directory entry

+          //

+          Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+          ReadSize = Size;

+          Status = ImageContext->ImageRead (

+                                   ImageContext->Handle,

+                                   DebugDirectoryEntryFileOffset + Index,

+                                   &Size,

+                                   &DebugEntry

+                                   );

+          if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+            if (Size != ReadSize) {

+              Status = RETURN_UNSUPPORTED;

+            }

+            return Status;

+          }

+

+          //

+          // From PeCoff spec, when DebugEntry.RVA == 0 means this debug info will not load into memory.

+          // Here we will always load EFI_IMAGE_DEBUG_TYPE_CODEVIEW type debug info. so need adjust the

+          // ImageContext->ImageSize when DebugEntry.RVA == 0.

+          //

+          if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+            ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);

+            if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {

+              ImageContext->ImageSize += DebugEntry.SizeOfData;

+            }

+

+            return RETURN_SUCCESS;

+          }

+        }

+      }

+    }

+  } else {

+

+    DebugDirectoryEntry             = &Hdr.Te->DataDirectory[1];

+    DebugDirectoryEntryRva          = DebugDirectoryEntry->VirtualAddress;

+    SectionHeaderOffset             = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));

+

+    DebugDirectoryEntryFileOffset   = 0;

+

+    for (Index = 0; Index < Hdr.Te->NumberOfSections;) {

+      //

+      // Read section header from file

+      //

+      Size   = sizeof (EFI_IMAGE_SECTION_HEADER);

+      ReadSize = Size;

+      Status = ImageContext->ImageRead (

+                               ImageContext->Handle,

+                               SectionHeaderOffset,

+                               &Size,

+                               &SectionHeader

+                               );

+      if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        if (Size != ReadSize) {

+          Status = RETURN_UNSUPPORTED;

+        }

+        return Status;

+      }

+

+      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&

+          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {

+        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -

+                                        SectionHeader.VirtualAddress +

+                                        SectionHeader.PointerToRawData -

+                                        TeStrippedOffset;

+

+        //

+        // File offset of the debug directory was found, if this is not the last

+        // section, then skip to the last section for calculating the image size.

+        //

+        if (Index < (UINTN) Hdr.Te->NumberOfSections - 1) {

+          SectionHeaderOffset += (Hdr.Te->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);

+          Index = Hdr.Te->NumberOfSections - 1;

+          continue;

+        }

+      }

+

+      //

+      // In Te image header there is not a field to describe the ImageSize.

+      // Actually, the ImageSize equals the RVA plus the VirtualSize of

+      // the last section mapped into memory (Must be rounded up to

+      // a multiple of Section Alignment). Per the PE/COFF specification, the

+      // section headers in the Section Table must appear in order of the RVA

+      // values for the corresponding sections. So the ImageSize can be determined

+      // by the RVA and the VirtualSize of the last section header in the

+      // Section Table.  

+      //

+      if ((++Index) == (UINTN)Hdr.Te->NumberOfSections) {

+        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) - TeStrippedOffset;

+      }

+

+      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);

+    }

+

+    if (DebugDirectoryEntryFileOffset != 0) {

+      for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {

+        //

+        // Read next debug directory entry

+        //

+        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);

+        ReadSize = Size;

+        Status = ImageContext->ImageRead (

+                                 ImageContext->Handle,

+                                 DebugDirectoryEntryFileOffset + Index,

+                                 &Size,

+                                 &DebugEntry

+                                 );

+        if (RETURN_ERROR (Status) || (Size != ReadSize)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          if (Size != ReadSize) {

+            Status = RETURN_UNSUPPORTED;

+          }

+          return Status;

+        }

+

+        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {

+          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);

+          return RETURN_SUCCESS;

+        }

+      }

+    }

+  }

+

+  return RETURN_SUCCESS;

+}

+

+

+/**

+  Converts an image address to the loaded address.

+

+  @param  ImageContext      The context of the image being loaded.

+  @param  Address           The address to be converted to the loaded address.

+  @param  TeStrippedOffset  Stripped offset for TE image.

+

+  @return The converted address or NULL if the address can not be converted.

+

+**/

+VOID *

+PeCoffLoaderImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN     UINTN                                 Address, 

+  IN     UINTN                                 TeStrippedOffset

+  )

+{

+  //

+  // Make sure that Address and ImageSize is correct for the loaded image.

+  //

+  if (Address >= ImageContext->ImageSize + TeStrippedOffset) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+    return NULL;

+  }

+

+  return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address - TeStrippedOffset);

+}

+

+/**

+  Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage().

+

+  If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of

+  ImageContext as the relocation base address.  Otherwise, use the DestinationAddress field

+  of ImageContext as the relocation base address.  The caller must allocate the relocation

+  fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function.

+  

+  The ImageRead, Handle, PeCoffHeaderOffset,  IsTeImage, Machine, ImageType, ImageAddress, 

+  ImageSize, DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders, 

+  DebugDirectoryEntryRva, EntryPoint, FixupDataSize, CodeView, PdbPointer, and FixupData of 

+  the ImageContext structure must be valid prior to invoking this service.

+    

+  If ImageContext is NULL, then ASSERT().

+

+  Note that if the platform does not maintain coherency between the instruction cache(s) and the data

+  cache(s) in hardware, then the caller is responsible for performing cache maintenance operations

+  prior to transferring control to a PE/COFF image that is loaded using this library.

+

+  @param  ImageContext        The pointer to the image context structure that describes the PE/COFF

+                              image that is being relocated.

+

+  @retval RETURN_SUCCESS      The PE/COFF image was relocated.

+                              Extended status information is in the ImageError field of ImageContext.

+  @retval RETURN_LOAD_ERROR   The image in not a valid PE/COFF image.

+                              Extended status information is in the ImageError field of ImageContext.

+  @retval RETURN_UNSUPPORTED  A relocation record type is not supported.

+                              Extended status information is in the ImageError field of ImageContext.

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderRelocateImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  RETURN_STATUS                         Status;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;

+  EFI_IMAGE_DATA_DIRECTORY              *RelocDir;

+  UINT64                                Adjust;

+  EFI_IMAGE_BASE_RELOCATION             *RelocBaseOrg;

+  EFI_IMAGE_BASE_RELOCATION             *RelocBase;

+  EFI_IMAGE_BASE_RELOCATION             *RelocBaseEnd;

+  UINT16                                *Reloc;

+  UINT16                                *RelocEnd;

+  CHAR8                                 *Fixup;

+  CHAR8                                 *FixupBase;

+  UINT16                                *Fixup16;

+  UINT32                                *Fixup32;

+  UINT64                                *Fixup64;

+  CHAR8                                 *FixupData;

+  PHYSICAL_ADDRESS                      BaseAddress;

+  UINT32                                NumberOfRvaAndSizes;

+  UINT16                                Magic;

+  UINT32                                TeStrippedOffset;

+

+  ASSERT (ImageContext != NULL);

+

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // If there are no relocation entries, then we are done

+  //

+  if (ImageContext->RelocationsStripped) {

+    // Applies additional environment specific actions to relocate fixups 

+    // to a PE/COFF image if needed

+    PeCoffLoaderRelocateImageExtraAction (ImageContext);  

+    return RETURN_SUCCESS;

+  }

+

+  //

+  // If the destination address is not 0, use that rather than the

+  // image address as the relocation target.

+  //

+  if (ImageContext->DestinationAddress != 0) {

+    BaseAddress = ImageContext->DestinationAddress;

+  } else {

+    BaseAddress = ImageContext->ImageAddress;

+  }

+

+  if (!(ImageContext->IsTeImage)) {

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);

+    TeStrippedOffset = 0;

+    Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);

+

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset

+      //

+      Adjust = (UINT64)BaseAddress - Hdr.Pe32->OptionalHeader.ImageBase;

+      if (Adjust != 0) {

+        Hdr.Pe32->OptionalHeader.ImageBase = (UINT32)BaseAddress;

+      }

+

+      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;

+      RelocDir  = &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+    } else {

+      //

+      // Use PE32+ offset

+      //

+      Adjust = (UINT64) BaseAddress - Hdr.Pe32Plus->OptionalHeader.ImageBase;

+      if (Adjust != 0) {

+        Hdr.Pe32Plus->OptionalHeader.ImageBase = (UINT64)BaseAddress;

+      }

+

+      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;

+      RelocDir  = &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+    }

+

+    //

+    // Find the relocation block

+    // Per the PE/COFF spec, you can't assume that a given data directory

+    // is present in the image. You have to check the NumberOfRvaAndSizes in

+    // the optional header to verify a desired directory entry is there.

+    //

+    if ((NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC)) {

+      RelocDir = NULL;

+    }

+  } else {

+    Hdr.Te             = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);

+    TeStrippedOffset   = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);

+    Adjust             = (UINT64) (BaseAddress - (Hdr.Te->ImageBase + TeStrippedOffset));

+    if (Adjust != 0) {

+      Hdr.Te->ImageBase  = (UINT64) (BaseAddress - TeStrippedOffset);

+    }

+

+    //

+    // Find the relocation block

+    //

+    RelocDir = &Hdr.Te->DataDirectory[0];

+  }

+

+  if ((RelocDir != NULL) && (RelocDir->Size > 0)) {

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);

+    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext,

+                                                                            RelocDir->VirtualAddress + RelocDir->Size - 1,

+                                                                            TeStrippedOffset

+                                                                            );

+    if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {

+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+      return RETURN_LOAD_ERROR;

+    }

+  } else {

+    //

+    // Set base and end to bypass processing below.

+    //

+    RelocBase = RelocBaseEnd = NULL;    

+  }

+  RelocBaseOrg = RelocBase;

+

+  //

+  // If Adjust is not zero, then apply fix ups to the image

+  //

+  if (Adjust != 0) {

+    //

+    // Run the relocation information and apply the fixups

+    //

+    FixupData = ImageContext->FixupData;

+    while (RelocBase < RelocBaseEnd) {

+

+      Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));

+      //

+      // Add check for RelocBase->SizeOfBlock field.

+      //

+      if (RelocBase->SizeOfBlock == 0) {

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_LOAD_ERROR;

+      }

+      if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_LOAD_ERROR;

+      }

+

+      RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);

+      if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_LOAD_ERROR;

+      }

+      FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);

+      if (FixupBase == NULL) {

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_LOAD_ERROR;

+      }  

+

+      //

+      // Run this relocation record

+      //

+      while (Reloc < RelocEnd) {

+        Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);

+        if (Fixup == NULL) {

+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+          return RETURN_LOAD_ERROR;

+        }

+        switch ((*Reloc) >> 12) {

+        case EFI_IMAGE_REL_BASED_ABSOLUTE:

+          break;

+

+        case EFI_IMAGE_REL_BASED_HIGH:

+          Fixup16   = (UINT16 *) Fixup;

+          *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));

+          if (FixupData != NULL) {

+            *(UINT16 *) FixupData = *Fixup16;

+            FixupData             = FixupData + sizeof (UINT16);

+          }

+          break;

+

+        case EFI_IMAGE_REL_BASED_LOW:

+          Fixup16   = (UINT16 *) Fixup;

+          *Fixup16  = (UINT16) (*Fixup16 + (UINT16) Adjust);

+          if (FixupData != NULL) {

+            *(UINT16 *) FixupData = *Fixup16;

+            FixupData             = FixupData + sizeof (UINT16);

+          }

+          break;

+

+        case EFI_IMAGE_REL_BASED_HIGHLOW:

+          Fixup32   = (UINT32 *) Fixup;

+          *Fixup32  = *Fixup32 + (UINT32) Adjust;

+          if (FixupData != NULL) {

+            FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT32));

+            *(UINT32 *)FixupData  = *Fixup32;

+            FixupData             = FixupData + sizeof (UINT32);

+          }

+          break;

+

+        case EFI_IMAGE_REL_BASED_DIR64:

+          Fixup64 = (UINT64 *) Fixup;

+          *Fixup64 = *Fixup64 + (UINT64) Adjust;

+          if (FixupData != NULL) {

+            FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));

+            *(UINT64 *)(FixupData) = *Fixup64;

+            FixupData = FixupData + sizeof(UINT64);

+          }

+          break;

+

+        default:

+          //

+          // The common code does not handle some of the stranger IPF relocations

+          // PeCoffLoaderRelocateImageEx () adds support for these complex fixups

+          // on IPF and is a No-Op on other architectures.

+          //

+          Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);

+          if (RETURN_ERROR (Status)) {

+            ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+            return Status;

+          }

+        }

+

+        //

+        // Next relocation record

+        //

+        Reloc += 1;

+      }

+

+      //

+      // Next reloc block

+      //

+      RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;

+    }

+    ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);

+

+    //

+    // Adjust the EntryPoint to match the linked-to address

+    //

+    if (ImageContext->DestinationAddress != 0) {

+       ImageContext->EntryPoint -= (UINT64) ImageContext->ImageAddress;

+       ImageContext->EntryPoint += (UINT64) ImageContext->DestinationAddress;

+    }

+  }

+  

+  // Applies additional environment specific actions to relocate fixups 

+  // to a PE/COFF image if needed

+  PeCoffLoaderRelocateImageExtraAction (ImageContext);

+  

+  return RETURN_SUCCESS;

+}

+

+/**

+  Loads a PE/COFF image into memory.

+

+  Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer

+  specified by the ImageAddress and ImageSize fields of ImageContext.  The caller must allocate

+  the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function.

+  The EntryPoint, FixupDataSize, CodeView, PdbPointer and HiiResourceData fields of ImageContext are computed.

+  The ImageRead, Handle, PeCoffHeaderOffset,  IsTeImage,  Machine, ImageType, ImageAddress, ImageSize, 

+  DestinationAddress, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva 

+  fields of the ImageContext structure must be valid prior to invoking this service.

+  

+  If ImageContext is NULL, then ASSERT().

+

+  Note that if the platform does not maintain coherency between the instruction cache(s) and the data

+  cache(s) in hardware, then the caller is responsible for performing cache maintenance operations

+  prior to transferring control to a PE/COFF image that is loaded using this library.

+

+  @param  ImageContext              The pointer to the image context structure that describes the PE/COFF

+                                    image that is being loaded.

+

+  @retval RETURN_SUCCESS            The PE/COFF image was loaded into the buffer specified by

+                                    the ImageAddress and ImageSize fields of ImageContext.

+                                    Extended status information is in the ImageError field of ImageContext.

+  @retval RETURN_BUFFER_TOO_SMALL   The caller did not provide a large enough buffer.

+                                    Extended status information is in the ImageError field of ImageContext.

+  @retval RETURN_LOAD_ERROR         The PE/COFF image is an EFI Runtime image with no relocations.

+                                    Extended status information is in the ImageError field of ImageContext.

+  @retval RETURN_INVALID_PARAMETER  The image address is invalid.

+                                    Extended status information is in the ImageError field of ImageContext.

+

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderLoadImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  RETURN_STATUS                         Status;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;

+  PE_COFF_LOADER_IMAGE_CONTEXT          CheckContext;

+  EFI_IMAGE_SECTION_HEADER              *FirstSection;

+  EFI_IMAGE_SECTION_HEADER              *Section;

+  UINTN                                 NumberOfSections;

+  UINTN                                 Index;

+  CHAR8                                 *Base;

+  CHAR8                                 *End;

+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;

+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;

+  UINTN                                 Size;

+  UINT32                                TempDebugEntryRva;

+  UINT32                                NumberOfRvaAndSizes;

+  UINT16                                Magic;

+  EFI_IMAGE_RESOURCE_DIRECTORY          *ResourceDirectory;

+  EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY    *ResourceDirectoryEntry;

+  EFI_IMAGE_RESOURCE_DIRECTORY_STRING   *ResourceDirectoryString;

+  EFI_IMAGE_RESOURCE_DATA_ENTRY         *ResourceDataEntry;

+  CHAR16                                *String;

+  UINT32                                Offset;

+  UINT32                                TeStrippedOffset;

+

+  ASSERT (ImageContext != NULL);

+

+  //

+  // Assume success

+  //

+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;

+

+  //

+  // Copy the provided context information into our local version, get what we

+  // can from the original image, and then use that to make sure everything

+  // is legit.

+  //

+  CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));

+

+  Status = PeCoffLoaderGetImageInfo (&CheckContext);

+  if (RETURN_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Make sure there is enough allocated space for the image being loaded

+  //

+  if (ImageContext->ImageSize < CheckContext.ImageSize) {

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;

+    return RETURN_BUFFER_TOO_SMALL;

+  }

+  if (ImageContext->ImageAddress == 0) {

+    //

+    // Image cannot be loaded into 0 address.

+    //

+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+    return RETURN_INVALID_PARAMETER;

+  }

+  //

+  // If there's no relocations, then make sure it's not a runtime driver,

+  // and that it's being loaded at the linked address.

+  //

+  if (CheckContext.RelocationsStripped) {

+    //

+    // If the image does not contain relocations and it is a runtime driver

+    // then return an error.

+    //

+    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;

+      return RETURN_LOAD_ERROR;

+    }

+    //

+    // If the image does not contain relocations, and the requested load address

+    // is not the linked address, then return an error.

+    //

+    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;

+      return RETURN_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Make sure the allocated space has the proper section alignment

+  //

+  if (!(ImageContext->IsTeImage)) {

+    if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {

+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;

+      return RETURN_INVALID_PARAMETER;

+    }

+  }

+  //

+  // Read the entire PE/COFF or TE header into memory

+  //

+  if (!(ImageContext->IsTeImage)) {

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &ImageContext->SizeOfHeaders,

+                            (VOID *) (UINTN) ImageContext->ImageAddress

+                            );

+

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);

+

+    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+                      (UINTN)ImageContext->ImageAddress +

+                      ImageContext->PeCoffHeaderOffset +

+                      sizeof(UINT32) +

+                      sizeof(EFI_IMAGE_FILE_HEADER) +

+                      Hdr.Pe32->FileHeader.SizeOfOptionalHeader

+      );

+    NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);

+    TeStrippedOffset = 0;

+  } else {

+    Status = ImageContext->ImageRead (

+                            ImageContext->Handle,

+                            0,

+                            &ImageContext->SizeOfHeaders,

+                            (void *)(UINTN)ImageContext->ImageAddress

+                            );

+

+    Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);

+    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (

+                      (UINTN)ImageContext->ImageAddress +

+                      sizeof(EFI_TE_IMAGE_HEADER)

+                      );

+    NumberOfSections  = (UINTN) (Hdr.Te->NumberOfSections);

+    TeStrippedOffset  = (UINT32) Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);

+  }

+

+  if (RETURN_ERROR (Status)) {

+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+    return RETURN_LOAD_ERROR;

+  }

+

+  //

+  // Load each section of the image

+  //

+  Section = FirstSection;

+  for (Index = 0; Index < NumberOfSections; Index++) {

+    //

+    // Read the section

+    //

+    Size = (UINTN) Section->Misc.VirtualSize;

+    if ((Size == 0) || (Size > Section->SizeOfRawData)) {

+      Size = (UINTN) Section->SizeOfRawData;

+    }

+

+    //

+    // Compute sections address

+    //

+    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress, TeStrippedOffset);

+    End  = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress + Section->Misc.VirtualSize - 1, TeStrippedOffset);

+

+    //

+    // If the size of the section is non-zero and the base address or end address resolved to 0, then fail.

+    //

+    if ((Size > 0) && ((Base == NULL) || (End == NULL))) {

+      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;

+      return RETURN_LOAD_ERROR;

+    }

+

+    if (Section->SizeOfRawData > 0) {

+      Status = ImageContext->ImageRead (

+                              ImageContext->Handle,

+                              Section->PointerToRawData - TeStrippedOffset,

+                              &Size,

+                              Base

+                              );

+      if (RETURN_ERROR (Status)) {

+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+        return Status;

+      }

+    }

+

+    //

+    // If raw size is less then virtual size, zero fill the remaining

+    //

+

+    if (Size < Section->Misc.VirtualSize) {

+      ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);

+    }

+

+    //

+    // Next Section

+    //

+    Section += 1;

+  }

+

+  //

+  // Get image's entry point

+  //

+  Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);

+  if (!(ImageContext->IsTeImage)) {

+    //

+    // Sizes of AddressOfEntryPoint are different so we need to do this safely

+    //

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset

+      //

+      ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (

+                                                            ImageContext,

+                                                            (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint,

+                                                            0

+                                                            );

+    } else {

+      //

+      // Use PE32+ offset

+      //

+      ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (

+                                                            ImageContext,

+                                                            (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint,

+                                                            0

+                                                            );

+    }

+  } else {

+    ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (

+                                                          ImageContext,

+                                                          (UINTN)Hdr.Te->AddressOfEntryPoint,

+                                                          TeStrippedOffset

+                                                          );

+  }

+

+  //

+  // Determine the size of the fixup data

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory

+  // is present in the image. You have to check the NumberOfRvaAndSizes in

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (!(ImageContext->IsTeImage)) {

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+    } else {

+      //

+      // Use PE32+ offset

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];

+    }

+

+    //

+    // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.

+    //

+    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);

+    } else {

+      ImageContext->FixupDataSize = 0;

+    }

+  } else {

+    DirectoryEntry              = &Hdr.Te->DataDirectory[0];

+    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);

+  }

+  //

+  // Consumer must allocate a buffer for the relocation fixup log.

+  // Only used for runtime drivers.

+  //

+  ImageContext->FixupData = NULL;

+

+  //

+  // Load the Codeview information if present

+  //

+  if (ImageContext->DebugDirectoryEntryRva != 0) {

+    DebugEntry = PeCoffLoaderImageAddress (

+                ImageContext,

+                ImageContext->DebugDirectoryEntryRva,

+                TeStrippedOffset

+                );

+    if (DebugEntry == NULL) {

+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+      return RETURN_LOAD_ERROR;

+    }

+

+    TempDebugEntryRva = DebugEntry->RVA;

+    if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {

+      Section--;

+      if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {

+        TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;

+      } else {

+        TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;

+      }

+    }

+

+    if (TempDebugEntryRva != 0) {

+      ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva, TeStrippedOffset); 

+      if (ImageContext->CodeView == NULL) {

+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;

+        return RETURN_LOAD_ERROR;

+      }

+

+      if (DebugEntry->RVA == 0) {

+        Size = DebugEntry->SizeOfData;

+        Status = ImageContext->ImageRead (

+                                ImageContext->Handle,

+                                DebugEntry->FileOffset - TeStrippedOffset,

+                                &Size,

+                                ImageContext->CodeView

+                                );

+        //

+        // Should we apply fix up to this field according to the size difference between PE and TE?

+        // Because now we maintain TE header fields unfixed, this field will also remain as they are

+        // in original PE image.

+        //

+

+        if (RETURN_ERROR (Status)) {

+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;

+          return RETURN_LOAD_ERROR;

+        }

+

+        DebugEntry->RVA = TempDebugEntryRva;

+      }

+

+      switch (*(UINT32 *) ImageContext->CodeView) {

+      case CODEVIEW_SIGNATURE_NB10:

+        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) {

+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+          return RETURN_UNSUPPORTED;

+        }

+        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);

+        break;

+

+      case CODEVIEW_SIGNATURE_RSDS:

+        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) {

+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+          return RETURN_UNSUPPORTED;

+        }

+        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);

+        break;

+

+      case CODEVIEW_SIGNATURE_MTOC:

+        if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) {

+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+          return RETURN_UNSUPPORTED;

+        }

+        ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);

+        break;

+

+      default:

+        break;

+      }

+    }

+  }

+

+  //

+  // Get Image's HII resource section

+  //

+  ImageContext->HiiResourceData = 0;

+  if (!(ImageContext->IsTeImage)) {

+    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+      //

+      // Use PE32 offset

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];

+    } else {

+      //

+      // Use PE32+ offset

+      //

+      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;

+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];

+    }

+

+    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && DirectoryEntry->Size != 0) {

+      Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress, 0);

+      if (Base != NULL) {

+        ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base;

+        Offset = sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * 

+               (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);

+        if (Offset > DirectoryEntry->Size) {

+          ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+          return RETURN_UNSUPPORTED;

+        }

+        ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);

+

+        for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) {

+          if (ResourceDirectoryEntry->u1.s.NameIsString) {

+            //

+            // Check the ResourceDirectoryEntry->u1.s.NameOffset before use it.

+            //

+            if (ResourceDirectoryEntry->u1.s.NameOffset >= DirectoryEntry->Size) {

+              ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+              return RETURN_UNSUPPORTED;

+            }

+            ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);

+            String = &ResourceDirectoryString->String[0];

+

+            if (ResourceDirectoryString->Length == 3 &&

+                String[0] == L'H' &&

+                String[1] == L'I' &&

+                String[2] == L'I') {

+              //

+              // Resource Type "HII" found

+              //

+              if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {

+                //

+                // Move to next level - resource Name

+                //

+                if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >= DirectoryEntry->Size) {

+                  ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+                  return RETURN_UNSUPPORTED;

+                }

+                ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);

+                Offset = ResourceDirectoryEntry->u2.s.OffsetToDirectory + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + 

+                         sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);

+                if (Offset > DirectoryEntry->Size) {

+                  ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+                  return RETURN_UNSUPPORTED;

+                }

+                ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);

+

+                if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {

+                  //

+                  // Move to next level - resource Language

+                  //

+                  if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >= DirectoryEntry->Size) {

+                    ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+                    return RETURN_UNSUPPORTED;

+                  }

+                  ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);

+                  Offset = ResourceDirectoryEntry->u2.s.OffsetToDirectory + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + 

+                           sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);

+                  if (Offset > DirectoryEntry->Size) {

+                    ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+                    return RETURN_UNSUPPORTED;

+                  }

+                  ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);

+                }

+              }

+

+              //

+              // Now it ought to be resource Data

+              //

+              if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {

+                if (ResourceDirectoryEntry->u2.OffsetToData >= DirectoryEntry->Size) {

+                  ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED;

+                  return RETURN_UNSUPPORTED;

+                }

+                ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData);

+                ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData, 0);

+                break;

+              }

+            }

+          }

+          ResourceDirectoryEntry++;

+        }

+      }

+    }

+  }

+ 

+  return Status;

+}

+

+

+/**

+  Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI

+  runtime. 

+  

+  This function reapplies relocation fixups to the PE/COFF image specified by ImageBase 

+  and ImageSize so the image will execute correctly when the PE/COFF image is mapped 

+  to the address specified by VirtualImageBase.  RelocationData must be identical 

+  to the FiuxupData buffer from the PE_COFF_LOADER_IMAGE_CONTEXT structure 

+  after this PE/COFF image was relocated with PeCoffLoaderRelocateImage().

+

+  Note that if the platform does not maintain coherency between the instruction cache(s) and the data

+  cache(s) in hardware, then the caller is responsible for performing cache maintenance operations

+  prior to transferring control to a PE/COFF image that is loaded using this library.

+

+  @param  ImageBase          The base address of a PE/COFF image that has been loaded 

+                             and relocated into system memory.

+  @param  VirtImageBase      The request virtual address that the PE/COFF image is to

+                             be fixed up for.

+  @param  ImageSize          The size, in bytes, of the PE/COFF image.

+  @param  RelocationData     A pointer to the relocation data that was collected when the PE/COFF 

+                             image was relocated using PeCoffLoaderRelocateImage().

+  

+**/

+VOID

+EFIAPI

+PeCoffLoaderRelocateImageForRuntime (

+  IN  PHYSICAL_ADDRESS        ImageBase,

+  IN  PHYSICAL_ADDRESS        VirtImageBase,

+  IN  UINTN                   ImageSize,

+  IN  VOID                    *RelocationData

+  )

+{

+  CHAR8                               *OldBase;

+  CHAR8                               *NewBase;

+  EFI_IMAGE_DOS_HEADER                *DosHdr;

+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;

+  UINT32                              NumberOfRvaAndSizes;

+  EFI_IMAGE_DATA_DIRECTORY            *DataDirectory;

+  EFI_IMAGE_DATA_DIRECTORY            *RelocDir;

+  EFI_IMAGE_BASE_RELOCATION           *RelocBase;

+  EFI_IMAGE_BASE_RELOCATION           *RelocBaseEnd;

+  UINT16                              *Reloc;

+  UINT16                              *RelocEnd;

+  CHAR8                               *Fixup;

+  CHAR8                               *FixupBase;

+  UINT16                              *Fixup16;

+  UINT32                              *Fixup32;

+  UINT64                              *Fixup64;

+  CHAR8                               *FixupData;

+  UINTN                               Adjust;

+  RETURN_STATUS                       Status;

+  UINT16                              Magic;

+

+  OldBase = (CHAR8 *)((UINTN)ImageBase);

+  NewBase = (CHAR8 *)((UINTN)VirtImageBase);

+  Adjust = (UINTN) NewBase - (UINTN) OldBase;

+

+  //

+  // Find the image's relocate dir info

+  //

+  DosHdr = (EFI_IMAGE_DOS_HEADER *)OldBase;

+  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {

+    //

+    // Valid DOS header so get address of PE header

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(((CHAR8 *)DosHdr) + DosHdr->e_lfanew);

+  } else {

+    //

+    // No Dos header so assume image starts with PE header.

+    //

+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)OldBase;

+  }

+

+  if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {

+    //

+    // Not a valid PE image so Exit

+    //

+    return ;

+  }

+

+  Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);

+

+  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {

+    //

+    // Use PE32 offset

+    //

+    NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;

+    DataDirectory = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[0]);

+  } else {

+    //

+    // Use PE32+ offset

+    //

+    NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;

+    DataDirectory = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[0]);

+  }

+

+  //

+  // Find the relocation block

+  //

+  // Per the PE/COFF spec, you can't assume that a given data directory

+  // is present in the image. You have to check the NumberOfRvaAndSizes in

+  // the optional header to verify a desired directory entry is there.

+  //

+  if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {

+    RelocDir      = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;

+    RelocBase     = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase + RelocDir->VirtualAddress);

+    RelocBaseEnd  = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase + RelocDir->VirtualAddress + RelocDir->Size);

+  } else {

+    //

+    // Cannot find relocations, cannot continue to relocate the image, ASSERT for this invalid image.

+    //

+    ASSERT (FALSE);

+    return ;

+  }

+  

+  //

+  // ASSERT for the invalid image when RelocBase and RelocBaseEnd are both NULL.

+  //

+  ASSERT (RelocBase != NULL && RelocBaseEnd != NULL);

+

+  //

+  // Run the whole relocation block. And re-fixup data that has not been

+  // modified. The FixupData is used to see if the image has been modified

+  // since it was relocated. This is so data sections that have been updated

+  // by code will not be fixed up, since that would set them back to

+  // defaults.

+  //

+  FixupData = RelocationData;

+  while (RelocBase < RelocBaseEnd) {

+    //

+    // Add check for RelocBase->SizeOfBlock field.

+    //

+    if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {

+      //

+      // Data invalid, cannot continue to relocate the image, just return.

+      //

+      return;

+    }

+

+    Reloc     = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));

+    RelocEnd  = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);

+    FixupBase = (CHAR8 *) ((UINTN)ImageBase) + RelocBase->VirtualAddress;

+

+    //

+    // Run this relocation record

+    //

+    while (Reloc < RelocEnd) {

+

+      Fixup = FixupBase + (*Reloc & 0xFFF);

+      switch ((*Reloc) >> 12) {

+

+      case EFI_IMAGE_REL_BASED_ABSOLUTE:

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGH:

+        Fixup16 = (UINT16 *) Fixup;

+        if (*(UINT16 *) FixupData == *Fixup16) {

+          *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));

+        }

+

+        FixupData = FixupData + sizeof (UINT16);

+        break;

+

+      case EFI_IMAGE_REL_BASED_LOW:

+        Fixup16 = (UINT16 *) Fixup;

+        if (*(UINT16 *) FixupData == *Fixup16) {

+          *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) Adjust & 0xffff));

+        }

+

+        FixupData = FixupData + sizeof (UINT16);

+        break;

+

+      case EFI_IMAGE_REL_BASED_HIGHLOW:

+        Fixup32       = (UINT32 *) Fixup;

+        FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));

+        if (*(UINT32 *) FixupData == *Fixup32) {

+          *Fixup32 = *Fixup32 + (UINT32) Adjust;

+        }

+

+        FixupData = FixupData + sizeof (UINT32);

+        break;

+

+      case EFI_IMAGE_REL_BASED_DIR64:

+        Fixup64       = (UINT64 *)Fixup;

+        FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64));

+        if (*(UINT64 *) FixupData == *Fixup64) {

+          *Fixup64 = *Fixup64 + (UINT64)Adjust;

+        }

+

+        FixupData = FixupData + sizeof (UINT64);

+        break;

+

+      default:

+        //

+        // Only Itanium requires ConvertPeImage_Ex

+        //

+        Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);

+        if (RETURN_ERROR (Status)) {

+          return ;

+        }

+      }

+      //

+      // Next relocation record

+      //

+      Reloc += 1;

+    }

+    //

+    // next reloc block

+    //

+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;

+  }

+}

+

+

+/**

+  Reads contents of a PE/COFF image from a buffer in system memory.

+   

+  This is the default implementation of a PE_COFF_LOADER_READ_FILE function 

+  that assumes FileHandle pointer to the beginning of a PE/COFF image.   

+  This function reads contents of the PE/COFF image that starts at the system memory 

+  address specified by FileHandle.  The read operation copies ReadSize bytes from the 

+  PE/COFF image starting at byte offset FileOffset into the buffer specified by Buffer.  

+  The size of the buffer actually read is returned in ReadSize.

+  

+  The caller must make sure the FileOffset and ReadSize within the file scope.

+

+  If FileHandle is NULL, then ASSERT().

+  If ReadSize is NULL, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+

+  @param  FileHandle        The pointer to base of the input stream

+  @param  FileOffset        Offset into the PE/COFF image to begin the read operation.

+  @param  ReadSize          On input, the size in bytes of the requested read operation.  

+                            On output, the number of bytes actually read.

+  @param  Buffer            Output buffer that contains the data read from the PE/COFF image.

+

+  @retval RETURN_SUCCESS    Data is read from FileOffset from the Handle into 

+                            the buffer.

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderImageReadFromMemory (

+  IN     VOID    *FileHandle,

+  IN     UINTN   FileOffset,

+  IN OUT UINTN   *ReadSize,

+  OUT    VOID    *Buffer

+  )

+{

+  ASSERT (ReadSize != NULL);

+  ASSERT (FileHandle != NULL);

+  ASSERT (Buffer != NULL);

+

+  CopyMem (Buffer, ((UINT8 *)FileHandle) + FileOffset, *ReadSize);

+  return RETURN_SUCCESS;

+}

+

+/**

+  Unloads a loaded PE/COFF image from memory and releases its taken resource.

+  Releases any environment specific resources that were allocated when the image 

+  specified by ImageContext was loaded using PeCoffLoaderLoadImage(). 

+ 

+  For NT32 emulator, the PE/COFF image loaded by system needs to release.

+  For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, 

+  this function can simply return RETURN_SUCCESS.

+  

+  If ImageContext is NULL, then ASSERT().

+  

+  @param  ImageContext              The pointer to the image context structure that describes the PE/COFF

+                                    image to be unloaded.

+

+  @retval RETURN_SUCCESS            The PE/COFF image was unloaded successfully.

+**/

+RETURN_STATUS

+EFIAPI

+PeCoffLoaderUnloadImage (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext

+  )

+{

+  //

+  // Applies additional environment specific actions to unload a 

+  // PE/COFF image if needed

+  //

+  PeCoffLoaderUnloadImageExtraAction (ImageContext);

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
new file mode 100644
index 0000000..576d728
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
@@ -0,0 +1,62 @@
+## @file

+#  PE/COFF Loader Library implementation.

+#  The IPF version library supports loading IPF and EBC PE/COFF image.

+#  The IA32 version library support loading IA32, X64 and EBC PE/COFF images.

+#  The X64 version library support loading IA32, X64 and EBC PE/COFF images.

+#

+#  Caution: This module requires additional review when modified.

+#  This library will have external input - PE/COFF image.

+#  This external input must be validated carefully to avoid security issue like

+#  buffer overflow, integer overflow.

+#

+#  Copyright (c) 2006 - 2014, 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePeCoffLib

+  MODULE_UNI_FILE                = BasePeCoffLib.uni

+  FILE_GUID                      = 556f5d10-7309-4af4-b80a-8196bd60946f

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeCoffLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64

+#

+

+[Sources]

+  BasePeCoffLibInternals.h

+  BasePeCoff.c

+

+[Sources.IA32, Sources.X64, Sources.EBC]

+  PeCoffLoaderEx.c

+

+[Sources.IPF]

+  Ipf/PeCoffLoaderEx.c

+

+[Sources.ARM]

+  Arm/PeCoffLoaderEx.c

+

+[Sources.AARCH64]

+  AArch64/PeCoffLoaderEx.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  PeCoffExtraActionLib

+  BaseMemoryLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
new file mode 100644
index 0000000..59908cf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
new file mode 100644
index 0000000..0851acc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
@@ -0,0 +1,133 @@
+/** @file

+  Declaration of internal functions in PE/COFF Lib.

+

+  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 __BASE_PECOFF_LIB_INTERNALS__

+#define __BASE_PECOFF_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/PeCoffLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeCoffExtraActionLib.h>

+#include <IndustryStandard/PeImage.h>

+

+

+

+/**

+  Performs an Itanium-based specific relocation fixup and is a no-op on other

+  instruction sets.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  );

+

+

+/**

+  Performs an Itanium-based specific re-relocation fixup and is a no-op on other

+  instruction sets. This is used to re-relocated the image into the EFI virtual

+  space for runtime calls.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  );

+

+

+/**

+  Returns TRUE if the machine type of PE/COFF image is supported. Supported

+  does not mean the image can be executed it means the PE/COFF loader supports

+  loading and relocating of the image type. It's up to the caller to support

+  the entry point.

+

+  @param  Machine   Machine type from the PE Header.

+

+  @return TRUE if this PE/COFF loader can load the image

+

+**/

+BOOLEAN

+PeCoffLoaderImageFormatSupported (

+  IN  UINT16  Machine

+  );

+

+/**

+  Retrieves the magic value from the PE/COFF header.

+

+  @param  Hdr             The buffer in which to return the PE32, PE32+, or TE header.

+

+  @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32

+  @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+

+

+**/

+UINT16

+PeCoffLoaderGetPeHeaderMagicValue (

+  IN  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr

+  );

+

+/**

+  Retrieves the PE or TE Header from a PE/COFF or TE image.

+

+  @param  ImageContext    The context of the image being loaded.

+  @param  Hdr             The buffer in which to return the PE32, PE32+, or TE header.

+

+  @retval RETURN_SUCCESS  The PE or TE Header is read.

+  @retval Other           The error status from reading the PE/COFF or TE image using the ImageRead function.

+

+**/

+RETURN_STATUS

+PeCoffLoaderGetPeHeader (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT         *ImageContext,

+  OUT    EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr

+  );

+

+/**

+  Converts an image address to the loaded address.

+

+  @param  ImageContext      The context of the image being loaded.

+  @param  Address           The address to be converted to the loaded address.

+  @param  TeStrippedOffset  Stripped offset for TE image.

+

+  @return The converted address or NULL if the address can not be converted.

+

+**/

+VOID *

+PeCoffLoaderImageAddress (

+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,

+  IN     UINTN                                 Address,

+  IN     UINTN                                 TeStrippedOffset

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
new file mode 100644
index 0000000..96e122b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
@@ -0,0 +1,422 @@
+/** @file

+  Fixes Intel Itanium(TM) specific relocation 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.

+

+**/

+

+#include "BasePeCoffLibInternals.h"

+

+

+

+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos)  \

+    Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)

+

+#define INS_IMM64(Value, Address, Size, InstPos, ValPos)  \

+    *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \

+          ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)

+

+#define IMM64_IMM7B_INST_WORD_X         3

+#define IMM64_IMM7B_SIZE_X              7

+#define IMM64_IMM7B_INST_WORD_POS_X     4

+#define IMM64_IMM7B_VAL_POS_X           0

+

+#define IMM64_IMM9D_INST_WORD_X         3

+#define IMM64_IMM9D_SIZE_X              9

+#define IMM64_IMM9D_INST_WORD_POS_X     18

+#define IMM64_IMM9D_VAL_POS_X           7

+

+#define IMM64_IMM5C_INST_WORD_X         3

+#define IMM64_IMM5C_SIZE_X              5

+#define IMM64_IMM5C_INST_WORD_POS_X     13

+#define IMM64_IMM5C_VAL_POS_X           16

+

+#define IMM64_IC_INST_WORD_X            3

+#define IMM64_IC_SIZE_X                 1

+#define IMM64_IC_INST_WORD_POS_X        12

+#define IMM64_IC_VAL_POS_X              21

+

+#define IMM64_IMM41A_INST_WORD_X        1

+#define IMM64_IMM41A_SIZE_X             10

+#define IMM64_IMM41A_INST_WORD_POS_X    14

+#define IMM64_IMM41A_VAL_POS_X          22

+

+#define IMM64_IMM41B_INST_WORD_X        1

+#define IMM64_IMM41B_SIZE_X             8

+#define IMM64_IMM41B_INST_WORD_POS_X    24

+#define IMM64_IMM41B_VAL_POS_X          32

+

+#define IMM64_IMM41C_INST_WORD_X        2

+#define IMM64_IMM41C_SIZE_X             23

+#define IMM64_IMM41C_INST_WORD_POS_X    0

+#define IMM64_IMM41C_VAL_POS_X          40

+

+#define IMM64_SIGN_INST_WORD_X          3

+#define IMM64_SIGN_SIZE_X               1

+#define IMM64_SIGN_INST_WORD_POS_X      27

+#define IMM64_SIGN_VAL_POS_X            63

+

+/**

+  Performs an Itanium-based specific relocation fixup.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @retval RETURN_SUCCESS Succeed to fix the relocation entry.

+  @retval RETURN_UNSUPPOTED Unrecoganized relocation entry.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT64      *Fixup64;

+  UINT64      FixupVal;

+

+  switch ((*Reloc) >> 12) {

+    case EFI_IMAGE_REL_BASED_IA64_IMM64:

+

+      //

+      // Align it to bundle address before fixing up the

+      // 64-bit immediate value of the movl instruction.

+      //

+

+      Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));

+      FixupVal = (UINT64)0;

+

+      //

+      // Extract the lower 32 bits of IMM64 from bundle

+      //

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,

+                IMM64_IMM7B_SIZE_X,

+                IMM64_IMM7B_INST_WORD_POS_X,

+                IMM64_IMM7B_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,

+                IMM64_IMM9D_SIZE_X,

+                IMM64_IMM9D_INST_WORD_POS_X,

+                IMM64_IMM9D_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,

+                IMM64_IMM5C_SIZE_X,

+                IMM64_IMM5C_INST_WORD_POS_X,

+                IMM64_IMM5C_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,

+                IMM64_IC_SIZE_X,

+                IMM64_IC_INST_WORD_POS_X,

+                IMM64_IC_VAL_POS_X

+                );

+

+      EXT_IMM64(FixupVal,

+                (UINT32 *)Fixup + IMM64_IMM41A_INST_WORD_X,

+                IMM64_IMM41A_SIZE_X,

+                IMM64_IMM41A_INST_WORD_POS_X,

+                IMM64_IMM41A_VAL_POS_X

+                );

+

+      //

+      // Update 64-bit address

+      //

+      FixupVal += Adjust;

+

+      //

+      // Insert IMM64 into bundle

+      //

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),

+                IMM64_IMM7B_SIZE_X,

+                IMM64_IMM7B_INST_WORD_POS_X,

+                IMM64_IMM7B_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),

+                IMM64_IMM9D_SIZE_X,

+                IMM64_IMM9D_INST_WORD_POS_X,

+                IMM64_IMM9D_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),

+                IMM64_IMM5C_SIZE_X,

+                IMM64_IMM5C_INST_WORD_POS_X,

+                IMM64_IMM5C_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),

+                IMM64_IC_SIZE_X,

+                IMM64_IC_INST_WORD_POS_X,

+                IMM64_IC_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41A_INST_WORD_X),

+                IMM64_IMM41A_SIZE_X,

+                IMM64_IMM41A_INST_WORD_POS_X,

+                IMM64_IMM41A_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41B_INST_WORD_X),

+                IMM64_IMM41B_SIZE_X,

+                IMM64_IMM41B_INST_WORD_POS_X,

+                IMM64_IMM41B_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_IMM41C_INST_WORD_X),

+                IMM64_IMM41C_SIZE_X,

+                IMM64_IMM41C_INST_WORD_POS_X,

+                IMM64_IMM41C_VAL_POS_X

+                );

+

+      INS_IMM64(FixupVal,

+                ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),

+                IMM64_SIGN_SIZE_X,

+                IMM64_SIGN_INST_WORD_POS_X,

+                IMM64_SIGN_VAL_POS_X

+                );

+

+      Fixup64 = (UINT64 *) Fixup;

+      if (*FixupData != NULL) {

+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));

+        *(UINT64 *)(*FixupData) = *Fixup64;

+        *FixupData = *FixupData + sizeof(UINT64);

+      }

+      break;

+

+    default:

+      return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Returns TRUE if the machine type of PE/COFF image is supported. Supported

+  does not mean the image can be executed it means the PE/COFF loader supports

+  loading and relocating of the image type. It's up to the caller to support

+  the entry point. 

+  

+  The itanium version PE/COFF loader/relocater supports itanium and EBC image.

+

+  @param  Machine   Machine type from the PE Header.

+

+  @return TRUE if this PE/COFF loader can load the image

+  @return FALSE unrecoganized machine type of image.

+

+**/

+BOOLEAN

+PeCoffLoaderImageFormatSupported (

+  IN  UINT16  Machine

+  )

+{

+  if ((Machine == IMAGE_FILE_MACHINE_IA64) || (Machine == IMAGE_FILE_MACHINE_EBC)) {

+    return TRUE;

+  }

+

+  return FALSE;

+}

+

+

+/**

+  ImageRead function that operates on a memory buffer whos base is passed into

+  FileHandle.

+

+  @param  Reloc             Ponter to baes of the input stream

+  @param  Fixup             Offset to the start of the buffer

+  @param  FixupData         The number of bytes to copy into the buffer

+  @param  Adjust            Location to place results of read

+

+  @retval RETURN_SUCCESS    Data is read from FileOffset from the Handle into

+                            the buffer.

+  @retval RETURN_UNSUPPORTED Un-recoganized relocation entry

+                             type.

+**/

+RETURN_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  UINT64  *Fixup64;

+  UINT64  FixupVal;

+

+  switch ((*Reloc) >> 12) {

+  case EFI_IMAGE_REL_BASED_DIR64:

+    Fixup64     = (UINT64 *) Fixup;

+    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));

+    if (*(UINT64 *) (*FixupData) == *Fixup64) {

+      *Fixup64 = *Fixup64 + (UINT64) Adjust;

+    }

+

+    *FixupData = *FixupData + sizeof (UINT64);

+    break;

+

+  case EFI_IMAGE_REL_BASED_IA64_IMM64:

+    Fixup64     = (UINT64 *) Fixup;

+    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));

+    if (*(UINT64 *) (*FixupData) == *Fixup64) {

+      //

+      // Align it to bundle address before fixing up the

+      // 64-bit immediate value of the movl instruction.

+      //

+      //

+      Fixup     = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));

+      FixupVal  = (UINT64) 0;

+

+      //

+      // Extract the lower 32 bits of IMM64 from bundle

+      //

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,

+        IMM64_IMM7B_SIZE_X,

+        IMM64_IMM7B_INST_WORD_POS_X,

+        IMM64_IMM7B_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,

+        IMM64_IMM9D_SIZE_X,

+        IMM64_IMM9D_INST_WORD_POS_X,

+        IMM64_IMM9D_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,

+        IMM64_IMM5C_SIZE_X,

+        IMM64_IMM5C_INST_WORD_POS_X,

+        IMM64_IMM5C_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,

+        IMM64_IC_SIZE_X,

+        IMM64_IC_INST_WORD_POS_X,

+        IMM64_IC_VAL_POS_X

+        );

+

+      EXT_IMM64 (

+        FixupVal,

+        (UINT32 *) Fixup + IMM64_IMM41A_INST_WORD_X,

+        IMM64_IMM41A_SIZE_X,

+        IMM64_IMM41A_INST_WORD_POS_X,

+        IMM64_IMM41A_VAL_POS_X

+        );

+

+      //

+      // Update 64-bit address

+      //

+      FixupVal += Adjust;

+

+      //

+      // Insert IMM64 into bundle

+      //

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),

+        IMM64_IMM7B_SIZE_X,

+        IMM64_IMM7B_INST_WORD_POS_X,

+        IMM64_IMM7B_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),

+        IMM64_IMM9D_SIZE_X,

+        IMM64_IMM9D_INST_WORD_POS_X,

+        IMM64_IMM9D_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),

+        IMM64_IMM5C_SIZE_X,

+        IMM64_IMM5C_INST_WORD_POS_X,

+        IMM64_IMM5C_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),

+        IMM64_IC_SIZE_X,

+        IMM64_IC_INST_WORD_POS_X,

+        IMM64_IC_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM41A_INST_WORD_X),

+        IMM64_IMM41A_SIZE_X,

+        IMM64_IMM41A_INST_WORD_POS_X,

+        IMM64_IMM41A_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM41B_INST_WORD_X),

+        IMM64_IMM41B_SIZE_X,

+        IMM64_IMM41B_INST_WORD_POS_X,

+        IMM64_IMM41B_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_IMM41C_INST_WORD_X),

+        IMM64_IMM41C_SIZE_X,

+        IMM64_IMM41C_INST_WORD_POS_X,

+        IMM64_IMM41C_VAL_POS_X

+        );

+

+      INS_IMM64 (

+        FixupVal,

+        ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),

+        IMM64_SIGN_SIZE_X,

+        IMM64_SIGN_INST_WORD_POS_X,

+        IMM64_SIGN_VAL_POS_X

+        );

+

+      *(UINT64 *) (*FixupData) = *Fixup64;

+    }

+

+    *FixupData = *FixupData + sizeof (UINT64);

+    break;

+

+  default:

+    DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));

+    return RETURN_UNSUPPORTED;

+  }

+

+  return RETURN_SUCCESS;

+}

+

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c
new file mode 100644
index 0000000..2ed5884
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePeCoffLib/PeCoffLoaderEx.c
@@ -0,0 +1,90 @@
+/** @file

+  Specific relocation fixups for none Itanium architecture.

+

+  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.

+

+**/

+

+#include "BasePeCoffLibInternals.h"

+

+

+/**

+  Performs an Itanium-based specific relocation fixup and is a no-op on other

+  instruction sets.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeCoffLoaderRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Returns TRUE if the machine type of PE/COFF image is supported. Supported

+  does not mean the image can be executed it means the PE/COFF loader supports

+  loading and relocating of the image type. It's up to the caller to support

+  the entry point.

+  

+  The IA32/X64 version PE/COFF loader/relocater both support IA32, X64 and EBC images.

+

+  @param  Machine   The machine type from the PE Header.

+

+  @return TRUE if this PE/COFF loader can load the image

+

+**/

+BOOLEAN

+PeCoffLoaderImageFormatSupported (

+  IN  UINT16  Machine

+  )

+{

+  if ((Machine == IMAGE_FILE_MACHINE_I386) || (Machine == IMAGE_FILE_MACHINE_X64) || 

+      (Machine ==  IMAGE_FILE_MACHINE_EBC)) {

+    return TRUE; 

+  }

+

+  return FALSE;

+}

+

+/**

+  Performs an Itanium-based specific re-relocation fixup and is a no-op on other

+  instruction sets. This is used to re-relocated the image into the EFI virtual

+  space for runtime calls.

+

+  @param  Reloc       The pointer to the relocation record.

+  @param  Fixup       The pointer to the address to fix up.

+  @param  FixupData   The pointer to a buffer to log the fixups.

+  @param  Adjust      The offset to adjust the fixup.

+

+  @return Status code.

+

+**/

+RETURN_STATUS

+PeHotRelocateImageEx (

+  IN UINT16      *Reloc,

+  IN OUT CHAR8   *Fixup,

+  IN OUT CHAR8   **FixupData,

+  IN UINT64      Adjust

+  )

+{

+  return RETURN_UNSUPPORTED;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
new file mode 100644
index 0000000..d29b532
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
@@ -0,0 +1,45 @@
+## @file

+#  Instance of Performance Library with empty functions.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePerformanceLibNull

+  MODULE_UNI_FILE                = BasePerformanceLibNull.uni

+  FILE_GUID                      = FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PerformanceLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PerformanceLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  PcdLib

+  DebugLib

+

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.uni
new file mode 100644
index 0000000..092332f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
new file mode 100644
index 0000000..e35235d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
@@ -0,0 +1,306 @@
+/** @file

+  Base Performance Library which provides no service.

+

+  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.

+

+**/

+

+

+#include <Base.h>

+

+

+#include <Library/PerformanceLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+/**

+  Creates a record for the beginning of a performance measurement. 

+  

+  Creates a record that contains the Handle, Token, and Module.

+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.

+  If TimeStamp is zero, then this function reads the current time stamp

+  and adds that time stamp value to the record as the start time.

+

+  @param  Handle                  The pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   The pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  The pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+  @retval RETURN_DEVICE_ERROR     A device error reading the time stamp.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Fills in the end time of a performance measurement. 

+  

+  Looks up the record that matches Handle, Token, and Module.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then TimeStamp is added to the record as the end time.

+  If the record is found and TimeStamp is zero, then this function reads

+  the current time stamp and adds that time stamp value to the record as the end time.

+

+  @param  Handle                  The pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   The pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  The pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+

+  @retval RETURN_SUCCESS          The end of the measurement was recorded.

+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+  @retval RETURN_DEVICE_ERROR     A device error reading the time stamp.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurement (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Attempts to retrieve a performance measurement log entry from the performance measurement log. 

+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,

+  and then eliminate the Identifier.

+

+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is

+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,

+  and the key for the second entry in the log is returned.  If the performance log is empty,

+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance

+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is

+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is

+  retrieved and an implementation specific non-zero key value that specifies the end of the performance

+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry

+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,

+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.

+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().

+  If Handle is NULL, then ASSERT().

+  If Token is NULL, then ASSERT().

+  If Module is NULL, then ASSERT().

+  If StartTimeStamp is NULL, then ASSERT().

+  If EndTimeStamp is NULL, then ASSERT().

+

+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.

+                                  0, then the first performance measurement log entry is retrieved.

+                                  On exit, the key of the next performance lof entry entry.

+  @param  Handle                  The pointer to environment specific context used to identify the component

+                                  being measured.  

+  @param  Token                   The pointer to a Null-terminated ASCII string that identifies the component

+                                  being measured. 

+  @param  Module                  The pointer to a Null-terminated ASCII string that identifies the module

+                                  being measured.

+  @param  StartTimeStamp          The pointer to the 64-bit time stamp that was recorded when the measurement

+                                  was started.

+  @param  EndTimeStamp            The pointer to the 64-bit time stamp that was recorded when the measurement

+                                  was ended.

+

+  @return The key for the next performance log entry (in general case).

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurement (

+  IN  UINTN       LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp

+  )

+{

+  ASSERT (Handle != NULL);

+  ASSERT (Token != NULL);

+  ASSERT (Module != NULL);

+  ASSERT (StartTimeStamp != NULL);

+  ASSERT (EndTimeStamp != NULL);

+

+  return 0;

+}

+

+/**

+  Creates a record for the beginning of a performance measurement.

+

+  Creates a record that contains the Handle, Token, Module and Identifier.

+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.

+  If TimeStamp is zero, then this function reads the current time stamp

+  and adds that time stamp value to the record as the start time.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+  @param  Identifier              32-bit identifier. If the value is 0, the created record

+                                  is same as the one created by StartPerformanceMeasurement.

+

+  @retval RETURN_SUCCESS          The start of the measurement was recorded.

+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

+  @retval RETURN_DEVICE_ERROR     A device error reading the time stamp.

+

+**/

+RETURN_STATUS

+EFIAPI

+StartPerformanceMeasurementEx (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp,

+  IN UINT32       Identifier

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Fills in the end time of a performance measurement.

+

+  Looks up the record that matches Handle, Token, Module and Identifier.

+  If the record can not be found then return RETURN_NOT_FOUND.

+  If the record is found and TimeStamp is not zero,

+  then TimeStamp is added to the record as the end time.

+  If the record is found and TimeStamp is zero, then this function reads

+  the current time stamp and adds that time stamp value to the record as the end time.

+

+  @param  Handle                  Pointer to environment specific context used

+                                  to identify the component being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string

+                                  that identifies the component being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string

+                                  that identifies the module being measured.

+  @param  TimeStamp               64-bit time stamp.

+  @param  Identifier              32-bit identifier. If the value is 0, the found record

+                                  is same as the one found by EndPerformanceMeasurement.

+

+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.

+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

+  @retval RETURN_DEVICE_ERROR     A device error reading the time stamp.

+

+**/

+RETURN_STATUS

+EFIAPI

+EndPerformanceMeasurementEx (

+  IN CONST VOID   *Handle,  OPTIONAL

+  IN CONST CHAR8  *Token,   OPTIONAL

+  IN CONST CHAR8  *Module,  OPTIONAL

+  IN UINT64       TimeStamp,

+  IN UINT32       Identifier

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Attempts to retrieve a performance measurement log entry from the performance measurement log.

+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,

+  and then assign the Identifier with 0.

+

+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is

+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,

+  and the key for the second entry in the log is returned.  If the performance log is empty,

+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance

+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is

+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is

+  retrieved and an implementation specific non-zero key value that specifies the end of the performance

+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry

+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,

+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.

+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().

+  If Handle is NULL, then ASSERT().

+  If Token is NULL, then ASSERT().

+  If Module is NULL, then ASSERT().

+  If StartTimeStamp is NULL, then ASSERT().

+  If EndTimeStamp is NULL, then ASSERT().

+  If Identifier is NULL, then ASSERT().

+

+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.

+                                  0, then the first performance measurement log entry is retrieved.

+                                  On exit, the key of the next performance lof entry entry.

+  @param  Handle                  Pointer to environment specific context used to identify the component

+                                  being measured.

+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component

+                                  being measured.

+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module

+                                  being measured.

+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement

+                                  was started.

+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement

+                                  was ended.

+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.

+

+  @return The key for the next performance log entry (in general case).

+

+**/

+UINTN

+EFIAPI

+GetPerformanceMeasurementEx (

+  IN  UINTN       LogEntryKey, 

+  OUT CONST VOID  **Handle,

+  OUT CONST CHAR8 **Token,

+  OUT CONST CHAR8 **Module,

+  OUT UINT64      *StartTimeStamp,

+  OUT UINT64      *EndTimeStamp,

+  OUT UINT32      *Identifier

+  )

+{

+  ASSERT (Handle != NULL);

+  ASSERT (Token != NULL);

+  ASSERT (Module != NULL);

+  ASSERT (StartTimeStamp != NULL);

+  ASSERT (EndTimeStamp != NULL);

+  ASSERT (Identifier != NULL);

+

+  return 0;

+}

+

+/**

+  Returns TRUE if the performance measurement macros are enabled. 

+  

+  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is set.

+  @retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of

+                                  PcdPerformanceLibraryPropertyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PerformanceMeasurementEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf
new file mode 100644
index 0000000..1b9c8ad
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf
@@ -0,0 +1,50 @@
+## @file

+#  Instance of Post Code Library based on Debug Library.

+#

+#  Post Code Library that uses DebugLib service to send PostCode.

+#  It layers on top of a Debug Library instance.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePostCodeLibDebug

+  MODULE_UNI_FILE                = BasePostCodeLibDebug.uni

+  FILE_GUID                      = 19e3bbba-beb1-43e8-b32d-9acbb22c7639

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PostCodeLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+

+[Sources]

+  PostCode.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+

+[LibraryClasses]

+  PcdLib

+  DebugLib

+

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.uni b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.uni
new file mode 100644
index 0000000..4f5b102
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/PostCode.c b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/PostCode.c
new file mode 100644
index 0000000..e6541ab
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibDebug/PostCode.c
@@ -0,0 +1,127 @@
+/** @file

+  The instance of Post Code Library that layers on top of a Debug Library instance.

+

+  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.             

+

+**/

+

+#include <Base.h>

+

+#include <Library/PostCodeLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Post Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return The 32-bit value to write to the POST card.

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x\n", Value));

+  return Value;

+}

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Post 

+  Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  The pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return The 32-bit value to write to the POST card.

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  )

+{

+  DEBUG((EFI_D_INFO, "POST %08x - %s\n", Value, Description));

+  return Value;

+}

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdPostCodePropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdPostCodeProperyMask is set.

+  @retval  FALSE  The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdPostCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PostCodeEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED

+  bit of PcdPostCodePropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of

+                  PcdPostCodeProperyMask is set.

+  @retval  FALSE  The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of

+                  PcdPostCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PostCodeDescriptionEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf
new file mode 100644
index 0000000..e2f0be5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf
@@ -0,0 +1,47 @@
+## @file

+#  Instance of Post Code Library using I/O port 0x80.

+#

+#  Post Code Library that writes post code values to I/O port 0x80.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePostCodeLibPort80

+  MODULE_UNI_FILE                = BasePostCodeLibPort80.uni

+  FILE_GUID                      = b6e9a733-eb75-41b6-b30c-009bcf3801c8

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PostCodeLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PostCode.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  IoLib

+  PcdLib

+

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.uni b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.uni
new file mode 100644
index 0000000..47d2eea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/PostCode.c b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/PostCode.c
new file mode 100644
index 0000000..925c740
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePostCodeLibPort80/PostCode.c
@@ -0,0 +1,127 @@
+/** @file

+  Post Code Library instance that writes post code values to I/O port 0x80.

+

+  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.             

+

+**/

+

+#include <Base.h>

+

+#include <Library/PostCodeLib.h>

+#include <Library/PcdLib.h>

+#include <Library/IoLib.h>

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Post Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return The 32-bit value to write to the POST card.

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  )

+{

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Post 

+  Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  The pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return The 32-bit value to write to the POST card.

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  )

+{

+  IoWrite8 (0x80, (UINT8)(Value));

+  return Value;

+}

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdPostCodePropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdPostCodeProperyMask is set.

+  @retval  FALSE  The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdPostCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PostCodeEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED

+  bit of PcdPostCodePropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of

+                  PcdPostCodeProperyMask is set.

+  @retval  FALSE  The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of

+                  PcdPostCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PostCodeDescriptionEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/BasePrintLib.inf b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/BasePrintLib.inf
new file mode 100644
index 0000000..5457276
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/BasePrintLib.inf
@@ -0,0 +1,44 @@
+## @file

+#  Print Library implementation.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BasePrintLib

+  MODULE_UNI_FILE                = BasePrintLib.uni

+  FILE_GUID                      = a86fbfca-0183-4eeb-aa8a-762e3b7da1f3

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PrintLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+

+[Sources]

+  PrintLibInternal.h

+  PrintLibInternal.c

+  PrintLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/BasePrintLib.uni b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/BasePrintLib.uni
new file mode 100644
index 0000000..12e1fe9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/BasePrintLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLib.c b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLib.c
new file mode 100644
index 0000000..43b2b3c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLib.c
@@ -0,0 +1,756 @@
+/** @file

+  Base Print Library instance implementation.

+

+  Copyright (c) 2006 - 2012, 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.

+

+**/

+

+#include "PrintLibInternal.h"

+

+//

+// Declare a VA_LIST global variable that is used in calls to BasePrintLibSPrintMarker()

+// when the BASE_LIST parameter is valid and the VA_LIST parameter is ignored.  

+// A NULL VA_LIST can not be passed into  BasePrintLibSPrintMarker() because some 

+// compilers define VA_LIST to be a structure.

+//

+VA_LIST gNullVaList;

+

+#define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on 

+  a Null-terminated Unicode format string and a VA_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 BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().

+  If BufferSize > 1 and FormatString is NULL, then ASSERT().

+  If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT_UNICODE_BUFFER (StartOfBuffer);

+  ASSERT_UNICODE_BUFFER (FormatString);

+  return BasePrintLibSPrintMarker ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker, NULL);

+}

+

+/**

+  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 BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().

+  If BufferSize > 1 and FormatString is NULL, then ASSERT().

+  If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT_UNICODE_BUFFER (StartOfBuffer);

+  ASSERT_UNICODE_BUFFER (FormatString);

+  return BasePrintLibSPrintMarker ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, gNullVaList, Marker);

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 

+  Unicode format string and variable 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 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 BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().

+  If BufferSize > 1 and FormatString is NULL, then ASSERT().

+  If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 

+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the

+  Null-terminator, then ASSERT().

+

+  @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,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   NumberOfPrinted;

+

+  VA_START (Marker, FormatString);

+  NumberOfPrinted = UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+  VA_END (Marker);

+  return NumberOfPrinted;

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_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 BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().

+  If BufferSize > 1 and FormatString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than

+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT_UNICODE_BUFFER (StartOfBuffer);

+  return BasePrintLibSPrintMarker ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE, FormatString, Marker, NULL);

+}

+

+/**

+  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 BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().

+  If BufferSize > 1 and FormatString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than

+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT_UNICODE_BUFFER (StartOfBuffer);

+  return BasePrintLibSPrintMarker ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE, FormatString, gNullVaList, Marker);

+}

+

+/**

+  Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 

+  ASCII format string and  variable 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 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 BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().

+  If BufferSize > 1 and FormatString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than

+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string

+  contains more than PcdMaximumUnicodeStringLength Unicode characters not including the

+  Null-terminator, then ASSERT().

+

+  @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,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   NumberOfPrinted;

+

+  VA_START (Marker, FormatString);

+  NumberOfPrinted = UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);

+  VA_END (Marker);

+  return NumberOfPrinted;

+}

+

+/**

+  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

+  )

+{

+  ASSERT_UNICODE_BUFFER(Buffer);

+  return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and a VA_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 is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than

+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string

+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, 0, FormatString, Marker, NULL);

+}

+

+/**

+  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 is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than

+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string

+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, 0, FormatString, gNullVaList, Marker);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  ASCII format string and  variable 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 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 is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is NULL, then ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than

+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string

+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the

+  Null-terminator, then ASSERT().

+

+  @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,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   NumberOfPrinted;

+

+  VA_START (Marker, FormatString);

+  NumberOfPrinted = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);

+  VA_END (Marker);

+  return NumberOfPrinted;

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  Unicode format string and a VA_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 is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than

+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string

+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT_UNICODE_BUFFER (FormatString);

+  return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker, NULL);

+}

+

+/**

+  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 BufferSize is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than

+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string

+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the

+  Null-terminator, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT_UNICODE_BUFFER (FormatString);

+  return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, gNullVaList, Marker);

+}

+

+/**

+  Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated

+  Unicode format string and  variable 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 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 is 0, then no output buffer is produced and 0 is returned.

+

+  If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is NULL, then ASSERT().

+  If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().

+  If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than

+  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then

+  ASSERT().

+  If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string

+  contains more than PcdMaximumAsciiStringLength ASCII characters not including the

+  Null-terminator, then ASSERT().

+

+  @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,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   NumberOfPrinted;

+

+  VA_START (Marker, FormatString);

+  NumberOfPrinted = AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);

+  VA_END (Marker);

+  return NumberOfPrinted;

+}

+

+

+/**

+  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  The 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

+  )

+{

+  return BasePrintLibConvertValueToString (Buffer, Flags, Value, Width, 1);

+}

+

+/**

+  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().

+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().

+

+  @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

+  )

+{

+  ASSERT(FormatString != NULL);

+  ASSERT_UNICODE_BUFFER (FormatString);

+  return BasePrintLibSPrintMarker (NULL, 0, FORMAT_UNICODE | OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);

+}

+

+/**

+  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().

+

+  @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

+  )

+{

+  ASSERT(FormatString != NULL);

+  return BasePrintLibSPrintMarker (NULL, 0, OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.c b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.c
new file mode 100644
index 0000000..8dc5ec7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.c
@@ -0,0 +1,1011 @@
+/** @file

+  Print Library internal worker functions.

+

+  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.

+

+**/

+

+#include "PrintLibInternal.h"

+

+#define WARNING_STATUS_NUMBER         5

+#define ERROR_STATUS_NUMBER           33

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mStatusString[] = {

+  "Success",                      //  RETURN_SUCCESS                = 0

+  "Warning Unknown Glyph",        //  RETURN_WARN_UNKNOWN_GLYPH     = 1

+  "Warning Delete Failure",       //  RETURN_WARN_DELETE_FAILURE    = 2

+  "Warning Write Failure",        //  RETURN_WARN_WRITE_FAILURE     = 3

+  "Warning Buffer Too Small",     //  RETURN_WARN_BUFFER_TOO_SMALL  = 4

+  "Warning Stale Data",           //  RETURN_WARN_STALE_DATA        = 5

+  "Load Error",                   //  RETURN_LOAD_ERROR             = 1  | MAX_BIT

+  "Invalid Parameter",            //  RETURN_INVALID_PARAMETER      = 2  | MAX_BIT

+  "Unsupported",                  //  RETURN_UNSUPPORTED            = 3  | MAX_BIT

+  "Bad Buffer Size",              //  RETURN_BAD_BUFFER_SIZE        = 4  | MAX_BIT

+  "Buffer Too Small",             //  RETURN_BUFFER_TOO_SMALL,      = 5  | MAX_BIT

+  "Not Ready",                    //  RETURN_NOT_READY              = 6  | MAX_BIT

+  "Device Error",                 //  RETURN_DEVICE_ERROR           = 7  | MAX_BIT

+  "Write Protected",              //  RETURN_WRITE_PROTECTED        = 8  | MAX_BIT

+  "Out of Resources",             //  RETURN_OUT_OF_RESOURCES       = 9  | MAX_BIT

+  "Volume Corrupt",               //  RETURN_VOLUME_CORRUPTED       = 10 | MAX_BIT

+  "Volume Full",                  //  RETURN_VOLUME_FULL            = 11 | MAX_BIT

+  "No Media",                     //  RETURN_NO_MEDIA               = 12 | MAX_BIT

+  "Media changed",                //  RETURN_MEDIA_CHANGED          = 13 | MAX_BIT

+  "Not Found",                    //  RETURN_NOT_FOUND              = 14 | MAX_BIT

+  "Access Denied",                //  RETURN_ACCESS_DENIED          = 15 | MAX_BIT

+  "No Response",                  //  RETURN_NO_RESPONSE            = 16 | MAX_BIT

+  "No mapping",                   //  RETURN_NO_MAPPING             = 17 | MAX_BIT

+  "Time out",                     //  RETURN_TIMEOUT                = 18 | MAX_BIT

+  "Not started",                  //  RETURN_NOT_STARTED            = 19 | MAX_BIT

+  "Already started",              //  RETURN_ALREADY_STARTED        = 20 | MAX_BIT

+  "Aborted",                      //  RETURN_ABORTED                = 21 | MAX_BIT

+  "ICMP Error",                   //  RETURN_ICMP_ERROR             = 22 | MAX_BIT

+  "TFTP Error",                   //  RETURN_TFTP_ERROR             = 23 | MAX_BIT

+  "Protocol Error",               //  RETURN_PROTOCOL_ERROR         = 24 | MAX_BIT

+  "Incompatible Version",         //  RETURN_INCOMPATIBLE_VERSION   = 25 | MAX_BIT

+  "Security Violation",           //  RETURN_SECURITY_VIOLATION     = 26 | MAX_BIT

+  "CRC Error",                    //  RETURN_CRC_ERROR              = 27 | MAX_BIT

+  "End of Media",                 //  RETURN_END_OF_MEDIA           = 28 | MAX_BIT

+  "Reserved (29)",                //  RESERVED                      = 29 | MAX_BIT

+  "Reserved (30)",                //  RESERVED                      = 30 | MAX_BIT

+  "End of File",                  //  RETURN_END_OF_FILE            = 31 | MAX_BIT

+  "Invalid Language",             //  RETURN_INVALID_LANGUAGE       = 32 | MAX_BIT

+  "Compromised Data"              //  RETURN_COMPROMISED_DATA       = 33 | MAX_BIT

+};

+

+

+/**

+  Internal function that places the character into the Buffer.

+

+  Internal function that places ASCII or Unicode character into the Buffer.

+

+  @param  Buffer      The buffer to place the Unicode or ASCII string.

+  @param  EndBuffer   The end of the input Buffer. No characters will be

+                      placed after that. 

+  @param  Length      The count of character to be placed into Buffer.

+                      (Negative value indicates no buffer fill.)

+  @param  Character   The character to be placed into Buffer.

+  @param  Increment   The character increment in Buffer.

+

+  @return Buffer.

+

+**/

+CHAR8 *

+BasePrintLibFillBuffer (

+  OUT CHAR8   *Buffer,

+  IN  CHAR8   *EndBuffer,

+  IN  INTN    Length,

+  IN  UINTN   Character,

+  IN  INTN    Increment

+  )

+{

+  INTN  Index;

+  

+  for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {

+    *Buffer = (CHAR8) Character;

+    if (Increment != 1) {

+      *(Buffer + 1) = (CHAR8)(Character >> 8);

+    }

+    Buffer += Increment;

+  }

+

+  return Buffer;

+}

+

+/**

+  Internal function that convert a number to a string in Buffer.

+

+  Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.

+

+  @param  Buffer    Location to place the ASCII string of Value.

+  @param  Value     The value to convert to a Decimal or Hexadecimal string in Buffer.

+  @param  Radix     Radix of the value

+

+  @return A pointer to the end of buffer filled with ASCII string.

+

+**/

+CHAR8 *

+BasePrintLibValueToString (

+  IN OUT CHAR8  *Buffer, 

+  IN INT64      Value, 

+  IN UINTN      Radix

+  )

+{

+  UINT32  Remainder;

+

+  //

+  // Loop to convert one digit at a time in reverse order

+  //

+  *Buffer = 0;

+  do {

+    Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);

+    *(++Buffer) = mHexStr[Remainder];

+  } while (Value != 0);

+

+  //

+  // Return pointer of the end of filled buffer.

+  //

+  return Buffer;

+}

+

+/**

+  Internal function that converts a decimal value to a Null-terminated string.

+  

+  Converts the decimal number specified by Value to a Null-terminated  

+  string specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  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 Value is < 0, 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 Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer    The pointer to the output buffer for the produced Null-terminated

+                    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 characters to place in Buffer, not including

+                    the Null-terminator.

+  @param  Increment The character increment in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+BasePrintLibConvertValueToString (

+  IN OUT CHAR8   *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width,

+  IN UINTN       Increment

+  )

+{

+  CHAR8  *OriginalBuffer;

+  CHAR8  *EndBuffer;

+  CHAR8  ValueBuffer[MAXIMUM_VALUE_CHARACTERS];

+  CHAR8  *ValueBufferPtr;

+  UINTN  Count;

+  UINTN  Digits;

+  UINTN  Index;

+  UINTN  Radix;

+

+  //

+  // Make sure Buffer is not NULL and Width < MAXIMUM

+  //

+  ASSERT (Buffer != NULL);

+  ASSERT (Width < MAXIMUM_VALUE_CHARACTERS);

+  //

+  // Make sure Flags can only contain supported bits.

+  //

+  ASSERT ((Flags & ~(LEFT_JUSTIFY | COMMA_TYPE | PREFIX_ZERO | RADIX_HEX)) == 0);

+

+  //

+  // If both COMMA_TYPE and RADIX_HEX are set, then ASSERT ()

+  //

+  ASSERT (((Flags & COMMA_TYPE) == 0) || ((Flags & RADIX_HEX) == 0));

+

+  OriginalBuffer = Buffer;

+  

+  //

+  // Width is 0 or COMMA_TYPE is set, PREFIX_ZERO is ignored.

+  //

+  if (Width == 0 || (Flags & COMMA_TYPE) != 0) {

+    Flags &= ~((UINTN) PREFIX_ZERO);

+  }

+  //

+  // If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  //

+  if (Width == 0) {

+    Width = MAXIMUM_VALUE_CHARACTERS - 1;

+  }

+  //

+  // Set the tag for the end of the input Buffer.

+  //

+  EndBuffer = Buffer + Width * Increment;

+  

+  //

+  // Convert decimal negative

+  //

+  if ((Value < 0) && ((Flags & RADIX_HEX) == 0)) {

+    Value = -Value;

+    Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, '-', Increment);

+    Width--;

+  }

+  

+  //

+  // Count the length of the value string.

+  //

+  Radix = ((Flags & RADIX_HEX) == 0)? 10 : 16;

+  ValueBufferPtr = BasePrintLibValueToString (ValueBuffer, Value, Radix);

+  Count = ValueBufferPtr - ValueBuffer;

+  

+  //

+  // Append Zero

+  //

+  if ((Flags & PREFIX_ZERO) != 0) {

+    Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Count, '0', Increment);

+  }

+  

+  //

+  // Print Comma type for every 3 characters

+  //

+  Digits = Count % 3;

+  if (Digits != 0) {

+    Digits = 3 - Digits;

+  }

+  for (Index = 0; Index < Count; Index++) {

+    Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, *ValueBufferPtr--, Increment);

+    if ((Flags & COMMA_TYPE) != 0) {

+      Digits++;

+      if (Digits == 3) {

+        Digits = 0;

+        if ((Index + 1) < Count) {

+          Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', Increment);

+        }

+      }

+    }

+  }

+  

+  //

+  // Print Null-terminator

+  //

+  BasePrintLibFillBuffer (Buffer, EndBuffer + Increment, 1, 0, Increment);

+

+  return ((Buffer - OriginalBuffer) / Increment);

+}

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and a VA_LIST argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine.

+

+  If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.

+

+  @param[out] Buffer          The character buffer to print the results of the 

+                              parsing of Format into.

+  @param[in]  BufferSize      The maximum number of characters to put into 

+                              buffer.

+  @param[in]  Flags           Initial flags value.

+                              Can only have FORMAT_UNICODE, OUTPUT_UNICODE, 

+                              and COUNT_ONLY_NO_PRINT set.

+  @param[in]  Format          A Null-terminated format string.

+  @param[in]  VaListMarker    VA_LIST style variable argument list consumed by

+                              processing Format.

+  @param[in]  BaseListMarker  BASE_LIST style variable argument list consumed

+                              by processing Format.

+

+  @return The number of characters printed not including the Null-terminator.

+          If COUNT_ONLY_NO_PRINT was set returns the same, but without any

+          modification to Buffer.

+

+**/

+UINTN

+BasePrintLibSPrintMarker (

+  OUT CHAR8        *Buffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *Format,

+  IN  VA_LIST      VaListMarker,   OPTIONAL

+  IN  BASE_LIST    BaseListMarker  OPTIONAL

+  )

+{

+  CHAR8             *OriginalBuffer;

+  CHAR8             *EndBuffer;

+  CHAR8             ValueBuffer[MAXIMUM_VALUE_CHARACTERS];

+  UINT32            BytesPerOutputCharacter;

+  UINTN             BytesPerFormatCharacter;

+  UINTN             FormatMask;

+  UINTN             FormatCharacter;

+  UINTN             Width;

+  UINTN             Precision;

+  INT64             Value;

+  CONST CHAR8       *ArgumentString;

+  UINTN             Character;

+  GUID              *TmpGuid;

+  TIME              *TmpTime;

+  UINTN             Count;

+  UINTN             ArgumentMask;

+  INTN              BytesPerArgumentCharacter;

+  UINTN             ArgumentCharacter;

+  BOOLEAN           Done;

+  UINTN             Index;

+  CHAR8             Prefix;

+  BOOLEAN           ZeroPad;

+  BOOLEAN           Comma;

+  UINTN             Digits;

+  UINTN             Radix;

+  RETURN_STATUS     Status;

+  UINT32            GuidData1;

+  UINT16            GuidData2;

+  UINT16            GuidData3;

+  UINTN             LengthToReturn;

+

+  //

+  // If you change this code be sure to match the 2 versions of this function.

+  // Nearly identical logic is found in the BasePrintLib and 

+  // DxePrintLibPrint2Protocol (both PrintLib instances).

+  //

+

+  if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {

+    if (BufferSize == 0) {

+      Buffer = NULL;

+    }

+  } else {

+    //

+    // We can run without a Buffer for counting only.

+    //

+    if (BufferSize == 0) {

+      return 0;

+    }

+    ASSERT (Buffer != NULL);

+  }

+

+  if ((Flags & OUTPUT_UNICODE) != 0) {

+    BytesPerOutputCharacter = 2;

+  } else {

+    BytesPerOutputCharacter = 1;

+  }

+

+  LengthToReturn = 0;

+  EndBuffer = NULL;

+  OriginalBuffer = NULL;

+

+  //

+  // Reserve space for the Null terminator.

+  //

+  if (Buffer != NULL) {

+    BufferSize--;

+    OriginalBuffer = Buffer;

+

+    //

+    // Set the tag for the end of the input Buffer.

+    //

+    EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;

+  }

+

+  if ((Flags & FORMAT_UNICODE) != 0) {

+    //

+    // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength

+    // Unicode characters if PcdMaximumUnicodeStringLength is not zero. 

+    //

+    ASSERT (StrSize ((CHAR16 *) Format) != 0);

+    BytesPerFormatCharacter = 2;

+    FormatMask = 0xffff;

+  } else {

+    //

+    // Make sure format string cannot contain more than PcdMaximumAsciiStringLength

+    // Ascii characters if PcdMaximumAsciiStringLength is not zero. 

+    //

+    ASSERT (AsciiStrSize (Format) != 0);

+    BytesPerFormatCharacter = 1;

+    FormatMask = 0xff;

+  }

+

+  //

+  // Get the first character from the format string

+  //

+  FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+

+  //

+  // Loop until the end of the format string is reached or the output buffer is full

+  //

+  while (FormatCharacter != 0) {

+    if ((Buffer != NULL) && (Buffer >= EndBuffer)) {

+      break;

+    }

+    //

+    // Clear all the flag bits except those that may have been passed in

+    //

+    Flags &= (UINTN) (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT);

+

+    //

+    // Set the default width to zero, and the default precision to 1

+    //

+    Width     = 0;

+    Precision = 1;

+    Prefix    = 0;

+    Comma     = FALSE;

+    ZeroPad   = FALSE;

+    Count     = 0;

+    Digits    = 0;

+

+    switch (FormatCharacter) {

+    case '%':

+      //

+      // Parse Flags and Width

+      //

+      for (Done = FALSE; !Done; ) {

+        Format += BytesPerFormatCharacter;

+        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+        switch (FormatCharacter) {

+        case '.': 

+          Flags |= PRECISION; 

+          break;

+        case '-': 

+          Flags |= LEFT_JUSTIFY; 

+          break;

+        case '+': 

+          Flags |= PREFIX_SIGN;  

+          break;

+        case ' ': 

+          Flags |= PREFIX_BLANK; 

+          break;

+        case ',': 

+          Flags |= COMMA_TYPE; 

+          break;

+        case 'L':

+        case 'l': 

+          Flags |= LONG_TYPE;    

+          break;

+        case '*':

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PAD_TO_WIDTH;

+            if (BaseListMarker == NULL) {

+              Width = VA_ARG (VaListMarker, UINTN);

+            } else {

+              Width = BASE_ARG (BaseListMarker, UINTN);

+            }

+          } else {

+            if (BaseListMarker == NULL) {

+              Precision = VA_ARG (VaListMarker, UINTN);

+            } else {

+              Precision = BASE_ARG (BaseListMarker, UINTN);

+            }

+          }

+          break;

+        case '0':

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PREFIX_ZERO;

+          }

+        case '1':

+        case '2':

+        case '3':

+        case '4':

+        case '5':

+        case '6':

+        case '7':

+        case '8':

+        case '9':

+          for (Count = 0; ((FormatCharacter >= '0') &&  (FormatCharacter <= '9')); ){

+            Count = (Count * 10) + FormatCharacter - '0';

+            Format += BytesPerFormatCharacter;

+            FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+          }

+          Format -= BytesPerFormatCharacter;

+          if ((Flags & PRECISION) == 0) {

+            Flags |= PAD_TO_WIDTH;

+            Width = Count;

+          } else {

+            Precision = Count;

+          }

+          break;

+       

+        case '\0':

+          //

+          // Make no output if Format string terminates unexpectedly when

+          // looking up for flag, width, precision and type. 

+          //

+          Format   -= BytesPerFormatCharacter;

+          Precision = 0;

+          //

+          // break skipped on purpose.

+          //

+        default:

+          Done = TRUE;

+          break;

+        }

+      } 

+

+      //

+      // Handle each argument type

+      //

+      switch (FormatCharacter) {

+      case 'p':

+        //

+        // Flag space, +, 0, L & l are invalid for type p.

+        //

+        Flags &= ~((UINTN) (PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE));

+        if (sizeof (VOID *) > 4) {

+          Flags |= LONG_TYPE;

+        }

+        //

+        // break skipped on purpose

+        //

+      case 'X':

+        Flags |= PREFIX_ZERO;

+        //

+        // break skipped on purpose

+        //

+      case 'x':

+        Flags |= RADIX_HEX;

+        //

+        // break skipped on purpose

+        //

+      case 'd':

+        if ((Flags & LONG_TYPE) == 0) {

+          //

+          // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".

+          // This assumption is made so the format string definition is compatible with the ANSI C

+          // Specification for formatted strings.  It is recommended that the Base Types be used 

+          // everywhere, but in this one case, compliance with ANSI C is more important, and 

+          // provides an implementation that is compatible with that largest possible set of CPU 

+          // architectures.  This is why the type "int" is used in this one case.

+          //

+          if (BaseListMarker == NULL) {

+            Value = VA_ARG (VaListMarker, int);

+          } else {

+            Value = BASE_ARG (BaseListMarker, int);

+          }

+        } else {

+          if (BaseListMarker == NULL) {

+            Value = VA_ARG (VaListMarker, INT64);

+          } else {

+            Value = BASE_ARG (BaseListMarker, INT64);

+          }

+        }

+        if ((Flags & PREFIX_BLANK) != 0) {

+          Prefix = ' ';

+        }

+        if ((Flags & PREFIX_SIGN) != 0) {

+          Prefix = '+';

+        }

+        if ((Flags & COMMA_TYPE) != 0) {

+          Comma = TRUE;

+        }

+        if ((Flags & RADIX_HEX) == 0) {

+          Radix = 10;

+          if (Comma) {

+            Flags &= ~((UINTN) PREFIX_ZERO);

+            Precision = 1;

+          }

+          if (Value < 0) {

+            Flags |= PREFIX_SIGN;

+            Prefix = '-';

+            Value = -Value;

+          }

+        } else {

+          Radix = 16;

+          Comma = FALSE;

+          if ((Flags & LONG_TYPE) == 0 && Value < 0) {

+            //

+            // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".

+            // This assumption is made so the format string definition is compatible with the ANSI C

+            // Specification for formatted strings.  It is recommended that the Base Types be used 

+            // everywhere, but in this one case, compliance with ANSI C is more important, and 

+            // provides an implementation that is compatible with that largest possible set of CPU 

+            // architectures.  This is why the type "unsigned int" is used in this one case.

+            //

+            Value = (unsigned int)Value;

+          }

+        }

+        //

+        // Convert Value to a reversed string

+        //

+        Count = BasePrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;

+        if (Value == 0 && Precision == 0) {

+          Count = 0;

+        }

+        ArgumentString = (CHAR8 *)ValueBuffer + Count;

+        

+        Digits = Count % 3;

+        if (Digits != 0) {

+          Digits = 3 - Digits;

+        }

+        if (Comma && Count != 0) {

+          Count += ((Count - 1) / 3);

+        }

+        if (Prefix != 0) {

+          Count++;

+          Precision++;

+        }

+        Flags |= ARGUMENT_REVERSED;

+        ZeroPad = TRUE;

+        if ((Flags & PREFIX_ZERO) != 0) {

+          if ((Flags & LEFT_JUSTIFY) == 0) {

+            if ((Flags & PAD_TO_WIDTH) != 0) {

+              if ((Flags & PRECISION) == 0) {

+                Precision = Width;

+              }

+            }

+          }

+        }

+        break;

+

+      case 's':

+      case 'S':

+        Flags |= ARGUMENT_UNICODE;

+        //

+        // break skipped on purpose

+        //

+      case 'a':

+        if (BaseListMarker == NULL) {

+          ArgumentString = VA_ARG (VaListMarker, CHAR8 *);

+        } else {

+          ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);

+        }

+        if (ArgumentString == NULL) {

+          Flags &= ~((UINTN) ARGUMENT_UNICODE);

+          ArgumentString = "<null string>";

+        }

+        //

+        // Set the default precision for string to be zero if not specified.

+        //

+        if ((Flags & PRECISION) == 0) {

+          Precision = 0;

+        }

+        break;

+

+      case 'c':

+        if (BaseListMarker == NULL) {

+          Character = VA_ARG (VaListMarker, UINTN) & 0xffff;

+        } else {

+          Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;

+        }

+        ArgumentString = (CHAR8 *)&Character;

+        Flags |= ARGUMENT_UNICODE;

+        break;

+

+      case 'g':

+        if (BaseListMarker == NULL) {

+          TmpGuid = VA_ARG (VaListMarker, GUID *);

+        } else {

+          TmpGuid = BASE_ARG (BaseListMarker, GUID *);

+        }

+        if (TmpGuid == NULL) {

+          ArgumentString = "<null guid>";

+        } else {

+          GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1));

+          GuidData2 = ReadUnaligned16 (&(TmpGuid->Data2));

+          GuidData3 = ReadUnaligned16 (&(TmpGuid->Data3));

+          BasePrintLibSPrint (

+            ValueBuffer,

+            MAXIMUM_VALUE_CHARACTERS, 

+            0,

+            "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",

+            GuidData1,

+            GuidData2,

+            GuidData3,

+            TmpGuid->Data4[0],

+            TmpGuid->Data4[1],

+            TmpGuid->Data4[2],

+            TmpGuid->Data4[3],

+            TmpGuid->Data4[4],

+            TmpGuid->Data4[5],

+            TmpGuid->Data4[6],

+            TmpGuid->Data4[7]

+            );

+          ArgumentString = ValueBuffer;

+        }

+        break;

+

+      case 't':

+        if (BaseListMarker == NULL) {

+          TmpTime = VA_ARG (VaListMarker, TIME *); 

+        } else {

+          TmpTime = BASE_ARG (BaseListMarker, TIME *); 

+        }

+        if (TmpTime == NULL) {

+          ArgumentString = "<null time>";

+        } else {

+          BasePrintLibSPrint (

+            ValueBuffer,

+            MAXIMUM_VALUE_CHARACTERS,

+            0,

+            "%02d/%02d/%04d  %02d:%02d",

+            TmpTime->Month,

+            TmpTime->Day,

+            TmpTime->Year,

+            TmpTime->Hour,

+            TmpTime->Minute

+            );

+          ArgumentString = ValueBuffer;

+        }

+        break;

+

+      case 'r':

+        if (BaseListMarker == NULL) {

+          Status = VA_ARG (VaListMarker, RETURN_STATUS);

+        } else {

+          Status = BASE_ARG (BaseListMarker, RETURN_STATUS);

+        }

+        ArgumentString = ValueBuffer;

+        if (RETURN_ERROR (Status)) {

+          //

+          // Clear error bit

+          //

+          Index = Status & ~MAX_BIT;

+          if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {

+            ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER];

+          }

+        } else {

+          Index = Status;

+          if (Index <= WARNING_STATUS_NUMBER) {

+            ArgumentString = mStatusString [Index];

+          }

+        }

+        if (ArgumentString == ValueBuffer) {

+          BasePrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);

+        }

+        break;

+

+      case '\r':

+        Format += BytesPerFormatCharacter;

+        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+        if (FormatCharacter == '\n') {

+          //

+          // Translate '\r\n' to '\r\n'

+          //

+          ArgumentString = "\r\n";

+        } else {

+          //

+          // Translate '\r' to '\r'

+          //

+          ArgumentString = "\r";

+          Format   -= BytesPerFormatCharacter;

+        }

+        break;

+

+      case '\n':

+        //

+        // Translate '\n' to '\r\n' and '\n\r' to '\r\n'

+        //

+        ArgumentString = "\r\n";

+        Format += BytesPerFormatCharacter;

+        FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+        if (FormatCharacter != '\r') {

+          Format   -= BytesPerFormatCharacter;

+        }

+        break;

+

+      case '%':

+      default:

+        //

+        // if the type is '%' or unknown, then print it to the screen

+        //

+        ArgumentString = (CHAR8 *)&FormatCharacter;

+        Flags |= ARGUMENT_UNICODE;

+        break;

+      }

+      break;

+ 

+    case '\r':

+      Format += BytesPerFormatCharacter;

+      FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+      if (FormatCharacter == '\n') {

+        //

+        // Translate '\r\n' to '\r\n'

+        //

+        ArgumentString = "\r\n";

+      } else {

+        //

+        // Translate '\r' to '\r'

+        //

+        ArgumentString = "\r";

+        Format   -= BytesPerFormatCharacter;

+      }

+      break;

+

+    case '\n':

+      //

+      // Translate '\n' to '\r\n' and '\n\r' to '\r\n'

+      //

+      ArgumentString = "\r\n";

+      Format += BytesPerFormatCharacter;

+      FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+      if (FormatCharacter != '\r') {

+        Format   -= BytesPerFormatCharacter;

+      }

+      break;

+

+    default:

+      ArgumentString = (CHAR8 *)&FormatCharacter;

+      Flags |= ARGUMENT_UNICODE;

+      break;

+    }

+

+    //

+    // Retrieve the ArgumentString attriubutes

+    //

+    if ((Flags & ARGUMENT_UNICODE) != 0) {

+      ArgumentMask = 0xffff;

+      BytesPerArgumentCharacter = 2;

+    } else {

+      ArgumentMask = 0xff;

+      BytesPerArgumentCharacter = 1;

+    }

+    if ((Flags & ARGUMENT_REVERSED) != 0) {

+      BytesPerArgumentCharacter = -BytesPerArgumentCharacter;

+    } else {

+      //

+      // Compute the number of characters in ArgumentString and store it in Count

+      // ArgumentString is either null-terminated, or it contains Precision characters

+      //

+      for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {

+        ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;

+        if (ArgumentCharacter == 0) {

+          break;

+        }

+      }

+    }

+

+    if (Precision < Count) {

+      Precision = Count;

+    }

+

+    //

+    // Pad before the string

+    //

+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {

+      LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);

+      if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+        Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);

+      }

+    }

+

+    if (ZeroPad) {

+      if (Prefix != 0) {

+        LengthToReturn += (1 * BytesPerOutputCharacter);

+        if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+          Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);

+        }

+      }

+      LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);

+      if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+        Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);

+      }

+    } else {

+      LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);

+      if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+        Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);

+      }

+      if (Prefix != 0) {

+        LengthToReturn += (1 * BytesPerOutputCharacter);

+        if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+          Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);

+        }

+      }

+    }

+

+    //

+    // Output the Prefix character if it is present

+    //

+    Index = 0;

+    if (Prefix != 0) {

+      Index++;

+    }

+

+    //

+    // Copy the string into the output buffer performing the required type conversions

+    //

+    while (Index < Count) {

+      ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;

+

+      LengthToReturn += (1 * BytesPerOutputCharacter);

+      if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+        Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);

+      }

+      ArgumentString    += BytesPerArgumentCharacter;

+      Index++;

+      if (Comma) {

+        Digits++;

+        if (Digits == 3) {

+          Digits = 0;

+          Index++;

+          if (Index < Count) {

+            LengthToReturn += (1 * BytesPerOutputCharacter);

+            if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+              Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter);

+            }

+          }

+        }

+      }

+    }

+

+    //

+    // Pad after the string

+    //

+    if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {

+      LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);

+      if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {

+        Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);

+      }

+    }

+

+    //

+    // Get the next character from the format string

+    //

+    Format += BytesPerFormatCharacter;

+

+    //

+    // Get the next character from the format string

+    //

+    FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;

+  }

+

+  if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {

+    return (LengthToReturn / BytesPerOutputCharacter);

+  }

+

+  ASSERT (Buffer != NULL);

+  //

+  // Null terminate the Unicode or ASCII string

+  //

+  BasePrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);

+  //

+  // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength

+  // Unicode characters if PcdMaximumUnicodeStringLength is not zero. 

+  //

+  ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (StrSize ((CHAR16 *) OriginalBuffer) != 0));

+  //

+  // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength

+  // ASCII characters if PcdMaximumAsciiStringLength is not zero. 

+  //

+  ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || (AsciiStrSize (OriginalBuffer) != 0));

+

+  return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);

+}

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and variable argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+  @param  StartOfBuffer The character buffer to print the results of the parsing

+                        of Format into.

+  @param  BufferSize    The maximum number of characters to put into buffer.

+                        Zero means no limit.

+  @param  Flags         Initial flags value.

+                        Can only have FORMAT_UNICODE and OUTPUT_UNICODE set

+  @param  FormatString  A Null-terminated format string.

+  @param  ...           The variable argument list.

+

+  @return The number of characters printed.

+

+**/

+UINTN

+EFIAPI

+BasePrintLibSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  )

+{

+  VA_LIST  Marker;

+  UINTN    NumberOfPrinted;

+

+  VA_START (Marker, FormatString);

+  NumberOfPrinted = BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);

+  VA_END (Marker);

+  return NumberOfPrinted;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.h b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.h
new file mode 100644
index 0000000..32a2126
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BasePrintLib/PrintLibInternal.h
@@ -0,0 +1,214 @@
+/** @file

+  Base Print Library instance Internal Functions 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

+  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 __PRINT_LIB_INTERNAL_H__

+#define __PRINT_LIB_INTERNAL_H__

+

+#include <Base.h>

+#include <Library/PrintLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+

+//

+// Print primitives

+//

+#define PREFIX_SIGN           BIT1

+#define PREFIX_BLANK          BIT2

+#define LONG_TYPE             BIT4

+#define OUTPUT_UNICODE        BIT6

+#define FORMAT_UNICODE        BIT8

+#define PAD_TO_WIDTH          BIT9

+#define ARGUMENT_UNICODE      BIT10

+#define PRECISION             BIT11

+#define ARGUMENT_REVERSED     BIT12

+#define COUNT_ONLY_NO_PRINT   BIT13

+

+//

+// Record date and time information

+//

+typedef struct {

+  UINT16  Year;

+  UINT8   Month;

+  UINT8   Day;

+  UINT8   Hour;

+  UINT8   Minute;

+  UINT8   Second;

+  UINT8   Pad1;

+  UINT32  Nanosecond;

+  INT16   TimeZone;

+  UINT8   Daylight;

+  UINT8   Pad2;

+} TIME;

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and a VA_LIST argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine.

+

+  If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.

+

+  @param[out] Buffer          The character buffer to print the results of the 

+                              parsing of Format into.

+  @param[in]  BufferSize      The maximum number of characters to put into 

+                              buffer.

+  @param[in]  Flags           Initial flags value.

+                              Can only have FORMAT_UNICODE, OUTPUT_UNICODE, 

+                              and COUNT_ONLY_NO_PRINT set.

+  @param[in]  Format          A Null-terminated format string.

+  @param[in]  VaListMarker    VA_LIST style variable argument list consumed by

+                              processing Format.

+  @param[in]  BaseListMarker  BASE_LIST style variable argument list consumed

+                              by processing Format.

+

+  @return The number of characters printed not including the Null-terminator.

+          If COUNT_ONLY_NO_PRINT was set returns the same, but without any

+          modification to Buffer.

+

+**/

+UINTN

+BasePrintLibSPrintMarker (

+  OUT CHAR8        *Buffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *Format,

+  IN  VA_LIST      VaListMarker,   OPTIONAL

+  IN  BASE_LIST    BaseListMarker  OPTIONAL

+  );

+

+/**

+  Worker function that produces a Null-terminated string in an output buffer 

+  based on a Null-terminated format string and variable argument list.

+

+  VSPrint function to process format and place the results in Buffer. Since a 

+  VA_LIST is used this routine allows the nesting of Vararg routines. Thus 

+  this is the main print working routine

+

+  @param  StartOfBuffer The character buffer to print the results of the parsing

+                        of Format into.

+  @param  BufferSize    The maximum number of characters to put into buffer.

+                        Zero means no limit.

+  @param  Flags         Initial flags value.

+                        Can only have FORMAT_UNICODE and OUTPUT_UNICODE set

+  @param  FormatString  Null-terminated format string.

+  @param  ...           The variable argument list.

+

+  @return The number of characters printed.

+

+**/

+UINTN

+EFIAPI

+BasePrintLibSPrint (

+  OUT CHAR8        *StartOfBuffer,

+  IN  UINTN        BufferSize,

+  IN  UINTN        Flags,

+  IN  CONST CHAR8  *FormatString,

+  ...

+  );

+

+/**

+  Internal function that places the character into the Buffer.

+

+  Internal function that places ASCII or Unicode character into the Buffer.

+

+  @param  Buffer      Buffer to place the Unicode or ASCII string.

+  @param  EndBuffer   The end of the input Buffer. No characters will be

+                      placed after that. 

+  @param  Length      The count of character to be placed into Buffer.

+                      (Negative value indicates no buffer fill.)

+  @param  Character   The character to be placed into Buffer.

+  @param  Increment   The character increment in Buffer.

+

+  @return Buffer      Buffer filled with the input Character.

+

+**/

+CHAR8 *

+BasePrintLibFillBuffer (

+  OUT CHAR8   *Buffer,

+  IN  CHAR8   *EndBuffer,

+  IN  INTN    Length,

+  IN  UINTN   Character,

+  IN  INTN    Increment

+  );

+

+/**

+  Internal function that convert a number to a string in Buffer.

+

+  Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.

+

+  @param  Buffer    Location to place the ASCII string of Value.

+  @param  Value     The value to convert to a Decimal or Hexadecimal string in Buffer.

+  @param  Radix     Radix of the value

+

+  @return A pointer to the end of buffer filled with ASCII string.

+

+**/

+CHAR8 *

+BasePrintLibValueToString (

+  IN OUT CHAR8  *Buffer, 

+  IN INT64      Value, 

+  IN UINTN      Radix

+  );

+

+/**

+  Internal function that converts a decimal value to a Null-terminated string.

+  

+  Converts the decimal number specified by Value to a Null-terminated  

+  string specified by Buffer containing at most Width characters.

+  If Width is 0 then a width of  MAXIMUM_VALUE_CHARACTERS is assumed.

+  The total number of characters placed in Buffer is returned.

+  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 Value is < 0, 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 Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()

+

+  @param  Buffer    The pointer to the output buffer for the produced Null-terminated

+                    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 characters to place in Buffer, not including

+                    the Null-terminator.

+  @param  Increment Character increment in Buffer.

+  

+  @return Total number of characters required to perform the conversion.

+

+**/

+UINTN

+BasePrintLibConvertValueToString (

+  IN OUT CHAR8   *Buffer,

+  IN UINTN       Flags,

+  IN INT64       Value,

+  IN UINTN       Width,

+  IN UINTN       Increment

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLib.c
new file mode 100644
index 0000000..829c597
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLib.c
@@ -0,0 +1,392 @@
+/** @file

+  Null Base Report Status Code Library instance with empty functions.

+

+  Copyright (c) 2009 - 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.

+

+**/

+

+#include <Base.h>

+#include <Library/ReportStatusCodeLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Converts a status code to an 8-bit POST code value.

+

+  Converts the status code specified by CodeType and Value to an 8-bit POST code

+  and returns the 8-bit POST code in PostCode.  If CodeType is an

+  EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode

+  are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits

+  24..26 of Value., and TRUE is returned.  Otherwise, FALSE is returned.

+

+  If PostCode is NULL, then ASSERT().

+

+  @param  CodeType  The type of status code being converted.

+  @param  Value     The status code value being converted.

+  @param  PostCode  A pointer to the 8-bit POST code value to return.

+

+  @retval  TRUE   The status code specified by CodeType and Value was converted

+                  to an 8-bit POST code and returned in  PostCode.

+  @retval  FALSE  The status code specified by CodeType and Value could not be

+                  converted to an 8-bit POST code value.

+

+**/

+BOOLEAN

+EFIAPI

+CodeTypeToPostCode (

+  IN  EFI_STATUS_CODE_TYPE   CodeType,

+  IN  EFI_STATUS_CODE_VALUE  Value,

+  OUT UINT8                  *PostCode

+  )

+{

+  ASSERT (PostCode != NULL);

+

+  return FALSE;

+}

+

+

+/**

+  Extracts ASSERT() information from a status code structure.

+

+  Converts the status code specified by CodeType, Value, and Data to the ASSERT()

+  arguments specified by Filename, Description, and LineNumber.  If CodeType is

+  an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and

+  Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract

+  Filename, Description, and LineNumber from the optional data area of the

+  status code buffer specified by Data.  The optional data area of Data contains

+  a Null-terminated ASCII string for the FileName, followed by a Null-terminated

+  ASCII string for the Description, followed by a 32-bit LineNumber.  If the

+  ASSERT() information could be extracted from Data, then return TRUE.

+  Otherwise, FALSE is returned.

+

+  If Data is NULL, then ASSERT().

+  If Filename is NULL, then ASSERT().

+  If Description is NULL, then ASSERT().

+  If LineNumber is NULL, then ASSERT().

+

+  @param  CodeType     The type of status code being converted.

+  @param  Value        The status code value being converted.

+  @param  Data         The pointer to the status code data buffer.

+  @param  Filename     The pointer to the source file name that generated the ASSERT().

+  @param  Description  The pointer to the description of the ASSERT().

+  @param  LineNumber   The pointer to the source line number that generated the ASSERT().

+

+  @retval  TRUE   The status code specified by CodeType, Value, and Data was

+                  converted ASSERT() arguments specified by Filename, Description,

+                  and LineNumber.

+  @retval  FALSE  The status code specified by CodeType, Value, and Data could

+                  not be converted to ASSERT() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractAssertInfo (

+  IN EFI_STATUS_CODE_TYPE        CodeType,

+  IN EFI_STATUS_CODE_VALUE       Value,

+  IN CONST EFI_STATUS_CODE_DATA  *Data,

+  OUT CHAR8                      **Filename,

+  OUT CHAR8                      **Description,

+  OUT UINT32                     *LineNumber

+  )

+{

+  return FALSE;

+}

+

+

+/**

+  Extracts DEBUG() information from a status code structure.

+

+  Converts the status code specified by Data to the DEBUG() arguments specified

+  by ErrorLevel, Marker, and Format.  If type GUID in Data is

+  EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and

+  Format from the optional data area of the status code buffer specified by Data.

+  The optional data area of Data contains a 32-bit ErrorLevel followed by Marker

+  which is 12 UINTN parameters, followed by a Null-terminated ASCII string for

+  the Format.  If the DEBUG() information could be extracted from Data, then

+  return TRUE.  Otherwise, FALSE is returned.

+

+  If Data is NULL, then ASSERT().

+  If ErrorLevel is NULL, then ASSERT().

+  If Marker is NULL, then ASSERT().

+  If Format is NULL, then ASSERT().

+

+  @param  Data        The pointer to the status code data buffer.

+  @param  ErrorLevel  The pointer to the error level mask for a debug message.

+  @param  Marker      The pointer to the variable argument list associated with Format.

+  @param  Format      The pointer to a Null-terminated ASCII format string of a

+                      debug message.

+

+  @retval  TRUE   The status code specified by Data was converted DEBUG() arguments

+                  specified by ErrorLevel, Marker, and Format.

+  @retval  FALSE  The status code specified by Data could not be converted to

+                  DEBUG() arguments.

+

+**/

+BOOLEAN

+EFIAPI

+ReportStatusCodeExtractDebugInfo (

+  IN CONST EFI_STATUS_CODE_DATA  *Data,

+  OUT UINT32                     *ErrorLevel,

+  OUT BASE_LIST                  *Marker,

+  OUT CHAR8                      **Format

+  )

+{

+  ASSERT (Data       != NULL);

+  ASSERT (ErrorLevel != NULL);

+  ASSERT (Marker     != NULL);

+  ASSERT (Format     != NULL);

+

+  return FALSE;

+}

+

+

+/**

+  Reports a status code.

+

+  Reports the status code specified by the parameters Type and Value.  Status

+  code also require an instance, caller ID, and extended data.  This function

+  passed in a zero instance, NULL extended data, and a caller ID of

+  gEfiCallerIdGuid, which is the GUID for the module.

+

+  ReportStatusCode()must actively prevent recursion.  If ReportStatusCode()

+  is called while processing another any other Report Status Code Library function,

+  then ReportStatusCode() must return immediately.

+

+  @param  Type   The status code type.

+  @param  Value  The status code value.

+

+  @retval  EFI_SUCCESS       The status code was reported.

+  @retval  EFI_DEVICE_ERROR  There status code could not be reported due to a

+                             device error.

+  @retval  EFI_UNSUPPORTED   The report status code is not supported.

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCode (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value

+  )

+{

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Reports a status code with a Device Path Protocol as the extended data.

+

+  Allocates and fills in the extended data section of a status code with the

+  Device Path Protocol specified by DevicePath.  This function is responsible

+  for allocating a buffer large enough for the standard header and the device

+  path.  The standard header is filled in with a GUID of

+  gEfiStatusCodeSpecificDataGuid.  The status code is reported with a zero

+  instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithDevicePath()must actively prevent recursion.  If

+  ReportStatusCodeWithDevicePath() is called while processing another any other

+  Report Status Code Library function, then ReportStatusCodeWithDevicePath()

+  must return EFI_DEVICE_ERROR immediately.

+

+  If DevicePath is NULL, then ASSERT().

+

+  @param  Type        Status code type.

+  @param  Value       Status code value.

+  @param  DevicePath  The pointer to the Device Path Protocol to be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended

+                                 data specified by DevicePath.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       The report status code is not supported

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithDevicePath (

+  IN EFI_STATUS_CODE_TYPE            Type,

+  IN EFI_STATUS_CODE_VALUE           Value,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath

+  )

+{

+  ASSERT (DevicePath != NULL);

+  

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Reports a status code with an extended data buffer.

+

+  Allocates and fills in the extended data section of a status code with the

+  extended data specified by ExtendedData and ExtendedDataSize.  ExtendedData

+  is assumed to be one of the data structures specified in Related Definitions.

+  These data structure do not have the standard header, so this function is

+  responsible for allocating a buffer large enough for the standard header and

+  the extended data passed into this function.  The standard header is filled

+  in with a GUID of  gEfiStatusCodeSpecificDataGuid.  The status code is reported

+  with a zero instance and a caller ID of gEfiCallerIdGuid.

+

+  ReportStatusCodeWithExtendedData()must actively prevent recursion.  If

+  ReportStatusCodeWithExtendedData() is called while processing another any other

+  Report Status Code Library function, then ReportStatusCodeWithExtendedData()

+  must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL, then ASSERT().

+  If ExtendedDataSize is 0, then ASSERT().

+

+  @param  Type              Status code type.

+  @param  Value             Status code value.

+  @param  ExtendedData      The pointer to the extended data buffer to be reported.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer to

+                            be reported.

+

+  @retval  EFI_SUCCESS           The status code was reported with the extended

+                                 data specified by ExtendedData and ExtendedDataSize.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate the

+                                 extended data section.

+  @retval  EFI_UNSUPPORTED       The report status code is not supported.

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeWithExtendedData (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN CONST VOID             *ExtendedData,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  ASSERT (ExtendedData     != NULL);

+  ASSERT (ExtendedDataSize != 0);

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Reports a status code with full parameters.

+

+  The function reports a status code.  If ExtendedData is NULL and ExtendedDataSize

+  is 0, then an extended data buffer is not reported.  If ExtendedData is not

+  NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.

+  ExtendedData is assumed not have the standard status code header, so this function

+  is responsible for allocating a buffer large enough for the standard header and

+  the extended data passed into this function.  The standard header is filled in

+  with a GUID specified by ExtendedDataGuid.  If ExtendedDataGuid is NULL, then a

+  GUID of gEfiStatusCodeSpecificDataGuid is used.  The status code is reported with

+  an instance specified by Instance and a caller ID specified by CallerId.  If

+  CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.

+

+  ReportStatusCodeEx()must actively prevent recursion.  If ReportStatusCodeEx()

+  is called while processing another any other Report Status Code Library function,

+  then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.

+

+  If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().

+  If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().

+

+  @param  Type              The status code type.

+  @param  Value             The status code value.

+  @param  Instance          Status code instance number.

+  @param  CallerId          The pointer to a GUID that identifies the caller of this

+                            function.  If this parameter is NULL, then a caller

+                            ID of gEfiCallerIdGuid is used.

+  @param  ExtendedDataGuid  The pointer to the GUID for the extended data buffer.

+                            If this parameter is NULL, then a the status code

+                            standard header is filled in with

+                            gEfiStatusCodeSpecificDataGuid.

+  @param  ExtendedData      The pointer to the extended data buffer.  This is an

+                            optional parameter that may be NULL.

+  @param  ExtendedDataSize  The size, in bytes, of the extended data buffer.

+

+  @retval  EFI_SUCCESS           The status code was reported.

+  @retval  EFI_OUT_OF_RESOURCES  There were not enough resources to allocate

+                                 the extended data section if it was specified.

+  @retval  EFI_UNSUPPORTED       The report status code is not supported.

+

+**/

+EFI_STATUS

+EFIAPI

+ReportStatusCodeEx (

+  IN EFI_STATUS_CODE_TYPE   Type,

+  IN EFI_STATUS_CODE_VALUE  Value,

+  IN UINT32                 Instance,

+  IN CONST EFI_GUID         *CallerId          OPTIONAL,

+  IN CONST EFI_GUID         *ExtendedDataGuid  OPTIONAL,

+  IN CONST VOID             *ExtendedData      OPTIONAL,

+  IN UINTN                  ExtendedDataSize

+  )

+{

+  return EFI_SUCCESS;

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportProgressCodeEnabled (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_ERROR_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportErrorCodeEnabled (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+

+/**

+  Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled

+

+  This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED

+  bit of PcdReportStatusCodeProperyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of

+                  PcdReportStatusCodeProperyMask is set.

+  @retval  FALSE  The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of

+                  PcdReportStatusCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+ReportDebugCodeEnabled (

+  VOID

+  )

+{

+  return FALSE;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
new file mode 100644
index 0000000..8ca96aa
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
@@ -0,0 +1,39 @@
+## @file

+#  Report Status Code Library with empty functions.

+#

+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseReportStatusCodeLibNull

+  MODULE_UNI_FILE                = BaseReportStatusCodeLibNull.uni

+  FILE_GUID                      = 1DE0B8C2-FFB6-4bdf-97F5-0FFB33979038

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ReportStatusCodeLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BaseReportStatusCodeLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.uni
new file mode 100644
index 0000000..886e75c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
new file mode 100644
index 0000000..41e966c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
@@ -0,0 +1,43 @@
+## @file

+# BootScriptLib instance that always produces NOP operation.

+#

+# This library is primarily used by platform that does not support ACPI S3

+# resume.  All the library interfaces simply return EFI_SUCCESS without

+# performing any operation.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+# This program and the accompanying materials are

+# licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseS3BootScriptLibNull

+  MODULE_UNI_FILE                = BaseS3BootScriptLibNull.uni

+  FILE_GUID                      = 9A6DC1AC-94C0-43b1-8714-4C70FD58A815

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = S3BootScriptLib

+

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BootScriptLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.uni
new file mode 100644
index 0000000..6765d4f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BootScriptLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BootScriptLib.c
new file mode 100644
index 0000000..373ce6b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3BootScriptLibNull/BootScriptLib.c
@@ -0,0 +1,568 @@
+/** @file

+  Null function implementation for EFI S3 boot script. 

+

+  Copyright (c) 2007 - 2014, 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 <Base.h>

+#include <Library/S3BootScriptLib.h>

+

+/**

+  Save I/O write to boot script 

+

+  @param Width  the width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Address The base address of the I/O operations.

+  @param Count   The number of I/O operations to perform.

+  @param Buffer  The source buffer from which to write data.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveIoWrite (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH             Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  VOID                              *Buffer

+  )

+{

+	return RETURN_SUCCESS;

+}

+

+/**

+  Adds a record for an I/O modify operation into a S3 boot script table

+

+  @param Width   The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Address The base address of the I/O operations.

+  @param Data    A pointer to the data to be OR-ed.

+  @param DataMask  A pointer to the data mask to be AND-ed with the data read from the register

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveIoReadWrite (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH             Width,

+  IN  UINT64                           Address,

+  IN  VOID                            *Data,

+  IN  VOID                            *DataMask

+  )

+{

+	return RETURN_SUCCESS;

+}

+

+/**

+  Adds a record for a memory write operation into a specified boot script table.

+

+  @param Width   The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Address The base address of the memory operations

+  @param Count   The number of memory operations to perform.

+  @param Buffer  The source buffer from which to write the data.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveMemWrite (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH              Width,

+  IN  UINT64                            Address,

+  IN  UINTN                             Count,

+  IN  VOID                              *Buffer

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for a memory modify operation into a specified boot script table.

+

+  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Address   The base address of the memory operations. Address needs alignment if required

+  @param Data      A pointer to the data to be OR-ed.

+  @param DataMask  A pointer to the data mask to be AND-ed with the data read from the register.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveMemReadWrite (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH             Width,

+  IN  UINT64                            Address,

+  IN  VOID                              *Data,

+  IN  VOID                              *DataMask

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for a PCI configuration space write operation into a specified boot script table.

+

+  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Address   The address within the PCI configuration space.

+  @param Count     The number of PCI operations to perform.

+  @param Buffer    The source buffer from which to write the data.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSavePciCfgWrite (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH             Width,

+  IN  UINT64                           Address,

+  IN  UINTN                            Count,

+  IN  VOID                            *Buffer

+  )

+{

+	return RETURN_SUCCESS;

+}

+

+/**

+  Adds a record for a PCI configuration space modify operation into a specified boot script table.

+

+  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Address   The address within the PCI configuration space.

+  @param Data      A pointer to the data to be OR-ed.The size depends on Width.

+  @param DataMask    A pointer to the data mask to be AND-ed.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN__SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSavePciCfgReadWrite (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH          Width,

+  IN  UINT64                            Address,

+  IN  VOID                              *Data,

+  IN  VOID                              *DataMask

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for a PCI configuration space modify operation into a specified boot script table.

+

+  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Segment   The PCI segment number for Address.

+  @param Address   The address within the PCI configuration space.

+  @param Count     The number of PCI operations to perform.

+  @param Buffer    The source buffer from which to write the data.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSavePciCfg2Write (

+  IN S3_BOOT_SCRIPT_LIB_WIDTH        Width,

+  IN UINT16                          Segment,

+  IN UINT64                          Address,

+  IN UINTN                           Count,

+  IN VOID                           *Buffer

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for a PCI configuration space modify operation into a specified boot script table.

+

+  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.

+  @param Segment   The PCI segment number for Address.

+  @param Address   The address within the PCI configuration space.

+  @param Data      A pointer to the data to be OR-ed. The size depends on Width.

+  @param DataMask    A pointer to the data mask to be AND-ed.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSavePciCfg2ReadWrite (

+  IN S3_BOOT_SCRIPT_LIB_WIDTH            Width,

+  IN UINT16                          Segment,

+  IN UINT64                          Address,

+  IN VOID                           *Data,

+  IN VOID                           *DataMask

+  )

+{ 

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for an SMBus command execution into a specified boot script table.

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length, and PEC.

+  @param Operation      Indicates which particular SMBus protocol it will use to execute the SMBus

+                        transactions.

+  @param Length         A pointer to signify the number of bytes that this operation will do.

+  @param Buffer         Contains the value of data to execute to the SMBUS slave device.

+  

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveSmbusExecute (

+  IN  UINTN                             SmBusAddress, 

+  IN  EFI_SMBUS_OPERATION               Operation,

+  IN  UINTN                             *Length,

+  IN  VOID                              *Buffer

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for an execution stall on the processor into a specified boot script table.

+

+  @param Duration   Duration in microseconds of the stall

+  

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveStall (

+  IN  UINTN                             Duration

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for dispatching specified arbitrary code into a specified boot script table.

+

+  @param EntryPoint   Entry point of the code to be dispatched.

+  

+  @retval RETURN_OUT_OF_RESOURCES   Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS            Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveDispatch (

+  IN  VOID *EntryPoint

+  )

+{

+  return RETURN_SUCCESS;

+}

+/**

+  Adds a record for dispatching specified arbitrary code into a specified boot script table.

+

+  @param EntryPoint   Entry point of the code to be dispatched.

+  @param Context      Argument to be passed into the EntryPoint of the code to be dispatched.

+  

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveDispatch2 (

+  IN  VOID                              *EntryPoint,

+  IN  VOID                              *Context

+  )

+{

+	return RETURN_SUCCESS;

+}

+

+/**

+  Adds a record for memory reads of the memory location and continues when the exit criteria is

+  satisfied or after a defined duration.

+ 

+  Please aware, below interface is different with PI specification, Vol 5:

+  EFI_S3_SAVE_STATE_PROTOCOL.Write() for EFI_BOOT_SCRIPT_MEM_POLL_OPCODE.

+  "Duration" below is microseconds, while "Delay" in PI specification means

+  the number of 100ns units to poll.

+

+  @param Width     The width of the memory operations.

+  @param Address   The base address of the memory operations.

+  @param BitMask   A pointer to the bit mask to be AND-ed with the data read from the register.

+  @param BitValue  A pointer to the data value after to be Masked.

+  @param Duration  Duration in microseconds of the stall.

+  @param LoopTimes The times of the register polling.

+

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveMemPoll (

+  IN  S3_BOOT_SCRIPT_LIB_WIDTH             Width,

+  IN  UINT64                            Address,

+  IN  VOID                              *BitMask,

+  IN  VOID                              *BitValue,

+  IN  UINTN                             Duration,

+  IN  UINTN                             LoopTimes

+  )

+{

+	return RETURN_SUCCESS;

+}

+

+/**

+  Store arbitrary information in the boot script table. This opcode is a no-op on dispatch and is only

+  used for debugging script issues.

+  

+  @param InformationLength   Length of the data in bytes

+  @param Information       Information to be logged in the boot scrpit

+ 

+  @retval RETURN_UNSUPPORTED   If  entering runtime, this method will not support.

+  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+  @retval RETURN_SUCCESS           Opcode is added.

+

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveInformation (

+  IN  UINT32                   InformationLength, 

+  IN  VOID                    *Information

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for I/O reads the I/O location and continues when the exit criteria is satisfied or after a

+  defined duration.

+  

+  @param  Width                 The width of the I/O operations. 

+  @param  Address               The base address of the I/O operations.

+  @param  Data                  The comparison value used for the polling exit criteria.

+  @param  DataMask              Mask used for the polling criteria. The bits in the bytes below Width which are zero

+                                in Data are ignored when polling the memory address.

+  @param  Delay                 The number of 100ns units to poll. Note that timer available may be of poorer

+                                granularity so the delay may be longer.

+

+ @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+ @retval RETURN_SUCCESS          Opcode is added.

+

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveIoPoll (

+  IN S3_BOOT_SCRIPT_LIB_WIDTH       Width,

+  IN UINT64                     Address,

+  IN VOID                      *Data,

+  IN VOID                      *DataMask, 

+  IN UINT64                     Delay   

+  )

+{

+	return RETURN_SUCCESS;

+}

+

+/**

+  Adds a record for PCI configuration space reads and continues when the exit criteria is satisfied or

+  after a defined duration.

+

+  @param  Width                 The width of the I/O operations. 

+  @param  Address               The address within the PCI configuration space.

+  @param  Data                  The comparison value used for the polling exit criteria.

+  @param  DataMask              Mask used for the polling criteria. The bits in the bytes below Width which are zero

+                                in Data are ignored when polling the memory address

+  @param  Delay                 The number of 100ns units to poll. Note that timer available may be of poorer

+                                granularity so the delay may be longer.

+

+ @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+ @retval RETURN_SUCCESS           Opcode is added.

+

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSavePciPoll (

+   IN S3_BOOT_SCRIPT_LIB_WIDTH   Width,

+   IN UINT64                     Address,

+   IN VOID                      *Data,

+   IN VOID                      *DataMask,

+   IN UINT64                     Delay

+ )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Adds a record for PCI configuration space reads and continues when the exit criteria is satisfied or

+  after a defined duration.

+

+  @param  Width                 The width of the I/O operations. 

+  @param  Segment               The PCI segment number for Address.

+  @param  Address               The address within the PCI configuration space.

+  @param  Data                  The comparison value used for the polling exit criteria.

+  @param  DataMask              Mask used for the polling criteria. The bits in the bytes below Width which are zero

+                                in Data are ignored when polling the memory address

+  @param  Delay                 The number of 100ns units to poll. Note that timer available may be of poorer

+                                granularity so the delay may be longer.

+

+ @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.

+ @retval RETURN_SUCCESS           Opcode is added.

+ @note   A known Limitations in the implementation: When interpreting the opcode  EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE

+         EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as 

+         Zero, or else, assert.

+

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSavePci2Poll (

+   IN S3_BOOT_SCRIPT_LIB_WIDTH      Width,

+   IN UINT16                        Segment,

+   IN UINT64                        Address,

+   IN VOID                         *Data,

+   IN VOID                         *DataMask,

+   IN UINT64                        Delay

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Save ASCII string information specified by Buffer to

+  boot script with opcode EFI_BOOT_SCRIPT_INFORMATION_OPCODE

+

+  @param  String         the ascii string to store into the S3 boot script table

+

+  @retval RETURN_NOT_FOUND  BootScriptSave Protocol not exist.

+  @retval RETURN_SUCCESS     BootScriptSave Protocol exist, always returns RETURN_SUCCESS

+

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptSaveInformationAsciiString (

+  IN  CONST CHAR8               *String

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  This is an function to close the S3 boot script table. The function could only be called in 

+  BOOT time phase. To comply with the Framework spec definition on 

+  EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable(), this function will fulfill following things:

+  1. Closes the specified boot script table

+  2. It allocates a new memory pool to duplicate all the boot scripts in the specified table. 

+     Once this function is called, the table maintained by the library will be destroyed 

+     after it is copied into the allocated pool.

+  3. Any attempts to add a script record after calling this function will cause a new table 

+     to be created by the library.

+  4. The base address of the allocated pool will be returned in Address. Note that after 

+     using the boot script table, the CALLER is responsible for freeing the pool that is allocated

+     by this function. 

+

+  In Spec PI1.1, this EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is retired. By then it is not

+  necessary to provide this API in BootScriptLib. To provides this API for now is only to meet

+  the requirement from Framework Spec.

+  

+  If anyone does call CloseTable() on a real platform, then the caller is responsible for figuring out 

+  how to get the script to run on an S3 resume because the boot script maintained by the lib will be 

+  destroyed.

+ 

+  @return the base address of the new copy of the boot script table.   

+

+**/

+UINT8*

+EFIAPI

+S3BootScriptCloseTable (

+  VOID

+  )

+{

+	return 0;

+}

+/**

+  Executes the S3 boot script table.

+

+  @param RETURN_SUCCESS           The boot script table was executed successfully.

+  @param RETURN_UNSUPPORTED       Invalid script table or opcode.  

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptExecute (

+   VOID

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Move the last boot script entry to the position 

+

+  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position

+                                in the boot script table specified by Position. If Position is NULL or points to

+                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end

+                                of the table (if FALSE).

+  @param  Position              On entry, specifies the position in the boot script table where the opcode will be

+                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies

+                                the position of the inserted opcode in the boot script table.

+

+  @retval RETURN_OUT_OF_RESOURCES  The table is not available.

+  @retval RETURN_INVALID_PARAMETER The Position is not a valid position in the boot script table.

+  @retval RETURN_SUCCESS           Opcode is inserted.

+**/

+RETURN_STATUS

+EFIAPI

+S3BootScriptMoveLastOpcode (

+  IN     BOOLEAN                        BeforeOrAfter,

+  IN OUT VOID                         **Position OPTIONAL

+)

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Find a label within the boot script table and, if not present, optionally create it.

+

+  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE)

+                                or after (FALSE) the position in the boot script table 

+                                specified by Position.

+  @param  CreateIfNotFound      Specifies whether the label will be created if the label 

+                                does not exists (TRUE) or not (FALSE).

+  @param  Position              On entry, specifies the position in the boot script table

+                                where the opcode will be inserted, either before or after,

+                                depending on BeforeOrAfter. On exit, specifies the position

+                                of the inserted opcode in the boot script table.

+  @param  Label                 Points to the label which will be inserted in the boot script table.

+

+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the

+                                specified script table.

+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.

+                                If the opcode is unknow or not supported because of the PCD 

+                                Feature Flags.

+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.

+

+**/

+RETURN_STATUS

+EFIAPI 

+S3BootScriptLabel (

+  IN       BOOLEAN                      BeforeOrAfter,

+  IN       BOOLEAN                      CreateIfNotFound,

+  IN OUT   VOID                       **Position OPTIONAL,

+  IN CONST CHAR8                       *Label

+  )

+{

+	return RETURN_SUCCESS;

+}

+/**

+  Compare two positions in the boot script table and return their relative position.

+  @param  Position1             The positions in the boot script table to compare

+  @param  Position2             The positions in the boot script table to compare

+  @param  RelativePosition      On return, points to the result of the comparison

+

+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the

+                                specified script table.

+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.

+                                If the opcode is unknow or not supported because of the PCD 

+                                Feature Flags.

+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.

+

+**/

+RETURN_STATUS

+EFIAPI 

+S3BootScriptCompare (

+  IN  UINT8                       *Position1,

+  IN  UINT8                       *Position2,

+  OUT UINTN                       *RelativePosition

+  )

+{

+	return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
new file mode 100644
index 0000000..b6c1094
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
@@ -0,0 +1,46 @@
+## @file

+# Instance of S3 I/O Library based on I/O and S3 BootScript Library.

+#

+# S3 I/O and MMIO Library Services that do I/O and also 

+# enable the I/O operatation to be replayed during an S3 resume.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+# This program and the accompanying materials are

+# licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseS3IoLib

+  MODULE_UNI_FILE                = BaseS3IoLib.uni

+  FILE_GUID                      = B13F938E-47DF-4516-A397-8927A4E42B61

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = S3IoLib 

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  S3IoLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  IoLib

+  S3BootScriptLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/BaseS3IoLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/BaseS3IoLib.uni
new file mode 100644
index 0000000..e70d179
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/BaseS3IoLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/S3IoLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/S3IoLib.c
new file mode 100644
index 0000000..017bcbb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3IoLib/S3IoLib.c
@@ -0,0 +1,3312 @@
+/** @file

+  I/O and MMIO Library Services that do I/O and also enable the I/O operatation

+  to be replayed during an S3 resume.

+  

+  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.

+

+**/

+

+#include <Base.h>

+

+#include <Library/S3IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/IoLib.h>

+#include <Library/S3BootScriptLib.h>

+

+

+/**

+  Saves an I/O port value to the boot script.

+

+  This internal worker function saves an I/O port value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Width         The width of I/O port.

+  @param  Port          The I/O port to write.

+  @param  Buffer        The buffer containing value.

+

+**/

+VOID

+InternalSaveIoWriteValueToBootScript (

+  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,

+  IN UINTN                  Port,

+  IN VOID                   *Buffer

+  )

+{

+  RETURN_STATUS                Status;

+  

+  Status = S3BootScriptSaveIoWrite (

+             Width,

+             Port,

+             1,

+             Buffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+}

+  

+/**

+  Saves an 8-bit I/O port value to the boot script.

+

+  This internal worker function saves an 8-bit I/O port value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT8

+InternalSaveIoWrite8ValueToBootScript (

+  IN UINTN              Port,

+  IN UINT8              Value

+  )

+{

+  InternalSaveIoWriteValueToBootScript (S3BootScriptWidthUint8, Port, &Value);

+

+  return Value;

+}

+

+/**

+  Reads an 8-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+S3IoRead8 (

+  IN UINTN              Port

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoRead8 (Port));

+}

+

+/**

+  Writes an 8-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoWrite8 (

+  IN UINTN              Port,

+  IN UINT8              Value

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoWrite8 (Port, Value));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 8-bit I/O port and saves the value in the S3 script to be

+  replayed on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  OrData        The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoOr8 (

+  IN UINTN              Port,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoOr8 (Port, OrData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port  and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoAnd8 (

+  IN UINTN              Port,

+  IN UINT8              AndData

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoAnd8 (Port, AndData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port and saves 

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoAndThenOr8 (

+  IN UINTN              Port,

+  IN UINT8              AndData,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoAndThenOr8 (Port, AndData, OrData));

+}

+

+/**

+  Reads a bit field of an I/O register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port 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  Port          The I/O port to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+S3IoBitFieldRead8 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoBitFieldRead8 (Port, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to an I/O register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port 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  Port          The I/O port to write.

+  @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 value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoBitFieldWrite8 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              Value

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoBitFieldWrite8 (Port, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port 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  Port          The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoBitFieldOr8 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoBitFieldOr8 (Port, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port  and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port 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  Port          The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoBitFieldAnd8 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              AndData

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoBitFieldAnd8 (Port, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit I/O port specified by Port, 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 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port 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  Port          The I/O port to write.

+  @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 I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+S3IoBitFieldAndThenOr8 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              AndData,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveIoWrite8ValueToBootScript (Port, IoBitFieldAndThenOr8 (Port, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 16-bit I/O port value to the boot script.

+

+  This internal worker function saves a 16-bit I/O port value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT16

+InternalSaveIoWrite16ValueToBootScript (

+  IN UINTN              Port,

+  IN UINT16             Value

+  )

+{

+  InternalSaveIoWriteValueToBootScript (S3BootScriptWidthUint16, Port, &Value);

+  

+  return Value;

+}

+

+/**

+  Reads a 16-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+S3IoRead16 (

+  IN UINTN              Port

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoRead16 (Port));

+}

+

+/**

+  Writes a 16-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoWrite16 (

+  IN UINTN              Port,

+  IN UINT16             Value

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoWrite16 (Port, Value));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 16-bit I/O port and saves the value in the S3 script to 

+  be replayed on S3 resume.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  OrData        The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoOr16 (

+  IN UINTN              Port,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoOr16 (Port, OrData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port  and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoAnd16 (

+  IN UINTN              Port,

+  IN UINT16             AndData

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoAnd16 (Port, AndData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoAndThenOr16 (

+  IN UINTN              Port,

+  IN UINT16             AndData,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoAndThenOr16 (Port, AndData, OrData));

+}

+

+/**

+  Reads a bit field of an I/O register saves the value in the S3 script to be

+  replayed on S3 resume.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port 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  Port          The I/O port to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+S3IoBitFieldRead16 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoBitFieldRead16 (Port, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to an I/O register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port 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  Port          The I/O port to write.

+  @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 value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoBitFieldWrite16 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             Value

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoBitFieldWrite16 (Port, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port 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  Port          The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoBitFieldOr16 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoBitFieldOr16 (Port, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port 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  Port          The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoBitFieldAnd16 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             AndData

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoBitFieldAnd16 (Port, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port  and saves the value in the S3 script to be replayed on S3 

+  resume.

+

+  Reads the 16-bit I/O port specified by Port, 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 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port 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  Port          The I/O port to write.

+  @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 I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+S3IoBitFieldAndThenOr16 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             AndData,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveIoWrite16ValueToBootScript (Port, IoBitFieldAndThenOr16 (Port, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 32-bit I/O port value to the boot script.

+

+  This internal worker function saves a 32-bit I/O port value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT32

+InternalSaveIoWrite32ValueToBootScript (

+  IN UINTN              Port,

+  IN UINT32             Value

+  )

+{

+  InternalSaveIoWriteValueToBootScript (S3BootScriptWidthUint32, Port, &Value);

+  

+  return Value;

+}

+

+/**

+  Reads a 32-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+S3IoRead32 (

+  IN UINTN              Port

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoRead32 (Port));

+}

+

+/**

+  Writes a 32-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoWrite32 (

+  IN UINTN              Port,

+  IN UINT32             Value

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoWrite32 (Port, Value));

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 32-bit I/O port and saves the value in the S3 script to 

+  be replayed on S3 resume.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  OrData        The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoOr32 (

+  IN UINTN              Port,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoOr32 (Port, OrData));

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoAnd32 (

+  IN UINTN              Port,

+  IN UINT32             AndData

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoAnd32 (Port, AndData));

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port and saves 

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoAndThenOr32 (

+  IN UINTN              Port,

+  IN UINT32             AndData,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoAndThenOr32 (Port, AndData, OrData));

+}

+

+/**

+  Reads a bit field of an I/O register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port 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  Port          The I/O port 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 value read.

+

+**/

+UINT32

+EFIAPI

+S3IoBitFieldRead32 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoBitFieldRead32 (Port, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to an I/O register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port 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  Port          The I/O port 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 value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoBitFieldWrite32 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             Value

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoBitFieldWrite32 (Port, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port 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  Port          The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoBitFieldOr32 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoBitFieldOr32 (Port, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port 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  Port          The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoBitFieldAnd32 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             AndData

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoBitFieldAnd32 (Port, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port and saves the value in the S3 script to be replayed on S3 

+  resume.

+

+  Reads the 32-bit I/O port specified by Port, 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 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port 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  Port          The I/O port 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 I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+S3IoBitFieldAndThenOr32 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             AndData,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveIoWrite32ValueToBootScript (Port, IoBitFieldAndThenOr32 (Port, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 64-bit I/O port value to the boot script.

+

+  This internal worker function saves a 64-bit I/O port value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT64

+InternalSaveIoWrite64ValueToBootScript (

+  IN UINTN              Port,

+  IN UINT64             Value

+  )

+{

+  InternalSaveIoWriteValueToBootScript (S3BootScriptWidthUint64, Port, &Value);

+  

+  return Value;

+}

+

+/**

+  Reads a 64-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+S3IoRead64 (

+  IN UINTN              Port

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoRead64 (Port));

+}

+

+/**

+  Writes a 64-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  Value         The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoWrite64 (

+  IN UINTN              Port,

+  IN UINT64             Value

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoWrite64 (Port, Value));

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 64-bit I/O port and saves the value in the S3 script to 

+  be replayed on S3 resume.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  OrData        The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoOr64 (

+  IN UINTN              Port,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoOr64 (Port, OrData));

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoAnd64 (

+  IN UINTN              Port,

+  IN UINT64             AndData

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoAnd64 (Port, AndData));

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port          The I/O port to write.

+  @param  AndData       The value to AND with the read value from the I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoAndThenOr64 (

+  IN UINTN              Port,

+  IN UINT64             AndData,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoAndThenOr64 (Port, AndData, OrData));

+}

+

+/**

+  Reads a bit field of an I/O register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port 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  Port          The I/O port 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.

+

+**/

+UINT64

+EFIAPI

+S3IoBitFieldRead64 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoBitFieldRead64 (Port, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to an I/O register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port 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  Port          The I/O port 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 I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoBitFieldWrite64 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             Value

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoBitFieldWrite64 (Port, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port 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  Port          The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoBitFieldOr64 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoBitFieldOr64 (Port, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port and saves the value in the 

+  S3 script to be replayed on S3 resume.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port 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  Port          The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoBitFieldAnd64 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             AndData

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoBitFieldAnd64 (Port, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  64-bit port and saves the value in the S3 script to be replayed on S3 

+  resume.

+

+  Reads the 64-bit I/O port specified by Port, 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 I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port 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  Port          The I/O port 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 I/O port.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+S3IoBitFieldAndThenOr64 (

+  IN UINTN              Port,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             AndData,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveIoWrite64ValueToBootScript (Port, IoBitFieldAndThenOr64 (Port, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves an MMIO register value to the boot script.

+

+  This internal worker function saves an MMIO register value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Width         The width of MMIO register.

+  @param  Address       The MMIO register to write.

+  @param  Buffer        The buffer containing value.

+

+**/

+VOID

+InternalSaveMmioWriteValueToBootScript (

+  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,

+  IN UINTN                  Address,

+  IN VOID                   *Buffer

+  )

+{

+  RETURN_STATUS            Status;

+

+  Status = S3BootScriptSaveMemWrite (

+             Width,

+             Address,

+             1,

+             Buffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+}

+

+/**

+  Saves an 8-bit MMIO register value to the boot script.

+

+  This internal worker function saves an 8-bit MMIO register value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT8

+InternalSaveMmioWrite8ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT8              Value

+  )

+{

+  InternalSaveMmioWriteValueToBootScript (S3BootScriptWidthUint8, Address, &Value);

+

+  return Value;

+}

+

+/**

+  Reads an 8-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+S3MmioRead8 (

+  IN UINTN              Address

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioRead8 (Address));

+}

+

+/**

+  Writes an 8-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value to write to the MMIO register.

+

+  @return The value written the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioWrite8 (

+  IN UINTN              Address,

+  IN UINT8              Value

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioWrite8 (Address, Value));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 8-bit MMIO register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  OrData        The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioOr8 (

+  IN UINTN              Address,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioOr8 (Address, OrData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioAnd8 (

+  IN UINTN              Address,

+  IN UINT8              AndData

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioAnd8 (Address, AndData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register and saves 

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioAndThenOr8 (

+  IN UINTN              Address,

+  IN UINT8              AndData,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioAndThenOr8 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register 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  Address       MMIO register to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+S3MmioBitFieldRead8 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioBitFieldRead8 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to an MMIO register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register 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  Address       The MMIO register to write.

+  @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 value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioBitFieldWrite8 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              Value

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioBitFieldWrite8 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register 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  Address       The MMIO register to write.

+  @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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioBitFieldOr8 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioBitFieldOr8 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register 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  Address       The MMIO register to write.

+  @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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioBitFieldAnd8 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              AndData

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioBitFieldAnd8 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  8-bit MMIO register  and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 8-bit MMIO register specified by Address, 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 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register 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  Address       The MMIO register to write.

+  @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 MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+S3MmioBitFieldAndThenOr8 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT8              AndData,

+  IN UINT8              OrData

+  )

+{

+  return InternalSaveMmioWrite8ValueToBootScript (Address, MmioBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 16-bit MMIO register value to the boot script.

+

+  This internal worker function saves a 16-bit MMIO register value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT16

+InternalSaveMmioWrite16ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT16             Value

+  )

+{

+  InternalSaveMmioWriteValueToBootScript (S3BootScriptWidthUint16, Address, &Value);

+  

+  return Value;

+}

+

+/**

+  Reads a 16-bit MMIO register and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+S3MmioRead16 (

+  IN UINTN              Address

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioRead16 (Address));

+}

+

+/**

+  Writes a 16-bit MMIO register and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized and saves the value in the S3 script to be

+  replayed on S3 resume.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value to write to the MMIO register.

+

+  @return The value written the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioWrite16 (

+  IN UINTN              Address,

+  IN UINT16             Value

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioWrite16 (Address, Value));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 16-bit MMIO register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  OrData        The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioOr16 (

+  IN UINTN              Address,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioOr16 (Address, OrData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioAnd16 (

+  IN UINTN              Address,

+  IN UINT16             AndData

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioAnd16 (Address, AndData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioAndThenOr16 (

+  IN UINTN              Address,

+  IN UINT16             AndData,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioAndThenOr16 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register 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  Address       MMIO register to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+S3MmioBitFieldRead16 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioBitFieldRead16 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to a MMIO register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register 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  Address       The MMIO register to write.

+  @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 value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioBitFieldWrite16 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             Value

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioBitFieldWrite16 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register 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  Address       The MMIO register to write.

+  @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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioBitFieldOr16 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioBitFieldOr16 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register 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  Address       The MMIO register to write.

+  @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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioBitFieldAnd16 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             AndData

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioBitFieldAnd16 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  16-bit MMIO register and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 16-bit MMIO register specified by Address, 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 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register 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  Address       The MMIO register to write.

+  @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 MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+S3MmioBitFieldAndThenOr16 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT16             AndData,

+  IN UINT16             OrData

+  )

+{

+  return InternalSaveMmioWrite16ValueToBootScript (Address, MmioBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 32-bit MMIO register value to the boot script.

+

+  This internal worker function saves a 32-bit MMIO register value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT32

+InternalSaveMmioWrite32ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT32             Value

+  )

+{

+  InternalSaveMmioWriteValueToBootScript (S3BootScriptWidthUint32, Address, &Value);

+

+  return Value;

+}

+

+/**

+  Reads a 32-bit MMIO register saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+S3MmioRead32 (

+  IN UINTN              Address

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioRead32 (Address));

+}

+

+/**

+  Writes a 32-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value to write to the MMIO register.

+

+  @return The value written the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioWrite32 (

+  IN UINTN              Address,

+  IN UINT32             Value

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioWrite32 (Address, Value));

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 32-bit MMIO register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  OrData        The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioOr32 (

+  IN UINTN              Address,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioOr32 (Address, OrData));

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioAnd32 (

+  IN UINTN              Address,

+  IN UINT32             AndData

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioAnd32 (Address, AndData));

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioAndThenOr32 (

+  IN UINTN              Address,

+  IN UINT32             AndData,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioAndThenOr32 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register 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  Address       MMIO register 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 value read.

+

+**/

+UINT32

+EFIAPI

+S3MmioBitFieldRead32 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioBitFieldRead32 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to a MMIO register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register 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  Address       The MMIO register 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 value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioBitFieldWrite32 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             Value

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioBitFieldWrite32 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioBitFieldOr32 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioBitFieldOr32 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioBitFieldAnd32 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             AndData

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioBitFieldAnd32 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  32-bit MMIO register and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 32-bit MMIO register specified by Address, 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 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+S3MmioBitFieldAndThenOr32 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT32             AndData,

+  IN UINT32             OrData

+  )

+{

+  return InternalSaveMmioWrite32ValueToBootScript (Address, MmioBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 64-bit MMIO register value to the boot script.

+

+  This internal worker function saves a 64-bit MMIO register value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT64

+InternalSaveMmioWrite64ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT64             Value

+  )

+{

+  InternalSaveMmioWriteValueToBootScript (S3BootScriptWidthUint64, Address, &Value);

+

+  return Value;

+}

+

+/**

+  Reads a 64-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+S3MmioRead64 (

+  IN UINTN              Address

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioRead64 (Address));

+}

+

+/**

+  Writes a 64-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  Value         The value to write to the MMIO register.

+

+  @return The value written the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioWrite64 (

+  IN UINTN              Address,

+  IN UINT64             Value

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioWrite64 (Address, Value));

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 64-bit MMIO register and saves the value in the S3 script 

+  to be replayed on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  OrData        The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioOr64 (

+  IN UINTN              Address,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioOr64 (Address, OrData));

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register and saves the value in the S3 script to be 

+  replayed on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioAnd64 (

+  IN UINTN              Address,

+  IN UINT64             AndData

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioAnd64 (Address, AndData));

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address       The MMIO register to write.

+  @param  AndData       The value to AND with the read value from the MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioAndThenOr64 (

+  IN UINTN              Address,

+  IN UINT64             AndData,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioAndThenOr64 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register 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  Address       MMIO register 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.

+

+**/

+UINT64

+EFIAPI

+S3MmioBitFieldRead64 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioBitFieldRead64 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to a MMIO register and saves the value in the S3 script to

+  be replayed on S3 resume.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioBitFieldWrite64 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             Value

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioBitFieldWrite64 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register and 

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioBitFieldOr64 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioBitFieldOr64 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioBitFieldAnd64 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             AndData

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioBitFieldAnd64 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  64-bit MMIO register and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Reads the 64-bit MMIO register specified by Address, 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 MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register 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  Address       The MMIO register 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 MMIO register.

+  @param  OrData        The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+S3MmioBitFieldAndThenOr64 (

+  IN UINTN              Address,

+  IN UINTN              StartBit,

+  IN UINTN              EndBit,

+  IN UINT64             AndData,

+  IN UINT64             OrData

+  )

+{

+  return InternalSaveMmioWrite64ValueToBootScript (Address, MmioBitFieldAndThenOr64 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Copy data from MMIO region to system memory by using 8-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 8-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+S3MmioReadBuffer8 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT8       *Buffer

+  )

+{

+  UINT8       *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioReadBuffer8 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint8,

+             StartAddress,

+             Length / sizeof (UINT8),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 16-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 16-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+S3MmioReadBuffer16 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT16      *Buffer

+  )

+{

+  UINT16       *ReturnBuffer;

+  RETURN_STATUS   Status;

+

+  ReturnBuffer = MmioReadBuffer16 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint16,

+             StartAddress,

+             Length / sizeof (UINT16),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 32-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 32-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+S3MmioReadBuffer32 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT32      *Buffer

+  )

+{

+  UINT32      *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioReadBuffer32 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint32,

+             StartAddress,

+             Length / sizeof (UINT32),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 64-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 64-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+S3MmioReadBuffer64 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT64      *Buffer

+  )

+{

+  UINT64      *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioReadBuffer64 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint64,

+             StartAddress,

+             Length / sizeof (UINT64),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 8-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 8-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+S3MmioWriteBuffer8 (

+  IN  UINTN         StartAddress,

+  IN  UINTN         Length,

+  IN  CONST UINT8   *Buffer

+  )

+{

+  UINT8       *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioWriteBuffer8 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint8,

+             StartAddress,

+             Length / sizeof (UINT8),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to MMIO region by using 16-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 16-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+S3MmioWriteBuffer16 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT16 *Buffer

+  )

+{

+  UINT16      *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioWriteBuffer16 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint16,

+             StartAddress,

+             Length / sizeof (UINT16),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 32-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 32-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+S3MmioWriteBuffer32 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT32 *Buffer

+  )

+{

+  UINT32      *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioWriteBuffer32 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint32,

+             StartAddress,

+             Length / sizeof (UINT32),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to MMIO region by using 64-bit access

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 64-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+S3MmioWriteBuffer64 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT64 *Buffer

+  )

+{

+  UINT64      *ReturnBuffer;

+  RETURN_STATUS  Status;

+

+  ReturnBuffer = MmioWriteBuffer64 (StartAddress, Length, Buffer);

+

+  Status = S3BootScriptSaveMemWrite (

+             S3BootScriptWidthUint64,

+             StartAddress,

+             Length / sizeof (UINT64),

+             ReturnBuffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+

+  return ReturnBuffer;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
new file mode 100644
index 0000000..561c504
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
@@ -0,0 +1,47 @@
+## @file

+# Instance of S3 PCI Library based on PCI and S3 BootScript Library.

+#

+# S3 PCI Services that perform PCI Configuration cycles and 

+# also enable the PCI operation to be replayed during an S3 resume.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+# This program and the accompanying materials are

+# licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseS3PciLib

+  MODULE_UNI_FILE                = BaseS3PciLib.uni

+  FILE_GUID                      = F66B6BD2-513F-441d-B367-2D5BD4998A50

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = S3PciLib 

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  S3PciLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  PciLib

+  S3BootScriptLib

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/BaseS3PciLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/BaseS3PciLib.uni
new file mode 100644
index 0000000..d9cab8a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/BaseS3PciLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/S3PciLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/S3PciLib.c
new file mode 100644
index 0000000..e29f7fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3PciLib/S3PciLib.c
@@ -0,0 +1,1269 @@
+/** @file

+  PCI configuration Library Services that do PCI configuration and also enable

+  the PCI operations to be replayed during an S3 resume. This library class

+  maps directly on top of the PciLib class. 

+

+  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.

+

+**/

+

+

+#include <Base.h>

+

+#include <Library/DebugLib.h>

+#include <Library/S3BootScriptLib.h>

+#include <Library/PciLib.h>

+#include <Library/S3PciLib.h>

+

+#define PCILIB_TO_COMMON_ADDRESS(Address) \

+        ((UINT64) ((((UINTN) ((Address>>20) & 0xff)) << 24) + (((UINTN) ((Address>>15) & 0x1f)) << 16) + (((UINTN) ((Address>>12) & 0x07)) << 8) + ((UINTN) (Address & 0xfff ))))

+

+/**

+  Saves a PCI configuration value to the boot script.

+

+  This internal worker function saves a PCI configuration value in

+  the S3 script to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Width   The width of PCI configuration.

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Buffer  The buffer containing value.

+

+**/

+VOID

+InternalSavePciWriteValueToBootScript (

+  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,

+  IN UINTN                  Address,

+  IN VOID                   *Buffer

+  )

+{

+  RETURN_STATUS                Status;

+

+  Status = S3BootScriptSavePciCfgWrite (

+             Width,

+             PCILIB_TO_COMMON_ADDRESS(Address),

+             1,

+             Buffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+}

+

+/**

+  Saves an 8-bit PCI configuration value to the boot script.

+

+  This internal worker function saves an 8-bit PCI configuration value in

+  the S3 script to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value saved to boot script.

+

+  @return Value.

+

+**/

+UINT8

+InternalSavePciWrite8ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT8              Value

+  )

+{

+  InternalSavePciWriteValueToBootScript (S3BootScriptWidthUint8, Address, &Value);

+

+  return Value;

+}

+

+/**

+  Reads an 8-bit PCI configuration register and saves the value in the S3

+  script to be replayed on S3 resume.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciRead8 (

+  IN UINTN                     Address

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciRead8 (Address));

+}

+

+/**

+  Writes an 8-bit PCI configuration register and saves the value in the S3

+  script to be replayed on S3 resume.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciWrite8 (

+  IN UINTN                     Address,

+  IN UINT8                     Value

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciWrite8 (Address, Value));

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciOr8 (

+  IN UINTN                     Address,

+  IN UINT8                     OrData

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciOr8 (Address, OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciAnd8 (

+  IN UINTN                     Address,

+  IN UINT8                     AndData

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciAnd8 (Address, AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciAndThenOr8 (

+  IN UINTN                     Address,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciAndThenOr8 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register and saves the value in

+  the S3 script to be replayed on S3 resume.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciBitFieldRead8 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldRead8 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to a PCI configuration register and saves the value in

+  the S3 script to be replayed on S3 resume.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciBitFieldWrite8 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     Value

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldWrite8 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port and saves the value

+  in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciBitFieldOr8 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     OrData

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldOr8 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register and

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciBitFieldAnd8 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldAnd8 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in an 8-bit Address, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+S3PciBitFieldAndThenOr8 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+{

+  return InternalSavePciWrite8ValueToBootScript (Address, PciBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 16-bit PCI configuration value to the boot script.

+

+  This internal worker function saves a 16-bit PCI configuration value in

+  the S3 script to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return Value.

+

+**/

+UINT16

+InternalSavePciWrite16ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT16             Value

+  )

+{

+  InternalSavePciWriteValueToBootScript (S3BootScriptWidthUint16, Address, &Value);

+

+  return Value;

+}

+

+/**

+  Reads a 16-bit PCI configuration register and saves the value in the S3

+  script to be replayed on S3 resume.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciRead16 (

+  IN UINTN                     Address

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciRead16 (Address));

+}

+

+/**

+  Writes a 16-bit PCI configuration register and saves the value in the S3

+  script to be replayed on S3 resume.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciWrite16 (

+  IN UINTN                     Address,

+  IN UINT16                    Value

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciWrite16 (Address, Value));

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciOr16 (

+  IN UINTN                     Address,

+  IN UINT16                    OrData

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciOr16 (Address, OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciAnd16 (

+  IN UINTN                     Address,

+  IN UINT16                    AndData

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciAnd16 (Address, AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciAndThenOr16 (

+  IN UINTN                     Address,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciAndThenOr16 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register and saves the value in

+  the S3 script to be replayed on S3 resume.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciBitFieldRead16 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldRead16 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to a PCI configuration register and saves the value in

+  the S3 script to be replayed on S3 resume.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciBitFieldWrite16 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    Value

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldWrite16 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port and saves the value

+  in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciBitFieldOr16 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    OrData

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldOr16 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register and

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciBitFieldAnd16 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldAnd16 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 16-bit Address, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+S3PciBitFieldAndThenOr16 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+{

+  return InternalSavePciWrite16ValueToBootScript (Address, PciBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Saves a 32-bit PCI configuration value to the boot script.

+

+  This internal worker function saves a 32-bit PCI configuration value in the S3 script

+  to be replayed on S3 resume. 

+

+  If the saving process fails, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return Value.

+

+**/

+UINT32

+InternalSavePciWrite32ValueToBootScript (

+  IN UINTN              Address,

+  IN UINT32             Value

+  )

+{

+  InternalSavePciWriteValueToBootScript (S3BootScriptWidthUint32, Address, &Value);

+

+  return Value;

+}

+

+/**

+  Reads a 32-bit PCI configuration register and saves the value in the S3

+  script to be replayed on S3 resume.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciRead32 (

+  IN UINTN                     Address

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciRead32 (Address));

+}

+

+/**

+  Writes a 32-bit PCI configuration register and saves the value in the S3

+  script to be replayed on S3 resume.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciWrite32 (

+  IN UINTN                     Address,

+  IN UINT32                    Value

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciWrite32 (Address, Value));

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciOr32 (

+  IN UINTN                     Address,

+  IN UINT32                    OrData

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciOr32 (Address, OrData));

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciAnd32 (

+  IN UINTN                     Address,

+  IN UINT32                    AndData

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciAnd32 (Address, AndData));

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciAndThenOr32 (

+  IN UINTN                     Address,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciAndThenOr32 (Address, AndData, OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register and saves the value in

+  the S3 script to be replayed on S3 resume.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciBitFieldRead32 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldRead32 (Address, StartBit, EndBit));

+}

+

+/**

+  Writes a bit field to a PCI configuration register and saves the value in

+  the S3 script to be replayed on S3 resume.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciBitFieldWrite32 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    Value

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldWrite32 (Address, StartBit, EndBit, Value));

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port and saves the value

+  in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciBitFieldOr32 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    OrData

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldOr32 (Address, StartBit, EndBit, OrData));

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register and

+  saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciBitFieldAnd32 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldAnd32 (Address, StartBit, EndBit, AndData));

+}

+

+/**

+  Reads a bit field in a 32-bit Address, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+S3PciBitFieldAndThenOr32 (

+  IN UINTN                     Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+{

+  return InternalSavePciWrite32ValueToBootScript (Address, PciBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData));

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer

+  and saves the value in the S3 script to be replayed on S3 resume.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+S3PciReadBuffer (

+  IN  UINTN                    StartAddress,

+  IN  UINTN                    Size,

+  OUT VOID                     *Buffer

+  )

+{

+  RETURN_STATUS    Status;

+

+  Status = S3BootScriptSavePciCfgWrite (

+             S3BootScriptWidthUint8,

+             PCILIB_TO_COMMON_ADDRESS (StartAddress),

+             PciReadBuffer (StartAddress, Size, Buffer),

+             Buffer

+             );

+ ASSERT (Status == RETURN_SUCCESS);

+

+  return Size;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space and saves the value in the S3 script to be replayed on S3

+  resume.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+S3PciWriteBuffer (

+  IN UINTN                     StartAddress,

+  IN UINTN                     Size,

+  IN VOID                      *Buffer

+  )

+{

+  RETURN_STATUS    Status;

+

+  Status = S3BootScriptSavePciCfgWrite (

+             S3BootScriptWidthUint8,

+             PCILIB_TO_COMMON_ADDRESS (StartAddress),

+             PciWriteBuffer (StartAddress, Size, Buffer),

+             Buffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+  

+  return Size;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.inf
new file mode 100644
index 0000000..5536624
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.inf
@@ -0,0 +1,47 @@
+## @file

+# Instance of S3 Smbus Library based on SmBus and S3 BootScript Library.

+#

+# S3 Smbus Library Services that do SMBus transactions and also enable the

+# operatation to be replayed during an S3 resume. 

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+# This program and the accompanying materials are

+# licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseS3SmbusLib

+  MODULE_UNI_FILE                = BaseS3SmbusLib.uni

+  FILE_GUID                      = 01190654-FED0-40d3-BA7F-2925539E5830

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = S3SmbusLib 

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  S3SmbusLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+  SmbusLib

+  S3BootScriptLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.uni
new file mode 100644
index 0000000..ee1e411
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/BaseS3SmbusLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/S3SmbusLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/S3SmbusLib.c
new file mode 100644
index 0000000..1a7e0ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3SmbusLib/S3SmbusLib.c
@@ -0,0 +1,502 @@
+/** @file

+  Smbus Library Services that do SMBus transactions and also enable the operatation

+  to be replayed during an S3 resume. This library class maps directly on top

+  of the SmbusLib class. 

+

+  Copyright (c) 2007, 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 <Base.h>

+

+#include <Library/DebugLib.h>

+#include <Library/S3BootScriptLib.h>

+#include <Library/SmbusLib.h>

+#include <Library/S3SmbusLib.h>

+

+/**

+  Saves an SMBus operation to S3 script to be replayed on S3 resume. 

+

+  This function provides a standard way to save SMBus operation to S3 boot Script.

+  The data can either be of the Length byte, word, or a block of data.

+  If it falis to save S3 boot script, then ASSERT ().

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance that it will use to

+                          execute the SMBus transactions.

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will do. The maximum number of

+                          bytes can be revision specific and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave device. Not all operations

+                          require this argument. The length of this buffer is identified by Length.

+

+**/

+VOID

+InternalSaveSmBusExecToBootScript (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer

+  )

+{

+  RETURN_STATUS                Status;

+

+  Status = S3BootScriptSaveSmbusExecute (

+             SmBusAddress,

+             SmbusOperation,

+            &Length,

+             Buffer

+             );

+  ASSERT (Status == RETURN_SUCCESS);

+}

+

+/**

+  Executes an SMBUS quick read command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+S3SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  SmBusQuickRead (SmBusAddress, Status);

+  

+  InternalSaveSmBusExecToBootScript (EfiSmbusQuickRead, SmBusAddress, 0, NULL);

+}

+

+/**

+  Executes an SMBUS quick write command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+**/

+VOID

+EFIAPI

+S3SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  SmBusQuickWrite (SmBusAddress, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusQuickWrite, SmBusAddress, 0, NULL);

+}

+  

+/**

+  Executes an SMBUS receive byte command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+S3SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  Byte = SmBusReceiveByte (SmBusAddress, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS send byte command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to send.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+S3SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  Byte = SmBusSendByte (SmBusAddress, Value, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusSendByte, SmBusAddress, 1, &Byte);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS read data byte command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+S3SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  Byte = SmBusReadDataByte (SmBusAddress, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusReadByte, SmBusAddress, 1, &Byte);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS write data byte command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 8-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+S3SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  Byte = SmBusWriteDataByte (SmBusAddress, Value, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusWriteByte, SmBusAddress, 1, &Byte);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS read data word command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+S3SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+  

+  Word = SmBusReadDataWord (SmBusAddress, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusReadWord, SmBusAddress, 2, &Word);

+

+  return Word;

+}

+

+/**

+  Executes an SMBUS write data word command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+S3SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  Word = SmBusWriteDataWord (SmBusAddress, Value, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusWriteWord, SmBusAddress, 2, &Word);

+

+  return Word;

+}

+

+/**

+  Executes an SMBUS process call command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value           The 16-bit value to write.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+S3SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  Word = SmBusProcessCall (SmBusAddress, Value, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusProcessCall, SmBusAddress, 2, &Value);

+

+  return Word; 

+}

+

+/**

+  Executes an SMBUS read block command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+S3SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN   Length;

+

+  Length = SmBusReadBlock (SmBusAddress, Buffer, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusReadBlock, SmBusAddress, Length, Buffer);

+

+  return Length;

+}

+

+/**

+  Executes an SMBUS write block command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+S3SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN  Length;

+

+  Length = SmBusWriteBlock (SmBusAddress, Buffer, Status);

+

+  InternalSaveSmBusExecToBootScript (EfiSmbusWriteBlock, SmBusAddress, SMBUS_LIB_LENGTH (SmBusAddress), Buffer);

+  

+  return Length;

+}

+

+/**

+  Executes an SMBUS block process call command and saves the value in the S3 script to be replayed

+  on S3 resume.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If WriteBuffer is NULL, then ASSERT().

+  If ReadBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    Address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.

+  @param  ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+S3SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *WriteBuffer,

+  OUT VOID           *ReadBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN   Length;

+  

+  Length = SmBusBlockProcessCall (SmBusAddress, WriteBuffer, ReadBuffer, Status);

+  

+  InternalSaveSmBusExecToBootScript (EfiSmbusBWBRProcessCall, SmBusAddress, SMBUS_LIB_LENGTH (SmBusAddress), ReadBuffer);

+

+  return Length;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf
new file mode 100644
index 0000000..a77eec5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf
@@ -0,0 +1,45 @@
+## @file

+# Instance of S3 Stall Library based on Timer and S3 BootScript Library.

+#

+# Stall Services that do stall and also enable the Stall operatation

+# to be replayed during an S3 resume. 

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+# This program and the accompanying materials are

+# licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution.  The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseS3StallLib

+  MODULE_UNI_FILE                = BaseS3StallLib.uni

+  FILE_GUID                      = 498C6AC3-CC29-4821-BE6F-7C6F4ECF2C14

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = S3StallLib 

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  S3StallLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  TimerLib

+  S3BootScriptLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/BaseS3StallLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/BaseS3StallLib.uni
new file mode 100644
index 0000000..aeb36f8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/BaseS3StallLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/S3StallLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/S3StallLib.c
new file mode 100644
index 0000000..e5ebc87
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseS3StallLib/S3StallLib.c
@@ -0,0 +1,52 @@
+/** @file

+  Stall Services that do stall and also enable the Stall operatation

+  to be replayed during an S3 resume. This library class maps directly on top

+  of the Timer class. 

+

+  Copyright (c) 2007, 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 <Base.h>

+

+#include <Library/TimerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/S3BootScriptLib.h>

+#include <Library/S3StallLib.h>

+

+

+/**

+  Stalls the CPU for at least the given number of microseconds and and saves

+  the value in the S3 script to be replayed on S3 resume.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return MicroSeconds

+

+**/

+UINTN

+EFIAPI

+S3Stall (

+  IN UINTN                     MicroSeconds

+  )

+{

+  RETURN_STATUS    Status;

+  

+  Status = S3BootScriptSaveStall (MicroSecondDelay (MicroSeconds));

+  ASSERT (Status == RETURN_SUCCESS);

+  

+  return MicroSeconds;

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.c b/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.c
new file mode 100644
index 0000000..d44fa52
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.c
@@ -0,0 +1,112 @@
+/** @file

+  Null Serial Port library instance with empty functions.

+

+  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.

+

+**/

+

+

+#include <Base.h>

+#include <Library/SerialPortLib.h>

+

+/**

+  Initialize the serial device hardware.

+  

+  If no initialization is required, then return RETURN_SUCCESS.

+  If the serial device was successfully initialized, then return RETURN_SUCCESS.

+  If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.

+  

+  @retval RETURN_SUCCESS        The serial device was initialized.

+  @retval RETURN_DEVICE_ERROR   The serial device could not be initialized.

+

+**/

+RETURN_STATUS

+EFIAPI

+SerialPortInitialize (

+  VOID

+  )

+{

+  return RETURN_SUCCESS;

+}

+

+/**

+  Write data from buffer to serial device. 

+ 

+  Writes NumberOfBytes data bytes from Buffer to the serial device.  

+  The number of bytes actually written to the serial device is returned.

+  If the return value is less than NumberOfBytes, then the write operation failed.

+  If Buffer is NULL, then ASSERT(). 

+  If NumberOfBytes is zero, then return 0.

+

+  @param  Buffer           The pointer to the data buffer to be written.

+  @param  NumberOfBytes    The number of bytes to written to the serial device.

+

+  @retval 0                NumberOfBytes is 0.

+  @retval >0               The number of bytes written to the serial device.  

+                           If this value is less than NumberOfBytes, then the read operation failed.

+

+**/

+UINTN

+EFIAPI

+SerialPortWrite (

+  IN UINT8     *Buffer,

+  IN UINTN     NumberOfBytes

+)

+{

+  return 0;

+}

+

+

+/**

+  Read data from serial device and save the datas in buffer.

+ 

+  Reads NumberOfBytes data bytes from a serial device into the buffer

+  specified by Buffer. The number of bytes actually read is returned. 

+  If the return value is less than NumberOfBytes, then the rest operation failed.

+  If Buffer is NULL, then ASSERT(). 

+  If NumberOfBytes is zero, then return 0.

+

+  @param  Buffer           The pointer to the data buffer to store the data read from the serial device.

+  @param  NumberOfBytes    The number of bytes which will be read.

+

+  @retval 0                Read data failed; No data is to be read.

+  @retval >0               The actual number of bytes read from serial device.

+

+**/

+UINTN

+EFIAPI

+SerialPortRead (

+  OUT UINT8     *Buffer,

+  IN  UINTN     NumberOfBytes

+)

+{

+  return 0;

+}

+

+/**

+  Polls a serial device to see if there is any data waiting to be read.

+

+  Polls a serial device to see if there is any data waiting to be read.

+  If there is data waiting to be read from the serial device, then TRUE is returned.

+  If there is no data waiting to be read from the serial device, then FALSE is returned.

+

+  @retval TRUE             Data is waiting to be read from the serial device.

+  @retval FALSE            There is no data waiting to be read from the serial device.

+

+**/

+BOOLEAN

+EFIAPI

+SerialPortPoll (

+  VOID

+  )

+{

+  return FALSE;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
new file mode 100644
index 0000000..28a7988
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
@@ -0,0 +1,36 @@
+## @file

+#  Null instance of Serial Port Library with empty functions.

+#

+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseSerialPortLibNull

+  MODULE_UNI_FILE                = BaseSerialPortLibNull.uni

+  FILE_GUID                      = E4541241-8897-411a-91F8-7D7E45837146

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SerialPortLib

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BaseSerialPortLibNull.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.uni
new file mode 100644
index 0000000..6d80c8a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c b/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c
new file mode 100644
index 0000000..32bead9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c
@@ -0,0 +1,544 @@
+/** @file

+Null implementation of SmBusLib class library.

+

+Copyright (c) 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.

+

+**/

+

+#include <Base.h>

+#include <Library/SmbusLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS  The SMBUS command was executed.

+                        RETURN_TIMEOUT  A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+}

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+}

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 8-bit value to send.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 8-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 16-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 16-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer        Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS The SMBUS command was executed.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer        Pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If WriteBuffer is NULL, then ASSERT().

+  If ReadBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  Address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  WriteBuffer   Pointer to the buffer of bytes to write to the SMBUS.

+  @param  ReadBuffer    Pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.

+                        RETURN_DEVICE_ERROR  The request was not completed because a failure

+                        reflected in the Host Status Register bit.  Device errors are a result

+                        of a transaction collision, illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED  The SMBus operation is not supported.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *WriteBuffer,

+  OUT VOID           *ReadBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (WriteBuffer != NULL);

+  ASSERT (ReadBuffer  != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+  if (Status != NULL) {

+    *Status = RETURN_UNSUPPORTED;

+  }

+  return 0;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
new file mode 100644
index 0000000..512db33
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
@@ -0,0 +1,35 @@
+## @file

+# Null implementation of the SMBUS Library.

+#

+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseSmbusLibNull

+  MODULE_UNI_FILE                = BaseSmbusLibNull.uni

+  FILE_GUID                      = E2ECA273-A1C0-407E-9A5C-F10C55142196

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmbusLib

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BaseSmbusLibNull.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.uni
new file mode 100644
index 0000000..5a18f52
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c
new file mode 100644
index 0000000..4cd0d4c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c
@@ -0,0 +1,55 @@
+/** @file

+ Base Stack Check library for GCC/clang.

+

+ Use -fstack-protector-all compiler flag to make the compiler insert the

+ __stack_chk_guard "canary" value into the stack and check the value prior

+ to exiting the function. If the "canary" is overwritten __stack_chk_fail()

+ is called. This is GCC specific code.

+

+ Copyright (c) 2012, 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.

+

+**/

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+/// "canary" value that is inserted by the compiler into the stack frame.

+VOID *__stack_chk_guard = (VOID*)0x0AFF;

+

+// If ASLR was enabled we could use

+//void (*__stack_chk_guard)(void) = __stack_chk_fail;

+

+/**

+ Error path for compiler generated stack "canary" value check code. If the

+ stack canary has been overwritten this function gets called on exit of the

+ function.

+**/

+VOID

+__stack_chk_fail (

+ VOID

+ )

+{

+  UINT8 DebugPropertyMask;

+

+  DEBUG ((DEBUG_ERROR, "STACK FAULT: Buffer Overflow in function %a.\n", __builtin_return_address(0)));

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings even if

+  // BaseDebugLibNull is in use.

+  //

+  DebugPropertyMask = PcdGet8 (PcdDebugPropertyMask);

+  if ((DebugPropertyMask & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((DebugPropertyMask & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+   CpuDeadLoop ();

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
new file mode 100644
index 0000000..d02d971
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
@@ -0,0 +1,44 @@
+## @file

+#  Stack Check Library

+#

+#  Stack Check Library

+#

+#  Copyright (c) 2014, 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

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseStackCheckLib

+  MODULE_UNI_FILE                = BaseStackCheckLib.uni

+  FILE_GUID                      = 5f6579f7-b648-4fdb-9f19-4c17e27e8eff

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = NULL

+

+

+#

+#  VALID_ARCHITECTURES           = ARM AARCH64

+#

+

+[Sources]

+  BaseStackCheckGcc.c | GCC

+  BaseStackCheckGcc.c | RVCT

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+

+[FixedPcd]

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask  ## CONSUMES

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni
new file mode 100644
index 0000000..8b4078c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c
new file mode 100644
index 0000000..2e619cc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.c
@@ -0,0 +1,115 @@
+/** @file

+  Implementation of synchronization functions. Still needs to be ported

+

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return ++*Value;

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return --*Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c
new file mode 100644
index 0000000..9ddaa09
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.c
@@ -0,0 +1,115 @@
+/** @file

+  Implementation of synchronization functions. Still needs to be ported

+

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified 

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and 

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned. 

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return ++*Value;

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return --*Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
new file mode 100644
index 0000000..bf9cf67
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
@@ -0,0 +1,98 @@
+## @file

+#  Base Synchronization Library implementation.

+#

+#  Copyright (c) 2007 - 2014, 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseSynchronizationLib

+  MODULE_UNI_FILE                = BaseSynchronizationLib.uni

+  FILE_GUID                      = FC9990DF-C5FF-44cf-8799-CBB45B577F87

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SynchronizationLib

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64

+#

+[Sources]

+  BaseSynchronizationLibInternals.h

+

+[Sources.IA32]

+  Ia32/InterlockedCompareExchange64.c | MSFT 

+  Ia32/InterlockedCompareExchange32.c | MSFT 

+  Ia32/InterlockedDecrement.c | MSFT 

+  Ia32/InterlockedIncrement.c | MSFT 

+  SynchronizationMsc.c  | MSFT

+

+  Ia32/InterlockedCompareExchange64.asm | INTEL 

+  Ia32/InterlockedCompareExchange32.asm | INTEL 

+  Ia32/InterlockedDecrement.asm | INTEL 

+  Ia32/InterlockedIncrement.asm | INTEL 

+  Synchronization.c | INTEL

+

+  Ia32/GccInline.c | GCC

+  SynchronizationGcc.c  | GCC

+

+[Sources.X64]

+  X64/InterlockedCompareExchange64.c | MSFT

+  X64/InterlockedCompareExchange32.c | MSFT

+  

+  X64/InterlockedCompareExchange64.asm | INTEL

+  X64/InterlockedCompareExchange32.asm | INTEL

+  

+  X64/InterlockedDecrement.c | MSFT 

+  X64/InterlockedIncrement.c | MSFT 

+  SynchronizationMsc.c | MSFT 

+

+  X64/InterlockedDecrement.asm | INTEL 

+  X64/InterlockedIncrement.asm | INTEL 

+  Synchronization.c | INTEL 

+

+  X64/GccInline.c | GCC

+  SynchronizationGcc.c  | GCC 

+

+[Sources.IPF]

+  Ipf/Synchronization.c

+  Ipf/InterlockedCompareExchange64.s

+  Ipf/InterlockedCompareExchange32.s

+

+  Synchronization.c     | INTEL 

+  SynchronizationMsc.c  | MSFT 

+  SynchronizationGcc.c  | GCC 

+

+[Sources.EBC]

+  Synchronization.c

+  Ebc/Synchronization.c

+

+[Sources.ARM]

+  Synchronization.c

+  Arm/Synchronization.c

+

+[Sources.AARCH64]

+  Synchronization.c

+  AArch64/Synchronization.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PcdLib

+  TimerLib

+  DebugLib

+  BaseMemoryLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout  ## SOMETIMES_CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.uni
new file mode 100644
index 0000000..4ba38d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
new file mode 100644
index 0000000..e42824c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
@@ -0,0 +1,115 @@
+/** @file

+  Declaration of internal functions in BaseSynchronizationLib.

+

+  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 __BASE_SYNCHRONIZATION_LIB_INTERNALS__

+#define __BASE_SYNCHRONIZATION_LIB_INTERNALS__

+

+#include <Base.h>

+#include <Library/SynchronizationLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/TimerLib.h>

+#include <Library/PcdLib.h>

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  );

+

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  );

+

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 32-bit value used in compare operation.

+  @param  ExchangeValue A 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  );

+

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 64-bit value used in compare operation.

+  @param  ExchangeValue A 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
new file mode 100644
index 0000000..9c34b9f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
@@ -0,0 +1,116 @@
+/** @file

+  Implementation of synchronization functions on EBC.

+

+  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.

+

+**/

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit

+  unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit

+  unsigned integer specified by Value.  If Value is equal to

+  CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to

+  CompareValue, then Value is returned. The compare exchange

+  operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 32-bit value for the

+                        compare exchange operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      volatile UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified 

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and 

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned. 

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  return *Value != CompareValue ? *Value :

+           ((*Value = ExchangeValue), CompareValue);

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return ++*Value;

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  return --*Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
new file mode 100644
index 0000000..b5a7827
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
@@ -0,0 +1,173 @@
+/** @file

+  GCC inline implementation of BaseSynchronizationLib processor specific functions.

+  

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32    *Value

+  )

+{

+  UINT32  Result;

+

+  __asm__ __volatile__ (

+    "lock               \n\t"

+    "incl    %2         \n\t"

+    "movl    %2, %%eax      "

+    : "=a" (Result),          // %0

+      "=m" (*Value)           // %1

+    : "m"  (*Value)           // %2 

+    : "memory",

+      "cc"

+    );

+    

+  return Result;    

+

+}

+

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32       *Value

+  )

+{

+   UINT32  Result;

+  

+  __asm__ __volatile__ (

+    "lock               \n\t"

+    "decl    %2         \n\t"

+    "movl    %2, %%eax      "

+    : "=a" (Result),          // %0

+      "=m" (*Value)           // %1

+    : "m"  (*Value)           // %2 

+    : "memory",

+      "cc"

+    );

+    

+  return Result;

+}

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN OUT volatile  UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+

+  __asm__ __volatile__ (

+    "                     \n\t"

+    "lock                 \n\t"

+    "cmpxchgl    %1, %2   \n\t"

+    : "=a" (CompareValue)     // %0

+    : "q"  (ExchangeValue),   // %1

+      "m"  (*Value),          // %2

+      "0"  (CompareValue)     // %4 

+    : "memory",

+      "cc"

+    );

+

+  return CompareValue;

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN OUT  volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  __asm__ __volatile__ (

+    "                       \n\t"

+    "push        %%ebx      \n\t" 

+    "movl        %2,%%ebx   \n\t"   

+    "lock                   \n\t"

+    "cmpxchg8b   (%1)       \n\t"

+    "pop         %%ebx      \n\t"

+    : "+A"  (CompareValue)                    // %0

+    : "S"   (Value),                          // %1

+      "r"   ((UINT32) ExchangeValue),         // %2

+      "c"   ((UINT32) (ExchangeValue >> 32))  // %3

+    : "memory",

+      "cc"

+    );

+  

+  return CompareValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm
new file mode 100644
index 0000000..78ea72c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.asm
@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange32.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .486

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InternalSyncCompareExchange32 (

+;   IN      UINT32                    *Value,

+;   IN      UINT32                    CompareValue,

+;   IN      UINT32                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange32   PROC

+    mov     ecx, [esp + 4]

+    mov     eax, [esp + 8]

+    mov     edx, [esp + 12]

+    lock    cmpxchg [ecx], edx

+    ret

+InternalSyncCompareExchange32   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c
new file mode 100644
index 0000000..a2c6838
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange32.c
@@ -0,0 +1,50 @@
+/** @file

+  InterlockedCompareExchange32 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  _asm {

+    mov     ecx, Value

+    mov     eax, CompareValue

+    mov     edx, ExchangeValue

+    lock    cmpxchg [ecx], edx

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm
new file mode 100644
index 0000000..0fcbd23
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.asm
@@ -0,0 +1,47 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange64.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .586P

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InternalSyncCompareExchange64 (

+;   IN      UINT64                    *Value,

+;   IN      UINT64                    CompareValue,

+;   IN      UINT64                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange64   PROC    USES    esi ebx

+    mov     esi, [esp + 12]

+    mov     eax, [esp + 16]

+    mov     edx, [esp + 20]

+    mov     ebx, [esp + 24]

+    mov     ecx, [esp + 28]

+    lock    cmpxchg8b   qword ptr [esi]

+    ret

+InternalSyncCompareExchange64   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c
new file mode 100644
index 0000000..73af6ef
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange64.c
@@ -0,0 +1,50 @@
+/** @file

+  InterlockedCompareExchange64 function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 64-bit value used in a compare operation.

+  @param  ExchangeValue A 64-bit value used in an exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  _asm {

+    mov     esi, Value

+    mov     eax, dword ptr [CompareValue + 0]

+    mov     edx, dword ptr [CompareValue + 4]

+    mov     ebx, dword ptr [ExchangeValue + 0]

+    mov     ecx, dword ptr [ExchangeValue + 4]

+    lock    cmpxchg8b   qword ptr [esi]

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm
new file mode 100644
index 0000000..22cb0b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedDecrement.Asm

+;

+; Abstract:

+;

+;   InterlockedDecrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InternalSyncDecrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncDecrement   PROC

+    mov     eax, [esp + 4]

+    lock    dec     dword ptr [eax]

+    mov     eax, [eax]

+    ret

+InternalSyncDecrement   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c
new file mode 100644
index 0000000..7f18e0b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedDecrement.c
@@ -0,0 +1,42 @@
+/** @file

+  InterlockedDecrement function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      UINT32                    *Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    lock    dec     dword ptr [eax]

+    mov     eax, [eax]

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm
new file mode 100644
index 0000000..51675f6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.asm
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedIncrement.Asm

+;

+; Abstract:

+;

+;   InterlockedIncrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .386

+    .model  flat,C

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InternalSyncIncrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncIncrement   PROC

+    mov     eax, [esp + 4]

+    lock    inc     dword ptr [eax]

+    mov     eax, [eax]

+    ret

+InternalSyncIncrement   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c
new file mode 100644
index 0000000..cf9f92a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedIncrement.c
@@ -0,0 +1,43 @@
+/** @file

+  InterLockedIncrement function

+

+  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.

+

+**/

+

+

+

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      UINT32                    *Value

+  )

+{

+  _asm {

+    mov     eax, Value

+    lock    inc     dword ptr [eax]

+    mov     eax, [eax]

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s
new file mode 100644
index 0000000..48273c9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange32.s
@@ -0,0 +1,29 @@
+/// @file

+///   Contains an implementation of InterlockedCompareExchange32 on Itanium-

+///   based architecture.

+///

+/// 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.

+///

+/// Module Name:  InterlockedCompareExchange32.s

+///

+///

+

+.auto

+.text

+

+.proc   InternalSyncCompareExchange32

+.type   InternalSyncCompareExchange32, @function

+InternalSyncCompareExchange32::

+        zxt4                r33 = r33

+        mov                 ar.ccv = r33

+        cmpxchg4.rel        r8  = [r32], r34

+        mf

+        br.ret.sptk.many    b0

+.endp   InternalSyncCompareExchange32

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s
new file mode 100644
index 0000000..b6ee196
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange64.s
@@ -0,0 +1,28 @@
+/// @file

+///   Contains an implementation of InterlockedCompareExchange64 on Itanium-

+///   based architecture.

+///

+/// 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.

+///

+/// Module Name:  InterlockedCompareExchange64.s

+///

+///

+

+.auto

+.text

+

+.proc   InternalSyncCompareExchange64

+.type   InternalSyncCompareExchange64, @function

+InternalSyncCompareExchange64::

+        mov                 ar.ccv = r33

+        cmpxchg8.rel        r8  = [r32], r34

+        mf

+        br.ret.sptk.many    b0

+.endp   InternalSyncCompareExchange64

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c
new file mode 100644
index 0000000..3e316e7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/Synchronization.c
@@ -0,0 +1,77 @@
+/** @file

+  Implementation of synchronization functions on Itanium.

+

+  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.

+

+**/

+

+#include "BaseSynchronizationLibInternals.h"

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  UINT32                            OriginalValue;

+

+  do {

+    OriginalValue = *Value;

+  } while (OriginalValue != InternalSyncCompareExchange32 (

+                              Value,

+                              OriginalValue,

+                              OriginalValue + 1

+                              ));

+  return OriginalValue + 1;

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32           *Value

+  )

+{

+  UINT32                            OriginalValue;

+

+  do {

+    OriginalValue = *Value;

+  } while (OriginalValue != InternalSyncCompareExchange32 (

+                              Value,

+                              OriginalValue,

+                              OriginalValue - 1

+                              ));

+  return OriginalValue - 1;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
new file mode 100644
index 0000000..0eea40b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
@@ -0,0 +1,387 @@
+/** @file

+  Implementation of synchronization functions.

+

+  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.

+

+**/

+

+#include "BaseSynchronizationLibInternals.h"

+

+#define SPIN_LOCK_RELEASED          ((UINTN) 1)

+#define SPIN_LOCK_ACQUIRED          ((UINTN) 2)

+

+/**

+  Retrieves the architecture specific spin lock alignment requirements for

+  optimal spin lock performance.

+

+  This function retrieves the spin lock alignment requirements for optimal

+  performance on a given CPU architecture. The spin lock alignment is byte alignment. 

+  It must be a power of two and is returned by this function. If there are no alignment

+  requirements, then 1 must be returned. The spin lock synchronization

+  functions must function correctly if the spin lock size and alignment values

+  returned by this function are not used at all. These values are hints to the

+  consumers of the spin lock synchronization functions to obtain optimal spin

+  lock performance.

+

+  @return The architecture specific spin lock alignment.

+

+**/

+UINTN

+EFIAPI

+GetSpinLockProperties (

+  VOID

+  )

+{

+  return 32;

+}

+

+/**

+  Initializes a spin lock to the released state and returns the spin lock.

+

+  This function initializes the spin lock specified by SpinLock to the released

+  state, and returns SpinLock. Optimal performance can be achieved by calling

+  GetSpinLockProperties() to determine the size and alignment requirements for

+  SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to initialize to the released

+                    state.

+

+  @return SpinLock is in release state.

+

+**/

+SPIN_LOCK *

+EFIAPI

+InitializeSpinLock (

+  OUT      SPIN_LOCK                 *SpinLock

+  )

+{

+  ASSERT (SpinLock != NULL);

+  *SpinLock = SPIN_LOCK_RELEASED;

+  return SpinLock;

+}

+

+/**

+  Waits until a spin lock can be placed in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns SpinLock. Otherwise, this function waits

+  indefinitely for the spin lock to be released, and then places it in the

+  acquired state and returns SpinLock. All state transitions of SpinLock must

+  be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+  If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in

+  PcdSpinLockTimeout microseconds, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @return SpinLock acquired the lock.

+

+**/

+SPIN_LOCK *

+EFIAPI

+AcquireSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  UINT64  Current;

+  UINT64  Previous;

+  UINT64  Total;

+  UINT64  Start;

+  UINT64  End;

+  UINT64  Timeout;

+  INT64   Cycle;

+  INT64   Delta;

+

+  if (PcdGet32 (PcdSpinLockTimeout) > 0) {

+    //

+    // Get the current timer value

+    //

+    Current = GetPerformanceCounter();

+

+    //

+    // Initialize local variables

+    //

+    Start = 0;

+    End   = 0;

+    Total = 0;

+

+    //

+    // Retrieve the performance counter properties and compute the number of performance

+    // counter ticks required to reach the timeout

+    //

+    Timeout = DivU64x32 (

+                MultU64x32 (

+                  GetPerformanceCounterProperties (&Start, &End),

+                  PcdGet32 (PcdSpinLockTimeout)

+                  ),

+                1000000

+                );

+    Cycle = End - Start;

+    if (Cycle < 0) {

+      Cycle = -Cycle;

+    }

+    Cycle++;

+

+    while (!AcquireSpinLockOrFail (SpinLock)) {

+      CpuPause ();

+      Previous = Current;

+      Current  = GetPerformanceCounter();

+      Delta = (INT64) (Current - Previous);

+      if (Start > End) {

+        Delta = -Delta;

+      }

+      if (Delta < 0) {

+        Delta += Cycle;

+      }

+      Total += Delta;

+      ASSERT (Total < Timeout);

+    }

+  } else {

+    while (!AcquireSpinLockOrFail (SpinLock)) {

+      CpuPause ();

+    }

+  }

+  return SpinLock;

+}

+

+/**

+  Attempts to place a spin lock in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns TRUE. Otherwise, FALSE is returned. All state

+  transitions of SpinLock must be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @retval TRUE  SpinLock was placed in the acquired state.

+  @retval FALSE SpinLock could not be acquired.

+

+**/

+BOOLEAN

+EFIAPI

+AcquireSpinLockOrFail (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  SPIN_LOCK    LockValue;

+

+  ASSERT (SpinLock != NULL);

+

+  LockValue = *SpinLock;

+  ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue);

+

+  return (BOOLEAN)(

+           InterlockedCompareExchangePointer (

+             (VOID**)SpinLock,

+             (VOID*)SPIN_LOCK_RELEASED,

+             (VOID*)SPIN_LOCK_ACQUIRED

+             ) == (VOID*)SPIN_LOCK_RELEASED

+           );

+}

+

+/**

+  Releases a spin lock.

+

+  This function places the spin lock specified by SpinLock in the release state

+  and returns SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to release.

+

+  @return SpinLock released lock.

+

+**/

+SPIN_LOCK *

+EFIAPI

+ReleaseSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  SPIN_LOCK    LockValue;

+

+  ASSERT (SpinLock != NULL);

+

+  LockValue = *SpinLock;

+  ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue);

+

+  *SpinLock = SPIN_LOCK_RELEASED;

+  return SpinLock;

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedIncrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncIncrement (Value);

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedDecrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncDecrement (Value);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InterlockedCompareExchange32 (

+  IN OUT  UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InterlockedCompareExchange64 (

+  IN OUT  UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a pointer value.

+

+  Performs an atomic compare exchange operation on the pointer value specified

+  by Value. If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned. If Value is not equal to

+  CompareValue, then Value is returned. The compare exchange operation must be

+  performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the pointer value for the compare exchange

+                        operation.

+  @param  CompareValue  Pointer value used in compare operation.

+  @param  ExchangeValue Pointer value used in exchange operation.

+

+  @return The original *Value before exchange.

+**/

+VOID *

+EFIAPI

+InterlockedCompareExchangePointer (

+  IN OUT  VOID                      **Value,

+  IN      VOID                      *CompareValue,

+  IN      VOID                      *ExchangeValue

+  )

+{

+  UINT8  SizeOfValue;

+

+  SizeOfValue = sizeof (*Value);

+

+  switch (SizeOfValue) {

+    case sizeof (UINT32):

+      return (VOID*)(UINTN)InterlockedCompareExchange32 (

+                             (UINT32*)Value,

+                             (UINT32)(UINTN)CompareValue,

+                             (UINT32)(UINTN)ExchangeValue

+                             );

+    case sizeof (UINT64):

+      return (VOID*)(UINTN)InterlockedCompareExchange64 (

+                             (UINT64*)Value,

+                             (UINT64)(UINTN)CompareValue,

+                             (UINT64)(UINTN)ExchangeValue

+                             );

+    default:

+      ASSERT (FALSE);

+      return NULL;

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
new file mode 100644
index 0000000..badf73c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
@@ -0,0 +1,403 @@
+/** @file

+  Implementation of synchronization functions.

+

+  Copyright (c) 2006 - 2012, 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.

+

+**/

+

+#include "BaseSynchronizationLibInternals.h"

+

+//

+// GCC inline assembly for Read Write Barrier  

+//

+#define _ReadWriteBarrier() do { __asm__ __volatile__ ("": : : "memory"); } while(0)

+

+#define SPIN_LOCK_RELEASED          ((UINTN) 1)

+#define SPIN_LOCK_ACQUIRED          ((UINTN) 2)

+

+/**

+  Retrieves the architecture specific spin lock alignment requirements for

+  optimal spin lock performance.

+

+  This function retrieves the spin lock alignment requirements for optimal

+  performance on a given CPU architecture. The spin lock alignment is byte alignment. 

+  It must be a power of two and is returned by this function. If there are no alignment

+  requirements, then 1 must be returned. The spin lock synchronization

+  functions must function correctly if the spin lock size and alignment values

+  returned by this function are not used at all. These values are hints to the

+  consumers of the spin lock synchronization functions to obtain optimal spin

+  lock performance.

+

+  @return The architecture specific spin lock alignment.

+

+**/

+UINTN

+EFIAPI

+GetSpinLockProperties (

+  VOID

+  )

+{

+  return 32;

+}

+

+/**

+  Initializes a spin lock to the released state and returns the spin lock.

+

+  This function initializes the spin lock specified by SpinLock to the released

+  state, and returns SpinLock. Optimal performance can be achieved by calling

+  GetSpinLockProperties() to determine the size and alignment requirements for

+  SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to initialize to the released

+                    state.

+

+  @return SpinLock is in release state.

+

+**/

+SPIN_LOCK *

+EFIAPI

+InitializeSpinLock (

+  OUT      SPIN_LOCK                 *SpinLock

+  )

+{

+  ASSERT (SpinLock != NULL);

+

+  _ReadWriteBarrier();

+  *SpinLock = SPIN_LOCK_RELEASED;

+  _ReadWriteBarrier();

+

+  return SpinLock;

+}

+

+/**

+  Waits until a spin lock can be placed in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns SpinLock. Otherwise, this function waits

+  indefinitely for the spin lock to be released, and then places it in the

+  acquired state and returns SpinLock. All state transitions of SpinLock must

+  be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+  If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in

+  PcdSpinLockTimeout microseconds, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @return SpinLock acquired the lock.

+

+**/

+SPIN_LOCK *

+EFIAPI

+AcquireSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  UINT64  Current;

+  UINT64  Previous;

+  UINT64  Total;

+  UINT64  Start;

+  UINT64  End;

+  UINT64  Timeout;

+  INT64   Cycle;

+  INT64   Delta;

+

+  if (PcdGet32 (PcdSpinLockTimeout) > 0) {

+    //

+    // Get the current timer value

+    //

+    Current = GetPerformanceCounter();

+

+    //

+    // Initialize local variables

+    //

+    Start = 0;

+    End   = 0;

+    Total = 0;

+

+    //

+    // Retrieve the performance counter properties and compute the number of performance

+    // counter ticks required to reach the timeout

+    //

+    Timeout = DivU64x32 (

+                MultU64x32 (

+                  GetPerformanceCounterProperties (&Start, &End),

+                  PcdGet32 (PcdSpinLockTimeout)

+                  ),

+                1000000

+                );

+    Cycle = End - Start;

+    if (Cycle < 0) {

+      Cycle = -Cycle;

+    }

+    Cycle++;

+

+    while (!AcquireSpinLockOrFail (SpinLock)) {

+      CpuPause ();

+      Previous = Current;

+      Current  = GetPerformanceCounter();

+      Delta = (INT64) (Current - Previous);

+      if (Start > End) {

+        Delta = -Delta;

+      }

+      if (Delta < 0) {

+        Delta += Cycle;

+      }

+      Total += Delta;

+      ASSERT (Total < Timeout);

+    }

+  } else {

+    while (!AcquireSpinLockOrFail (SpinLock)) {

+      CpuPause ();

+    }

+  }

+  return SpinLock;

+}

+

+/**

+  Attempts to place a spin lock in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns TRUE. Otherwise, FALSE is returned. All state

+  transitions of SpinLock must be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @retval TRUE  SpinLock was placed in the acquired state.

+  @retval FALSE SpinLock could not be acquired.

+

+**/

+BOOLEAN

+EFIAPI

+AcquireSpinLockOrFail (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  SPIN_LOCK   LockValue;

+  VOID        *Result;

+  

+  ASSERT (SpinLock != NULL);

+

+  LockValue = *SpinLock;

+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);

+

+  _ReadWriteBarrier ();

+  Result = InterlockedCompareExchangePointer (

+             (VOID**)SpinLock,

+             (VOID*)SPIN_LOCK_RELEASED,

+             (VOID*)SPIN_LOCK_ACQUIRED

+           );

+

+  _ReadWriteBarrier ();

+  return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED);

+}

+

+/**

+  Releases a spin lock.

+

+  This function places the spin lock specified by SpinLock in the release state

+  and returns SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to release.

+

+  @return SpinLock released the lock.

+

+**/

+SPIN_LOCK *

+EFIAPI

+ReleaseSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  SPIN_LOCK    LockValue;

+

+  ASSERT (SpinLock != NULL);

+

+  LockValue = *SpinLock;

+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);

+

+  _ReadWriteBarrier ();

+  *SpinLock = SPIN_LOCK_RELEASED;

+  _ReadWriteBarrier ();

+

+  return SpinLock;

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedIncrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncIncrement (Value);

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedDecrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncDecrement (Value);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 32-bit value used in compare operation.

+  @param  ExchangeValue A 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InterlockedCompareExchange32 (

+  IN OUT  UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 64-bit value used in a compare operation.

+  @param  ExchangeValue A 64-bit value used in an exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InterlockedCompareExchange64 (

+  IN OUT  UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a pointer value.

+

+  Performs an atomic compare exchange operation on the pointer value specified

+  by Value. If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned. If Value is not equal to

+  CompareValue, then Value is returned. The compare exchange operation must be

+  performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the pointer value for the compare exchange

+                        operation.

+  @param  CompareValue  A pointer value used in a compare operation.

+  @param  ExchangeValue A pointer value used in an exchange operation.

+

+  @return The original *Value before exchange.

+**/

+VOID *

+EFIAPI

+InterlockedCompareExchangePointer (

+  IN OUT  VOID                      **Value,

+  IN      VOID                      *CompareValue,

+  IN      VOID                      *ExchangeValue

+  )

+{

+  UINT8  SizeOfValue;

+

+  SizeOfValue = sizeof (*Value);

+

+  switch (SizeOfValue) {

+    case sizeof (UINT32):

+      return (VOID*)(UINTN)InterlockedCompareExchange32 (

+                             (UINT32*)Value,

+                             (UINT32)(UINTN)CompareValue,

+                             (UINT32)(UINTN)ExchangeValue

+                             );

+    case sizeof (UINT64):

+      return (VOID*)(UINTN)InterlockedCompareExchange64 (

+                             (UINT64*)Value,

+                             (UINT64)(UINTN)CompareValue,

+                             (UINT64)(UINTN)ExchangeValue

+                             );

+    default:

+      ASSERT (FALSE);

+      return NULL;

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
new file mode 100644
index 0000000..9b20236
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
@@ -0,0 +1,405 @@
+/** @file

+  Implementation of synchronization functions.

+

+  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.

+

+**/

+

+#include "BaseSynchronizationLibInternals.h"

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for read write barrier Intrinsics.

+**/

+

+void    _ReadWriteBarrier (void);

+#pragma intrinsic(_ReadWriteBarrier)

+

+

+#define SPIN_LOCK_RELEASED          ((UINTN) 1)

+#define SPIN_LOCK_ACQUIRED          ((UINTN) 2)

+

+/**

+  Retrieves the architecture specific spin lock alignment requirements for

+  optimal spin lock performance.

+

+  This function retrieves the spin lock alignment requirements for optimal

+  performance on a given CPU architecture. The spin lock alignment is byte alignment. 

+  It must be a power of two and is returned by this function. If there are no alignment

+  requirements, then 1 must be returned. The spin lock synchronization

+  functions must function correctly if the spin lock size and alignment values

+  returned by this function are not used at all. These values are hints to the

+  consumers of the spin lock synchronization functions to obtain optimal spin

+  lock performance.

+

+  @return The architecture specific spin lock alignment.

+

+**/

+UINTN

+EFIAPI

+GetSpinLockProperties (

+  VOID

+  )

+{

+  return 32;

+}

+

+/**

+  Initializes a spin lock to the released state and returns the spin lock.

+

+  This function initializes the spin lock specified by SpinLock to the released

+  state, and returns SpinLock. Optimal performance can be achieved by calling

+  GetSpinLockProperties() to determine the size and alignment requirements for

+  SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to initialize to the released

+                    state.

+

+  @return SpinLock is in release state.

+

+**/

+SPIN_LOCK *

+EFIAPI

+InitializeSpinLock (

+  OUT      SPIN_LOCK                 *SpinLock

+  )

+{

+  ASSERT (SpinLock != NULL);

+

+  _ReadWriteBarrier();

+  *SpinLock = SPIN_LOCK_RELEASED;

+  _ReadWriteBarrier();

+

+  return SpinLock;

+}

+

+/**

+  Waits until a spin lock can be placed in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns SpinLock. Otherwise, this function waits

+  indefinitely for the spin lock to be released, and then places it in the

+  acquired state and returns SpinLock. All state transitions of SpinLock must

+  be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+  If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in

+  PcdSpinLockTimeout microseconds, then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @return SpinLock acquired the lock.

+

+**/

+SPIN_LOCK *

+EFIAPI

+AcquireSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  UINT64  Current;

+  UINT64  Previous;

+  UINT64  Total;

+  UINT64  Start;

+  UINT64  End;

+  UINT64  Timeout;

+  INT64   Cycle;

+  INT64   Delta;

+

+  if (PcdGet32 (PcdSpinLockTimeout) > 0) {

+    //

+    // Get the current timer value

+    //

+    Current = GetPerformanceCounter();

+

+    //

+    // Initialize local variables

+    //

+    Start = 0;

+    End   = 0;

+    Total = 0;

+

+    //

+    // Retrieve the performance counter properties and compute the number of performance

+    // counter ticks required to reach the timeout

+    //

+    Timeout = DivU64x32 (

+                MultU64x32 (

+                  GetPerformanceCounterProperties (&Start, &End),

+                  PcdGet32 (PcdSpinLockTimeout)

+                  ),

+                1000000

+                );

+    Cycle = End - Start;

+    if (Cycle < 0) {

+      Cycle = -Cycle;

+    }

+    Cycle++;

+

+    while (!AcquireSpinLockOrFail (SpinLock)) {

+      CpuPause ();

+      Previous = Current;

+      Current  = GetPerformanceCounter();

+      Delta = (INT64) (Current - Previous);

+      if (Start > End) {

+        Delta = -Delta;

+      }

+      if (Delta < 0) {

+        Delta += Cycle;

+      }

+      Total += Delta;

+      ASSERT (Total < Timeout);

+    }

+  } else {

+    while (!AcquireSpinLockOrFail (SpinLock)) {

+      CpuPause ();

+    }

+  }

+  return SpinLock;

+}

+

+/**

+  Attempts to place a spin lock in the acquired state.

+

+  This function checks the state of the spin lock specified by SpinLock. If

+  SpinLock is in the released state, then this function places SpinLock in the

+  acquired state and returns TRUE. Otherwise, FALSE is returned. All state

+  transitions of SpinLock must be performed using MP safe mechanisms.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.

+

+  @retval TRUE  SpinLock was placed in the acquired state.

+  @retval FALSE SpinLock could not be acquired.

+

+**/

+BOOLEAN

+EFIAPI

+AcquireSpinLockOrFail (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  SPIN_LOCK   LockValue;

+  VOID        *Result;

+  

+  ASSERT (SpinLock != NULL);

+

+  LockValue = *SpinLock;

+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);

+

+  _ReadWriteBarrier ();

+  Result = InterlockedCompareExchangePointer (

+             (VOID**)SpinLock,

+             (VOID*)SPIN_LOCK_RELEASED,

+             (VOID*)SPIN_LOCK_ACQUIRED

+           );

+

+  _ReadWriteBarrier ();

+  return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED);

+}

+

+/**

+  Releases a spin lock.

+

+  This function places the spin lock specified by SpinLock in the release state

+  and returns SpinLock.

+

+  If SpinLock is NULL, then ASSERT().

+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().

+

+  @param  SpinLock  A pointer to the spin lock to release.

+

+  @return SpinLock released the lock.

+

+**/

+SPIN_LOCK *

+EFIAPI

+ReleaseSpinLock (

+  IN OUT  SPIN_LOCK                 *SpinLock

+  )

+{

+  SPIN_LOCK    LockValue;

+

+  ASSERT (SpinLock != NULL);

+

+  LockValue = *SpinLock;

+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);

+

+  _ReadWriteBarrier ();

+  *SpinLock = SPIN_LOCK_RELEASED;

+  _ReadWriteBarrier ();

+

+  return SpinLock;

+}

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedIncrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncIncrement (Value);

+}

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InterlockedDecrement (

+  IN      UINT32                    *Value

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncDecrement (Value);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 32-bit value used in a compare operation.

+  @param  ExchangeValue A 32-bit value used in an exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InterlockedCompareExchange32 (

+  IN OUT  UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  A 64-bit value used in a compare operation.

+  @param  ExchangeValue A 64-bit value used in an exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InterlockedCompareExchange64 (

+  IN OUT  UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  ASSERT (Value != NULL);

+  return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);

+}

+

+/**

+  Performs an atomic compare exchange operation on a pointer value.

+

+  Performs an atomic compare exchange operation on the pointer value specified

+  by Value. If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned. If Value is not equal to

+  CompareValue, then Value is returned. The compare exchange operation must be

+  performed using MP safe mechanisms.

+

+  If Value is NULL, then ASSERT().

+

+  @param  Value         A pointer to the pointer value for the compare exchange

+                        operation.

+  @param  CompareValue  A pointer value used in a compare operation.

+  @param  ExchangeValue A pointer value used in an exchange operation.

+

+  @return The original *Value before exchange.

+**/

+VOID *

+EFIAPI

+InterlockedCompareExchangePointer (

+  IN OUT  VOID                      **Value,

+  IN      VOID                      *CompareValue,

+  IN      VOID                      *ExchangeValue

+  )

+{

+  UINT8  SizeOfValue;

+

+  SizeOfValue = (UINT8) sizeof (*Value);

+

+  switch (SizeOfValue) {

+    case sizeof (UINT32):

+      return (VOID*)(UINTN)InterlockedCompareExchange32 (

+                             (UINT32*)Value,

+                             (UINT32)(UINTN)CompareValue,

+                             (UINT32)(UINTN)ExchangeValue

+                             );

+    case sizeof (UINT64):

+      return (VOID*)(UINTN)InterlockedCompareExchange64 (

+                             (UINT64*)Value,

+                             (UINT64)(UINTN)CompareValue,

+                             (UINT64)(UINTN)ExchangeValue

+                             );

+    default:

+      ASSERT (FALSE);

+      return NULL;

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
new file mode 100644
index 0000000..ceb80ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
@@ -0,0 +1,176 @@
+/** @file

+  GCC inline implementation of BaseSynchronizationLib processor specific functions.

+  

+  Copyright (c) 2006 - 2010, 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.

+

+**/

+

+

+

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      volatile UINT32    *Value

+  )

+{

+  UINT32  Result;

+

+  __asm__ __volatile__ (

+    "lock               \n\t"

+    "incl    %2         \n\t"

+    "mov     %2, %%eax      "

+    : "=a" (Result),          // %0

+      "=m" (*Value)           // %1

+    : "m"  (*Value)           // %2 

+    : "memory",

+      "cc"

+    );

+    

+  return Result;    

+}

+

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decremented value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      volatile UINT32       *Value

+  )

+{

+   UINT32  Result;

+  

+  __asm__ __volatile__ (

+    "lock               \n\t"

+    "decl    %2         \n\t"

+    "mov     %2, %%eax      "

+    : "=a" (Result),          // %0

+      "=m" (*Value)           // %1

+    : "m"  (*Value)           // %2 

+    : "memory",

+      "cc"

+    );

+    

+  return Result;

+}

+

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN OUT volatile  UINT32           *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+

+

+  __asm__ __volatile__ (

+    "lock                 \n\t"

+    "cmpxchgl    %3, %1       "

+    : "=a" (CompareValue),    // %0

+      "=m" (*Value)           // %1

+    : "a"  (CompareValue),    // %2

+      "r"  (ExchangeValue),   // %3 

+      "m"  (*Value)

+    : "memory",

+      "cc"

+    );

+    

+  return CompareValue;

+}

+

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN OUT  volatile UINT64           *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+

+  __asm__ __volatile__ (

+    "lock                 \n\t"

+    "cmpxchgq    %3, %1       "

+    : "=a" (CompareValue),    // %0

+      "=m" (*Value)           // %1

+    : "a"  (CompareValue),    // %2

+      "r"  (ExchangeValue),   // %3 

+      "m"  (*Value)

+    : "memory",

+      "cc"

+    );

+  

+  return CompareValue;

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm
new file mode 100644
index 0000000..ee94ff7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange32.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange32 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedCompareExchange32 (

+;   IN      UINT32                    *Value,

+;   IN      UINT32                    CompareValue,

+;   IN      UINT32                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange32   PROC

+    mov     eax, edx

+    lock    cmpxchg [rcx], r8d

+    ret

+InternalSyncCompareExchange32   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c
new file mode 100644
index 0000000..9f8f3d3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange32.c
@@ -0,0 +1,54 @@
+/** @file

+  InterlockedCompareExchange32 function

+

+  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.

+

+**/

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+long _InterlockedCompareExchange(

+   long volatile * Destination,

+   long Exchange,

+   long Comperand

+);

+

+#pragma intrinsic(_InterlockedCompareExchange)

+

+/**

+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 32-bit unsigned integer

+  specified by Value.  If Value is equal to CompareValue, then Value is set to

+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,

+  then Value is returned.  The compare exchange operation must be performed using

+  MP safe mechanisms.

+

+  @param  Value         A pointer to the 32-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  32-bit value used in compare operation.

+  @param  ExchangeValue 32-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT32

+EFIAPI

+InternalSyncCompareExchange32 (

+  IN      UINT32                    *Value,

+  IN      UINT32                    CompareValue,

+  IN      UINT32                    ExchangeValue

+  )

+{

+  return _InterlockedCompareExchange (Value, ExchangeValue, CompareValue);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm
new file mode 100644
index 0000000..b5bcd25
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.asm
@@ -0,0 +1,41 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedCompareExchange64.Asm

+;

+; Abstract:

+;

+;   InterlockedCompareExchange64 function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT64

+; EFIAPI

+; InterlockedCompareExchange64 (

+;   IN      UINT64                    *Value,

+;   IN      UINT64                    CompareValue,

+;   IN      UINT64                    ExchangeValue

+;   );

+;------------------------------------------------------------------------------

+InternalSyncCompareExchange64   PROC

+    mov     rax, rdx

+    lock    cmpxchg [rcx], r8

+    ret

+InternalSyncCompareExchange64   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c
new file mode 100644
index 0000000..56805b3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange64.c
@@ -0,0 +1,53 @@
+/** @file

+  InterlockedCompareExchange64 function

+

+  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.

+

+**/

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+__int64 _InterlockedCompareExchange64(

+   __int64 volatile * Destination,

+   __int64 Exchange,

+   __int64 Comperand

+);

+

+#pragma intrinsic(_InterlockedCompareExchange64)

+

+/**

+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.

+

+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified

+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and

+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.

+  The compare exchange operation must be performed using MP safe mechanisms.

+

+  @param  Value         A pointer to the 64-bit value for the compare exchange

+                        operation.

+  @param  CompareValue  64-bit value used in compare operation.

+  @param  ExchangeValue 64-bit value used in exchange operation.

+

+  @return The original *Value before exchange.

+

+**/

+UINT64

+EFIAPI

+InternalSyncCompareExchange64 (

+  IN      UINT64                    *Value,

+  IN      UINT64                    CompareValue,

+  IN      UINT64                    ExchangeValue

+  )

+{

+  return _InterlockedCompareExchange64 (Value, ExchangeValue, CompareValue);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm
new file mode 100644
index 0000000..fdea0d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedDecrement.Asm

+;

+; Abstract:

+;

+;   InterlockedDecrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedDecrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncDecrement   PROC

+    lock    dec     dword ptr [rcx]

+    mov     eax, [rcx]

+    ret

+InternalSyncDecrement   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c
new file mode 100644
index 0000000..65faf01
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedDecrement.c
@@ -0,0 +1,46 @@
+/** @file

+  InterlockedDecrement function

+

+  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.

+

+**/

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+long _InterlockedDecrement(

+   long * lpAddend

+);

+

+#pragma intrinsic(_InterlockedDecrement)

+

+/**

+  Performs an atomic decrement of an 32-bit unsigned integer.

+

+  Performs an atomic decrement of the 32-bit unsigned integer specified by

+  Value and returns the decrement value. The decrement operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to decrement.

+

+  @return The decrement value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncDecrement (

+  IN      UINT32                    *Value

+  )

+{

+  return _InterlockedDecrement (Value);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm
new file mode 100644
index 0000000..65abcf7
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.asm
@@ -0,0 +1,39 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2006, 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.

+;

+; Module Name:

+;

+;   InterlockedIncrement.Asm

+;

+; Abstract:

+;

+;   InterlockedIncrement function

+;

+; Notes:

+;

+;------------------------------------------------------------------------------

+

+    .code

+

+;------------------------------------------------------------------------------

+; UINT32

+; EFIAPI

+; InterlockedIncrement (

+;   IN      UINT32                    *Value

+;   );

+;------------------------------------------------------------------------------

+InternalSyncIncrement   PROC

+    lock    inc     dword ptr [rcx]

+    mov     eax, [rcx]

+    ret

+InternalSyncIncrement   ENDP

+

+    END

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c
new file mode 100644
index 0000000..c0deb60
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedIncrement.c
@@ -0,0 +1,46 @@
+/** @file

+  InterLockedIncrement function

+

+  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.

+

+**/

+

+/**

+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.

+**/

+

+long _InterlockedIncrement(

+   long * lpAddend

+);

+

+#pragma intrinsic(_InterlockedIncrement)

+

+/**

+  Performs an atomic increment of an 32-bit unsigned integer.

+

+  Performs an atomic increment of the 32-bit unsigned integer specified by

+  Value and returns the incremented value. The increment operation must be

+  performed using MP safe mechanisms. The state of the return value is not

+  guaranteed to be MP safe.

+

+  @param  Value A pointer to the 32-bit value to increment.

+

+  @return The incremented value.

+

+**/

+UINT32

+EFIAPI

+InternalSyncIncrement (

+  IN      UINT32                    *Value

+  )

+{

+  return _InterlockedIncrement (Value);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf b/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
new file mode 100644
index 0000000..e72abdd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
@@ -0,0 +1,45 @@
+## @file

+#  NULL instance of Timer Library as a template.

+#

+#  A non-functional instance of the Timer Library that can be used as a template

+#  for the implementation of a functional timer library instance. This library instance can

+#  also be used to test build DXE, Runtime, DXE SAL, and DXE SMM modules that require timer

+#  services as well as EBC modules that require timer services.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseTimerLibNullTemplate

+  MODULE_UNI_FILE                = BaseTimerLibNullTemplate.uni

+  FILE_GUID                      = f4731d79-537e-4505-bd52-c03f9b1f6b89

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = TimerLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  TimerLibNull.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.uni b/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.uni
new file mode 100644
index 0000000..dfd8d40
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/TimerLibNull.c b/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/TimerLibNull.c
new file mode 100644
index 0000000..d06cd0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseTimerLibNullTemplate/TimerLibNull.c
@@ -0,0 +1,134 @@
+/** @file

+  A non-functional instance of the Timer Library.

+

+  Copyright (c) 2007 - 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

+  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 <Base.h>

+#include <Library/TimerLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return The value of MicroSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  ASSERT (FALSE);

+  return MicroSeconds;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return The value of NanoSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  The counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  OUT      UINT64                    *StartValue,  OPTIONAL

+  OUT      UINT64                    *EndValue     OPTIONAL

+  )

+{

+  ASSERT (FALSE);

+

+  return (UINT64)(-1);

+}

+

+/**

+  Converts elapsed ticks of performance counter to time in nanoseconds.

+

+  This function converts the elapsed ticks of running performance counter to

+  time value in unit of nanoseconds.

+

+  @param  Ticks     The number of elapsed ticks of running performance counter.

+

+  @return The elapsed time in nanoseconds.

+

+**/

+UINT64

+EFIAPI

+GetTimeInNanoSecond (

+  IN      UINT64                     Ticks

+  )

+{

+  ASSERT (FALSE);

+  return 0;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
new file mode 100644
index 0000000..e59a9de
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.c
@@ -0,0 +1,803 @@
+/** @file

+  UEFI Decompress Library implementation refer to UEFI specification.

+

+  Copyright (c) 2006 - 2014, 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.

+

+**/

+

+

+#include <Base.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiDecompressLib.h>

+

+#include "BaseUefiDecompressLibInternals.h"

+

+/**

+  Read NumOfBit of bits from source into mBitBuf.

+

+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.

+

+  @param  Sd        The global scratch data.

+  @param  NumOfBits The number of bits to shift and read.

+

+**/

+VOID

+FillBuf (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+{

+  //

+  // Left shift NumOfBits of bits in advance

+  //

+  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);

+

+  //

+  // Copy data needed in bytes into mSbuBitBuf

+  //

+  while (NumOfBits > Sd->mBitCount) {

+

+    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));

+

+    if (Sd->mCompSize > 0) {

+      //

+      // Get 1 byte into SubBitBuf

+      //

+      Sd->mCompSize--;

+      Sd->mSubBitBuf  = Sd->mSrcBase[Sd->mInBuf++];

+      Sd->mBitCount   = 8;

+

+    } else {

+      //

+      // No more bits from the source, just pad zero bit.

+      //

+      Sd->mSubBitBuf  = 0;

+      Sd->mBitCount   = 8;

+

+    }

+  }

+

+  //

+  // Caculate additional bit count read to update mBitCount

+  //

+  Sd->mBitCount = (UINT16) (Sd->mBitCount - NumOfBits);

+  

+  //

+  // Copy NumOfBits of bits from mSubBitBuf into mBitBuf

+  //

+  Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;

+}

+

+/**

+  Get NumOfBits of bits out from mBitBuf.

+

+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent

+  NumOfBits of bits from source. Returns NumOfBits of bits that are

+  popped out.

+

+  @param  Sd        The global scratch data.

+  @param  NumOfBits The number of bits to pop and read.

+

+  @return The bits that are popped out.

+

+**/

+UINT32

+GetBits (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  )

+{

+  UINT32  OutBits;

+

+  //

+  // Pop NumOfBits of Bits from Left

+  //  

+  OutBits = (UINT32) (Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));

+

+  //

+  // Fill up mBitBuf from source

+  //

+  FillBuf (Sd, NumOfBits);

+

+  return OutBits;

+}

+

+/**

+  Creates Huffman Code mapping table according to code length array.

+

+  Creates Huffman Code mapping table for Extra Set, Char&Len Set

+  and Position Set according to code length array.

+  If TableBits > 16, then ASSERT ().

+

+  @param  Sd        The global scratch data.

+  @param  NumOfChar The number of symbols in the symbol set.

+  @param  BitLen    Code length array.

+  @param  TableBits The width of the mapping table.

+  @param  Table     The table to be created.

+

+  @retval  0 OK.

+  @retval  BAD_TABLE The table is corrupted.

+

+**/

+UINT16

+MakeTable (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfChar,

+  IN  UINT8         *BitLen,

+  IN  UINT16        TableBits,

+  OUT UINT16        *Table

+  )

+{

+  UINT16  Count[17];

+  UINT16  Weight[17];

+  UINT16  Start[18];

+  UINT16  *Pointer;

+  UINT16  Index3;

+  UINT16  Index;

+  UINT16  Len;

+  UINT16  Char;

+  UINT16  JuBits;

+  UINT16  Avail;

+  UINT16  NextCode;

+  UINT16  Mask;

+  UINT16  WordOfStart;

+  UINT16  WordOfCount;

+

+  //

+  // The maximum mapping table width supported by this internal

+  // working function is 16.

+  //

+  ASSERT (TableBits <= 16);

+

+  for (Index = 0; Index <= 16; Index++) {

+    Count[Index] = 0;

+  }

+

+  for (Index = 0; Index < NumOfChar; Index++) {

+    Count[BitLen[Index]]++;

+  }

+  

+  Start[0] = 0;

+  Start[1] = 0;

+

+  for (Index = 1; Index <= 16; Index++) {

+    WordOfStart = Start[Index];

+    WordOfCount = Count[Index];

+    Start[Index + 1] = (UINT16) (WordOfStart + (WordOfCount << (16 - Index)));

+  }

+

+  if (Start[17] != 0) {

+    /*(1U << 16)*/

+    return (UINT16) BAD_TABLE;

+  }

+

+  JuBits = (UINT16) (16 - TableBits);

+  

+  Weight[0] = 0;

+  for (Index = 1; Index <= TableBits; Index++) {

+    Start[Index] >>= JuBits;

+    Weight[Index] = (UINT16) (1U << (TableBits - Index));

+  }

+

+  while (Index <= 16) {

+    Weight[Index] = (UINT16) (1U << (16 - Index));

+    Index++;    

+  }

+

+  Index = (UINT16) (Start[TableBits + 1] >> JuBits);

+

+  if (Index != 0) {

+    Index3 = (UINT16) (1U << TableBits);

+    if (Index < Index3) {

+      SetMem16 (Table + Index, (Index3 - Index) * sizeof (*Table), 0);

+    }

+  }

+

+  Avail = NumOfChar;

+  Mask  = (UINT16) (1U << (15 - TableBits));

+

+  for (Char = 0; Char < NumOfChar; Char++) {

+

+    Len = BitLen[Char];

+    if (Len == 0 || Len >= 17) {

+      continue;

+    }

+

+    NextCode = (UINT16) (Start[Len] + Weight[Len]);

+

+    if (Len <= TableBits) {

+

+      for (Index = Start[Len]; Index < NextCode; Index++) {

+        Table[Index] = Char;

+      }

+

+    } else {

+

+      Index3  = Start[Len];

+      Pointer = &Table[Index3 >> JuBits];

+      Index   = (UINT16) (Len - TableBits);

+

+      while (Index != 0) {

+        if (*Pointer == 0 && Avail < (2 * NC - 1)) {

+          Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;

+          *Pointer = Avail++;

+        }

+        

+        if (*Pointer < (2 * NC - 1)) {

+          if ((Index3 & Mask) != 0) {

+            Pointer = &Sd->mRight[*Pointer];

+          } else {

+            Pointer = &Sd->mLeft[*Pointer];

+          }

+        }

+

+        Index3 <<= 1;

+        Index--;

+      }

+

+      *Pointer = Char;

+

+    }

+

+    Start[Len] = NextCode;

+  }

+  //

+  // Succeeds

+  //

+  return 0;

+}

+

+/**

+  Decodes a position value.

+

+  Get a position value according to Position Huffman Table.

+

+  @param  Sd The global scratch data.

+

+  @return The position value decoded.

+

+**/

+UINT32

+DecodeP (

+  IN  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  Val;

+  UINT32  Mask;

+  UINT32  Pos;

+

+  Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+

+  if (Val >= MAXNP) {

+    Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+    do {

+

+      if ((Sd->mBitBuf & Mask) != 0) {

+        Val = Sd->mRight[Val];

+      } else {

+        Val = Sd->mLeft[Val];

+      }

+

+      Mask >>= 1;

+    } while (Val >= MAXNP);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mPTLen[Val]);

+

+  Pos = Val;

+  if (Val > 1) {

+    Pos = (UINT32) ((1U << (Val - 1)) + GetBits (Sd, (UINT16) (Val - 1)));

+  }

+

+  return Pos;

+}

+

+/**

+  Reads code lengths for the Extra Set or the Position Set.

+

+  Read in the Extra Set or Pointion Set Length Arrary, then

+  generate the Huffman code mapping for them.

+

+  @param  Sd      The global scratch data.

+  @param  nn      The number of symbols.

+  @param  nbit    The number of bits needed to represent nn.

+  @param  Special The special symbol that needs to be taken care of.

+

+  @retval  0 OK.

+  @retval  BAD_TABLE Table is corrupted.

+

+**/

+UINT16

+ReadPTLen (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        nn,

+  IN  UINT16        nbit,

+  IN  UINT16        Special

+  )

+{

+  UINT16  Number;

+  UINT16  CharC;

+  UINT16  Index;

+  UINT32  Mask;

+

+  ASSERT (nn <= NPT);

+  //

+  // Read Extra Set Code Length Array size 

+  //

+  Number = (UINT16) GetBits (Sd, nbit);

+

+  if (Number == 0) {

+    //

+    // This represents only Huffman code used

+    //

+    CharC = (UINT16) GetBits (Sd, nbit);

+

+    SetMem16 (&Sd->mPTTable[0] , sizeof (Sd->mPTTable), CharC);

+

+    SetMem (Sd->mPTLen, nn, 0);

+

+    return 0;

+  }

+

+  Index = 0;

+

+  while (Index < Number && Index < NPT) {

+

+    CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));

+

+    //

+    // If a code length is less than 7, then it is encoded as a 3-bit

+    // value. Or it is encoded as a series of "1"s followed by a 

+    // terminating "0". The number of "1"s = Code length - 4.

+    //

+    if (CharC == 7) {

+      Mask = 1U << (BITBUFSIZ - 1 - 3);

+      while (Mask & Sd->mBitBuf) {

+        Mask >>= 1;

+        CharC += 1;

+      }

+    }

+    

+    FillBuf (Sd, (UINT16) ((CharC < 7) ? 3 : CharC - 3));

+

+    Sd->mPTLen[Index++] = (UINT8) CharC;

+ 

+    //

+    // For Code&Len Set, 

+    // After the third length of the code length concatenation,

+    // a 2-bit value is used to indicated the number of consecutive 

+    // zero lengths after the third length.

+    //

+    if (Index == Special) {

+      CharC = (UINT16) GetBits (Sd, 2);

+      while ((INT16) (--CharC) >= 0 && Index < NPT) {

+        Sd->mPTLen[Index++] = 0;

+      }

+    }

+  }

+

+  while (Index < nn && Index < NPT) {

+    Sd->mPTLen[Index++] = 0;

+  }

+  

+  return MakeTable (Sd, nn, Sd->mPTLen, 8, Sd->mPTTable);

+}

+

+/**

+  Reads code lengths for Char&Len Set.

+

+  Read in and decode the Char&Len Set Code Length Array, then

+  generate the Huffman Code mapping table for the Char&Len Set.

+

+  @param  Sd The global scratch data.

+

+**/

+VOID

+ReadCLen (

+  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16           Number;

+  UINT16           CharC;

+  UINT16           Index;

+  UINT32           Mask;

+

+  Number = (UINT16) GetBits (Sd, CBIT);

+

+  if (Number == 0) {

+    //

+    // This represents only Huffman code used

+    //

+    CharC = (UINT16) GetBits (Sd, CBIT);

+

+    SetMem (Sd->mCLen, NC, 0);

+    SetMem16 (&Sd->mCTable[0], sizeof (Sd->mCTable), CharC);

+

+    return ;

+  }

+

+  Index = 0;

+  while (Index < Number && Index < NC) {

+    CharC = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];

+    if (CharC >= NT) {

+      Mask = 1U << (BITBUFSIZ - 1 - 8);

+

+      do {

+

+        if (Mask & Sd->mBitBuf) {

+          CharC = Sd->mRight[CharC];

+        } else {

+          CharC = Sd->mLeft[CharC];

+        }

+

+        Mask >>= 1;

+

+      } while (CharC >= NT);

+    }

+    //

+    // Advance what we have read

+    //

+    FillBuf (Sd, Sd->mPTLen[CharC]);

+

+    if (CharC <= 2) {

+

+      if (CharC == 0) {

+        CharC = 1;

+      } else if (CharC == 1) {

+        CharC = (UINT16) (GetBits (Sd, 4) + 3);

+      } else if (CharC == 2) {

+        CharC = (UINT16) (GetBits (Sd, CBIT) + 20);

+      }

+

+      while ((INT16) (--CharC) >= 0 && Index < NC) {

+        Sd->mCLen[Index++] = 0;

+      }

+

+    } else {

+

+      Sd->mCLen[Index++] = (UINT8) (CharC - 2);

+

+    }

+  }

+

+  SetMem (Sd->mCLen + Index, NC - Index, 0);

+

+  MakeTable (Sd, NC, Sd->mCLen, 12, Sd->mCTable);

+

+  return ;

+}

+

+/**

+  Decode a character/length value.

+

+  Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates

+  Huffman code mapping table for Extra Set, Code&Len Set and

+  Position Set.

+

+  @param  Sd The global scratch data.

+

+  @return The value decoded.

+

+**/

+UINT16

+DecodeC (

+  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  Index2;

+  UINT32  Mask;

+

+  if (Sd->mBlockSize == 0) {

+    //

+    // Starting a new block

+    // Read BlockSize from block header

+    // 

+    Sd->mBlockSize    = (UINT16) GetBits (Sd, 16);

+

+    //

+    // Read in the Extra Set Code Length Arrary,

+    // Generate the Huffman code mapping table for Extra Set.

+    //

+    Sd->mBadTableFlag = ReadPTLen (Sd, NT, TBIT, 3);

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+

+    //

+    // Read in and decode the Char&Len Set Code Length Arrary,

+    // Generate the Huffman code mapping table for Char&Len Set.

+    //

+    ReadCLen (Sd);

+

+    //

+    // Read in the Position Set Code Length Arrary, 

+    // Generate the Huffman code mapping table for the Position Set.

+    //

+    Sd->mBadTableFlag = ReadPTLen (Sd, MAXNP, Sd->mPBit, (UINT16) (-1));

+    if (Sd->mBadTableFlag != 0) {

+      return 0;

+    }

+  }

+

+  //

+  // Get one code according to Code&Set Huffman Table

+  //

+  Sd->mBlockSize--;

+  Index2 = Sd->mCTable[Sd->mBitBuf >> (BITBUFSIZ - 12)];

+

+  if (Index2 >= NC) {

+    Mask = 1U << (BITBUFSIZ - 1 - 12);

+

+    do {

+      if ((Sd->mBitBuf & Mask) != 0) {

+        Index2 = Sd->mRight[Index2];

+      } else {

+        Index2 = Sd->mLeft[Index2];

+      }

+

+      Mask >>= 1;

+    } while (Index2 >= NC);

+  }

+  //

+  // Advance what we have read

+  //

+  FillBuf (Sd, Sd->mCLen[Index2]);

+

+  return Index2;

+}

+

+/**

+  Decode the source data and put the resulting data into the destination buffer.

+

+  @param  Sd The global scratch data.

+

+**/

+VOID

+Decode (

+  SCRATCH_DATA  *Sd

+  )

+{

+  UINT16  BytesRemain;

+  UINT32  DataIdx;

+  UINT16  CharC;

+

+  BytesRemain = (UINT16) (-1);

+

+  DataIdx     = 0;

+

+  for (;;) {

+    //

+    // Get one code from mBitBuf

+    // 

+    CharC = DecodeC (Sd);

+    if (Sd->mBadTableFlag != 0) {

+      goto Done;

+    }

+

+    if (CharC < 256) {

+      //

+      // Process an Original character

+      //

+      if (Sd->mOutBuf >= Sd->mOrigSize) {

+        goto Done;

+      } else {

+        //

+        // Write orignal character into mDstBase

+        //

+        Sd->mDstBase[Sd->mOutBuf++] = (UINT8) CharC;

+      }

+

+    } else {

+      //

+      // Process a Pointer

+      //

+      CharC       = (UINT16) (CharC - (BIT8 - THRESHOLD));

+ 

+      //

+      // Get string length

+      //

+      BytesRemain = CharC;

+

+      //

+      // Locate string position

+      //

+      DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;

+

+      //

+      // Write BytesRemain of bytes into mDstBase

+      //

+      BytesRemain--;

+      while ((INT16) (BytesRemain) >= 0) {

+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];

+        if (Sd->mOutBuf >= Sd->mOrigSize) {

+          goto Done;

+        }

+

+        BytesRemain--;

+      }

+    }

+  }

+

+Done:

+  return ;

+}

+

+/**

+  Given a compressed source buffer, this function retrieves the size of 

+  the uncompressed buffer and the size of the scratch buffer required 

+  to decompress the compressed source buffer.

+

+  Retrieves the size of the uncompressed buffer and the temporary scratch buffer 

+  required to decompress the buffer specified by Source and SourceSize.

+  If the size of the uncompressed buffer or the size of the scratch buffer cannot

+  be determined from the compressed data specified by Source and SourceData, 

+  then RETURN_INVALID_PARAMETER is returned.  Otherwise, the size of the uncompressed

+  buffer is returned in DestinationSize, the size of the scratch buffer is returned

+  in ScratchSize, and RETURN_SUCCESS is returned.

+  This function does not have scratch buffer available to perform a thorough 

+  checking of the validity of the source data.  It just retrieves the "Original Size"

+  field from the beginning bytes of the source data and output it as DestinationSize.

+  And ScratchSize is specific to the decompression implementation.

+

+  If Source is NULL, then ASSERT().

+  If DestinationSize is NULL, then ASSERT().

+  If ScratchSize is NULL, then ASSERT().

+

+  @param  Source          The source buffer containing the compressed data.

+  @param  SourceSize      The size, in bytes, of the source buffer.

+  @param  DestinationSize A pointer to the size, in bytes, of the uncompressed buffer

+                          that will be generated when the compressed buffer specified

+                          by Source and SourceSize is decompressed.

+  @param  ScratchSize     A pointer to the size, in bytes, of the scratch buffer that

+                          is required to decompress the compressed buffer specified 

+                          by Source and SourceSize.

+

+  @retval  RETURN_SUCCESS The size of the uncompressed data was returned 

+                          in DestinationSize, and the size of the scratch 

+                          buffer was returned in ScratchSize.

+  @retval  RETURN_INVALID_PARAMETER 

+                          The size of the uncompressed data or the size of 

+                          the scratch buffer cannot be determined from 

+                          the compressed data specified by Source 

+                          and SourceSize.

+**/

+RETURN_STATUS

+EFIAPI

+UefiDecompressGetInfo (

+  IN  CONST VOID  *Source,

+  IN  UINT32      SourceSize,

+  OUT UINT32      *DestinationSize,

+  OUT UINT32      *ScratchSize

+  )

+{

+  UINT32  CompressedSize;

+

+  ASSERT (Source != NULL);

+  ASSERT (DestinationSize != NULL);

+  ASSERT (ScratchSize != NULL);

+

+  if (SourceSize < 8) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  CompressedSize   = ReadUnaligned32 ((UINT32 *)Source);

+  if (SourceSize < (CompressedSize + 8)) {

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  *ScratchSize  = sizeof (SCRATCH_DATA);

+  *DestinationSize = ReadUnaligned32 ((UINT32 *)Source + 1);

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Decompresses a compressed source buffer.

+

+  Extracts decompressed data to its original form.

+  This function is designed so that the decompression algorithm can be implemented

+  without using any memory services.  As a result, this function is not allowed to

+  call any memory allocation services in its implementation.  It is the caller's 

+  responsibility to allocate and free the Destination and Scratch buffers.

+  If the compressed source data specified by Source is successfully decompressed 

+  into Destination, then RETURN_SUCCESS is returned.  If the compressed source data 

+  specified by Source is not in a valid compressed data format,

+  then RETURN_INVALID_PARAMETER is returned.

+

+  If Source is NULL, then ASSERT().

+  If Destination is NULL, then ASSERT().

+  If the required scratch buffer size > 0 and Scratch is NULL, then ASSERT().

+

+  @param  Source      The source buffer containing the compressed data.

+  @param  Destination The destination buffer to store the decompressed data.

+  @param  Scratch     A temporary scratch buffer that is used to perform the decompression.

+                      This is an optional parameter that may be NULL if the 

+                      required scratch buffer size is 0.

+                     

+  @retval  RETURN_SUCCESS Decompression completed successfully, and 

+                          the uncompressed buffer is returned in Destination.

+  @retval  RETURN_INVALID_PARAMETER 

+                          The source buffer specified by Source is corrupted 

+                          (not in a valid compressed format).

+**/

+RETURN_STATUS

+EFIAPI

+UefiDecompress (

+  IN CONST VOID  *Source,

+  IN OUT VOID    *Destination,

+  IN OUT VOID    *Scratch  OPTIONAL

+  )

+{

+  UINT32           CompSize;

+  UINT32           OrigSize;

+  SCRATCH_DATA     *Sd;

+  CONST UINT8      *Src;

+  UINT8            *Dst;

+

+  ASSERT (Source != NULL);

+  ASSERT (Destination != NULL);

+  ASSERT (Scratch != NULL);

+

+  Src     = Source;

+  Dst     = Destination;

+

+  Sd = (SCRATCH_DATA *) Scratch;

+

+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);

+  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);

+

+  //

+  // If compressed file size is 0, return

+  //

+  if (OrigSize == 0) {

+    return RETURN_SUCCESS;

+  }

+

+  Src = Src + 8;

+  SetMem (Sd, sizeof (SCRATCH_DATA), 0);

+

+  //

+  // The length of the field 'Position Set Code Length Array Size' in Block Header.

+  // For UEFI 2.0 de/compression algorithm(Version 1), mPBit = 4

+  //

+  Sd->mPBit     = 4;

+  Sd->mSrcBase  = (UINT8 *)Src;

+  Sd->mDstBase  = Dst;

+  //

+  // CompSize and OrigSize are caculated in bytes

+  //

+  Sd->mCompSize = CompSize;

+  Sd->mOrigSize = OrigSize;

+

+  //

+  // Fill the first BITBUFSIZ bits

+  //

+  FillBuf (Sd, BITBUFSIZ);

+

+  //

+  // Decompress it

+  //

+  Decode (Sd);

+

+  if (Sd->mBadTableFlag != 0) {

+    //

+    // Something wrong with the source

+    //

+    return RETURN_INVALID_PARAMETER;

+  }

+

+  return RETURN_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
new file mode 100644
index 0000000..36d7a24
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
@@ -0,0 +1,43 @@
+## @file

+#  UEFI Decompress Library implementation.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = BaseUefiDecompressLib

+  MODULE_UNI_FILE                = BaseUefiDecompressLib.uni

+  FILE_GUID                      = 9ae5147d-b240-467f-a484-b024fdc42ee0

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiDecompressLib 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  BaseUefiDecompressLibInternals.h

+  BaseUefiDecompressLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  BaseMemoryLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.uni b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.uni
new file mode 100644
index 0000000..bbf835e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLibInternals.h
new file mode 100644
index 0000000..358c598
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLibInternals.h
@@ -0,0 +1,211 @@
+/** @file

+  Internal data structure defintions for Base UEFI Decompress Libary.

+

+  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 __BASE_UEFI_DECOMPRESS_LIB_INTERNALS_H__

+#define __BASE_UEFI_DECOMPRESS_LIB_INTERNALS_H__

+

+//

+// Decompression algorithm begins here

+//

+#define BITBUFSIZ 32

+#define MAXMATCH  256

+#define THRESHOLD 3

+#define CODE_BIT  16

+#define BAD_TABLE - 1

+

+//

+// C: Char&Len Set; P: Position Set; T: exTra Set

+//

+#define NC      (0xff + MAXMATCH + 2 - THRESHOLD)

+#define CBIT    9

+#define MAXPBIT 5

+#define TBIT    5

+#define MAXNP   ((1U << MAXPBIT) - 1)

+#define NT      (CODE_BIT + 3)

+#if NT > MAXNP

+#define NPT NT

+#else

+#define NPT MAXNP

+#endif

+

+typedef struct {

+  UINT8   *mSrcBase;  // The starting address of compressed data

+  UINT8   *mDstBase;  // The starting address of decompressed data

+  UINT32  mOutBuf;

+  UINT32  mInBuf;

+

+  UINT16  mBitCount;

+  UINT32  mBitBuf;

+  UINT32  mSubBitBuf;

+  UINT16  mBlockSize;

+  UINT32  mCompSize;

+  UINT32  mOrigSize;

+

+  UINT16  mBadTableFlag;

+

+  UINT16  mLeft[2 * NC - 1];

+  UINT16  mRight[2 * NC - 1];

+  UINT8   mCLen[NC];

+  UINT8   mPTLen[NPT];

+  UINT16  mCTable[4096];

+  UINT16  mPTTable[256];

+

+  ///

+  /// The length of the field 'Position Set Code Length Array Size' in Block Header.

+  /// For UEFI 2.0 de/compression algorithm, mPBit = 4.

+  ///

+  UINT8   mPBit;

+} SCRATCH_DATA;

+

+/**

+  Read NumOfBit of bits from source into mBitBuf.

+

+  Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.

+

+  @param  Sd        The global scratch data.

+  @param  NumOfBits The number of bits to shift and read.

+

+**/

+VOID

+FillBuf (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  );

+

+/**

+  Get NumOfBits of bits out from mBitBuf.

+

+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent

+  NumOfBits of bits from source. Returns NumOfBits of bits that are

+  popped out.

+

+  @param  Sd        The global scratch data.

+  @param  NumOfBits The number of bits to pop and read.

+

+  @return The bits that are popped out.

+

+**/

+UINT32

+GetBits (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfBits

+  );

+

+/**

+  Creates Huffman Code mapping table according to code length array.

+

+  Creates Huffman Code mapping table for Extra Set, Char&Len Set

+  and Position Set according to code length array.

+  If TableBits > 16, then ASSERT ().

+

+  @param  Sd        The global scratch data.

+  @param  NumOfChar The number of symbols in the symbol set.

+  @param  BitLen    Code length array.

+  @param  TableBits The width of the mapping table.

+  @param  Table     The table to be created.

+

+  @retval  0 OK.

+  @retval  BAD_TABLE The table is corrupted.

+

+**/

+UINT16

+MakeTable (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        NumOfChar,

+  IN  UINT8         *BitLen,

+  IN  UINT16        TableBits,

+  OUT UINT16        *Table

+  );

+

+/**

+  Decodes a position value.

+

+  Get a position value according to Position Huffman Table.

+

+  @param  Sd The global scratch data.

+

+  @return The position value decoded.

+

+**/

+UINT32

+DecodeP (

+  IN  SCRATCH_DATA  *Sd

+  );

+

+/**

+  Reads code lengths for the Extra Set or the Position Set.

+

+  Read in the Extra Set or Pointion Set Length Arrary, then

+  generate the Huffman code mapping for them.

+

+  @param  Sd      The global scratch data.

+  @param  nn      The number of symbols.

+  @param  nbit    The number of bits needed to represent nn.

+  @param  Special The special symbol that needs to be taken care of.

+

+  @retval  0 OK.

+  @retval  BAD_TABLE Table is corrupted.

+

+**/

+UINT16

+ReadPTLen (

+  IN  SCRATCH_DATA  *Sd,

+  IN  UINT16        nn,

+  IN  UINT16        nbit,

+  IN  UINT16        Special

+  );

+

+/**

+  Reads code lengths for Char&Len Set.

+

+  Read in and decode the Char&Len Set Code Length Array, then

+  generate the Huffman Code mapping table for the Char&Len Set.

+

+  @param  Sd The global scratch data.

+

+**/

+VOID

+ReadCLen (

+  SCRATCH_DATA  *Sd

+  );

+

+/**

+  Decode a character/length value.

+

+  Read one value from mBitBuf, Get one code from mBitBuf. If it is at block boundary, generates

+  Huffman code mapping table for Extra Set, Code&Len Set and

+  Position Set.

+

+  @param  Sd The global scratch data.

+

+  @return The value decoded.

+

+**/

+UINT16

+DecodeC (

+  SCRATCH_DATA  *Sd

+  );

+

+/**

+  Decode the source data and put the resulting data into the destination buffer.

+

+  @param  Sd The global scratch data.

+

+**/

+VOID

+Decode (

+  SCRATCH_DATA  *Sd

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c b/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c
new file mode 100644
index 0000000..d3d8c4c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.c
@@ -0,0 +1,79 @@
+/** @file

+  Entry point to the DXE Core.

+

+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.

+

+**/

+

+

+#include <PiDxe.h>

+

+

+#include <Library/DxeCoreEntryPoint.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+

+//

+// Cache copy of HobList pointer. 

+// 

+VOID *gHobList = NULL;

+

+/**

+  The entry point of PE/COFF Image for the DXE Core. 

+

+  This function is the entry point for the DXE Core. This function is required to call

+  ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.

+  The DXE Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI

+  System Table and the image handle for the DXE Core itself have been established.

+  If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.

+

+  @param  HobStart  The pointer to the beginning of the HOB List passed in from the PEI Phase. 

+

+**/

+VOID

+EFIAPI

+_ModuleEntryPoint (

+  IN VOID  *HobStart

+  )

+{

+  //

+  // Cache a pointer to the HobList

+  //

+  gHobList = HobStart;

+

+  //

+  // Call the DXE Core entry point

+  //

+  ProcessModuleEntryPointList (HobStart);

+

+  //

+  // Should never return

+  //

+  ASSERT(FALSE);

+  CpuDeadLoop ();

+}

+

+

+/**

+  Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().

+

+  This function is required to call _ModuleEntryPoint() passing in HobStart.

+

+  @param  HobStart  The pointer to the beginning of the HOB List passed in from the PEI Phase. 

+

+**/

+VOID

+EFIAPI

+EfiMain (

+  IN VOID  *HobStart

+  )

+{

+  _ModuleEntryPoint (HobStart);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf b/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
new file mode 100644
index 0000000..01f64c3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
@@ -0,0 +1,41 @@
+## @file

+# Module entry point library for DXE core.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeCoreEntryPoint

+  MODULE_UNI_FILE                = DxeCoreEntryPoint.uni

+  FILE_GUID                      = d258d6af-2fc0-4019-9c1f-1101c3dd19b5

+  MODULE_TYPE                    = DXE_CORE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DxeCoreEntryPoint|DXE_CORE 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  DxeCoreEntryPoint.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.uni b/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.uni
new file mode 100644
index 0000000..9d62486
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
new file mode 100644
index 0000000..ae48d92
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -0,0 +1,44 @@
+## @file

+# Instance of HOB Library for DXE Core.

+#

+# HOB Library implementation for the DXE Core. Does not have a constructor.

+#  Uses gHobList defined in the DXE Core Entry Point Library.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeCoreHobLib

+  MODULE_UNI_FILE                = DxeCoreHobLib.uni

+  FILE_GUID                      = 882ee1a3-35b2-412c-b8a2-7a8d34a7c390

+  MODULE_TYPE                    = DXE_CORE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = HobLib|DXE_CORE 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  HobLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  DebugLib

+  DxeCoreEntryPoint

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.uni
new file mode 100644
index 0000000..e414ad8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/HobLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/HobLib.c
new file mode 100644
index 0000000..ad66966
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeCoreHobLib/HobLib.c
@@ -0,0 +1,566 @@
+/** @file

+  HOB Library implementation for DxeCore driver.

+

+Copyright (c) 2006 - 2014, 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 <PiDxe.h>

+

+#include <Library/HobLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DxeCoreEntryPoint.h>

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+  For PEI phase, the PEI service GetHobList() can be used to retrieve the pointer 

+  to the HOB list.  For the DXE phase, the HOB list pointer can be retrieved through

+  the EFI System Table by looking up theHOB list GUID in the System Configuration Table.

+  Since the System Configuration Table does not exist that the time the DXE Core is 

+  launched, the DXE Core uses a global variable from the DXE Core Entry Point Library 

+  to manage the pointer to the HOB list.

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+  

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+{

+  ASSERT (gHobList != NULL);

+  return gHobList;

+}

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  ASSERT (HobStart != NULL);

+

+  Hob.Raw = (UINT8 *) HobStart;

+  //

+  // Parse the HOB list until end of list or matching type is found.

+  //

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == Type) {

+      return Hob.Raw;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return NULL;

+}

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextHob (Type, HobList);

+}

+

+/**

+  Returns the next instance of the matched GUID HOB from the starting HOB.

+  

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION, and its GUID Name equals to the input Guid. 

+  If such a HOB from the starting HOB pointer does not exist, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size information, respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  GuidHob;

+

+  GuidHob.Raw = (UINT8 *) HobStart;

+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {

+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+  return GuidHob.Raw;

+}

+

+/**

+  Returns the first instance of the matched GUID HOB among the whole HOB list.

+  

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If such a HOB from the starting HOB pointer does not exist, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size information, respectively.

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextGuidHob (Guid, HobList);

+}

+

+/**

+  Get the system boot mode from the HOB list.

+

+  This function returns the system boot mode information from the 

+  PHIT HOB in HOB list.

+

+  If the pointer to the HOB list is NULL, then ASSERT().

+  

+  @param  VOID

+

+  @return The Boot Mode.

+

+**/

+EFI_BOOT_MODE

+EFIAPI

+GetBootModeHob (

+  VOID

+  )

+{

+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;

+

+  HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();

+

+  return  HandOffHob->BootMode;

+}

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the module entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory with Owner GUID.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+  @param  OwnerGUID           GUID for the owner of this resource.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorWithOwnerHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes,

+  IN EFI_GUID                     *OwnerGUID

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a customized HOB tagged with a GUID for identification and returns 

+  the start address of GUID HOB data.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase.

+  For DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().

+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @retval  NULL         The GUID HOB could not be allocated.

+  @retval  others       The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Builds a customized HOB tagged with a GUID for identification, copies the input data to the HOB 

+  data field, and returns the start address of the GUID HOB data.

+

+  This function builds a customized HOB tagged with a GUID for identification and copies the input

+  data to the HOB data field and returns the start address of the GUID HOB data.  It can only be 

+  invoked during PEI phase; for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.  

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase.

+  For DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().

+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @retval  NULL         The GUID HOB could not be allocated.

+  @retval  others       The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a EFI_HOB_TYPE_FV2 HOB.

+

+  This function builds a EFI_HOB_TYPE_FV2 HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+  @param  FvName        The name of the Firmware Volume.

+  @param  FileName      The name of the file.

+  

+**/

+VOID

+EFIAPI

+BuildFv2Hob (

+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN          UINT64                      Length,

+  IN CONST    EFI_GUID                    *FvName,

+  IN CONST    EFI_GUID                    *FileName

+  )

+{

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If the platform does not support Capsule Volume HOBs, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() because PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf
new file mode 100644
index 0000000..2c4e28b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.inf
@@ -0,0 +1,46 @@
+## @file

+#  The library implements the Extended SAL Library Class for boot service only modules.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeExtendedSalLib

+  MODULE_UNI_FILE                = DxeExtendedSalLib.uni

+  FILE_GUID                      = 8FDED21D-7AB5-4c26-8CF7-20EC4DB9861D

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ExtendedSalLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION 

+  CONSTRUCTOR                    = DxeExtendedSalLibConstruct

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources.IPF]

+  ExtendedSalLib.c

+  Ipf/AsmExtendedSalLib.s

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+

+[Protocols]

+  gEfiExtendedSalBootServiceProtocolGuid        ## CONSUMES

+

+[Depex.common.DXE_DRIVER]

+  gEfiExtendedSalBootServiceProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.uni
new file mode 100644
index 0000000..7c407e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/DxeExtendedSalLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c
new file mode 100644
index 0000000..0f48c63
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/ExtendedSalLib.c
@@ -0,0 +1,1001 @@
+/** @file

+  The library implements the Extended SAL Library Class for boot service only modules.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/ExtendedSalBootService.h>

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/ExtendedSalLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Stores the physical plabel of ESAL entrypoint.

+

+  This assembly function stores the physical plabel of ESAL entrypoint

+  where GetEsalEntryPoint() can easily retrieve.

+

+  @param  EntryPoint  Physical address of ESAL entrypoint

+  @param  Gp          Physical GP of ESAL entrypoint

+

+  @return r8 = EFI_SAL_SUCCESS

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+SetEsalPhysicalEntryPoint (

+  IN  UINT64  EntryPoint,

+  IN  UINT64  Gp

+  );

+

+/**

+  Retrieves plabel of ESAL entrypoint.

+

+  This function retrives plabel of ESAL entrypoint stored by

+  SetEsalPhysicalEntryPoint().

+

+  @return r8  = EFI_SAL_SUCCESS

+          r9  = Physical Plabel

+          r10 = Virtual Plabel

+          r11 = PSR

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+GetEsalEntryPoint (

+  VOID

+  );

+

+EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;

+EFI_PLABEL                          mPlabel;

+

+/**

+  Constructor function to get Extended SAL Boot Service Protocol, and initializes

+  physical plabel of ESAL entrypoint.

+  

+  This function first locates Extended SAL Boot Service Protocol and caches it in global variable.

+  Then it initializes the physical plable of ESAL entrypoint, and stores

+  it where GetEsalEntryPoint() can easily retrieve.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeExtendedSalLibConstruct (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_PLABEL  *Plabel;

+  EFI_STATUS  Status;

+

+  //

+  // The protocol contains a function pointer, which is an indirect procedure call.

+  // An indirect procedure call goes through a plabel, and pointer to a function is

+  // a pointer to a plabel. To implement indirect procedure calls that can work in

+  // both physical and virtual mode, two plabels are required (one physical and one

+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it

+  // away. We cache it in a module global, so we can register the vitrual version.

+  //

+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);

+  ASSERT_EFI_ERROR (Status);

+

+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;

+  mPlabel.EntryPoint  = Plabel->EntryPoint;

+  mPlabel.GP          = Plabel->GP;

+  //

+  // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.

+  //

+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Registers function of ESAL class and it's associated global.

+  

+  This function registers function of ESAL class, together with its associated global.

+  It is worker function for RegisterEsalClass().

+  It is only for boot time.

+

+  @param  FunctionId     ID of function to register

+  @param  ClassGuidLo    GUID of ESAL class, lower 64-bits

+  @param  ClassGuidHi    GUID of ESAL class, upper 64-bits

+  @param  Function       Function to register with ClassGuid/FunctionId pair

+  @param  ModuleGlobal   Module global for the function.

+

+  @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol

+

+**/

+EFI_STATUS

+RegisterEsalFunction (

+  IN  UINT64                                    FunctionId,

+  IN  UINT64                                    ClassGuidLo,

+  IN  UINT64                                    ClassGuidHi,

+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,

+  IN  VOID                                      *ModuleGlobal

+  )

+{

+  return mEsalBootService->RegisterExtendedSalProc (

+                             mEsalBootService,

+                             ClassGuidLo,

+                             ClassGuidHi,

+                             FunctionId,

+                             Function,

+                             ModuleGlobal

+                             );

+}

+

+/**

+  Registers ESAL Class and it's associated global.

+  

+  This function registers one or more Extended SAL services in a given

+  class along with the associated global context.

+  This function is only available prior to ExitBootServices().

+

+  @param  ClassGuidLo          GUID of function class, lower 64-bits

+  @param  ClassGuidHi          GUID of function class, upper 64-bits

+  @param  ModuleGlobal         Module global for the class.

+  @param  ...                  List of Function/FunctionId pairs, ended by NULL

+  

+  @retval EFI_SUCCESS          The Extended SAL services were registered.

+  @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().

+  @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.

+  @retval Other                ClassGuid could not be installed onto a new handle.  

+

+**/

+EFI_STATUS

+EFIAPI

+RegisterEsalClass (

+  IN  CONST UINT64    ClassGuidLo,

+  IN  CONST UINT64    ClassGuidHi,

+  IN  VOID            *ModuleGlobal,  OPTIONAL

+  ...

+  )

+{

+  VA_LIST                         Args;

+  EFI_STATUS                      Status;

+  SAL_INTERNAL_EXTENDED_SAL_PROC  Function;

+  UINT64                          FunctionId;

+  EFI_HANDLE                      NewHandle;

+  EFI_GUID                        ClassGuid;

+

+  VA_START (Args, ModuleGlobal);

+

+  //

+  // Register all functions of the class to register.

+  //

+  Status = EFI_SUCCESS;

+  while (!EFI_ERROR (Status)) {

+    Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);

+    //

+    // NULL serves as the end mark of function list

+    //

+    if (Function == NULL) {

+      break;

+    }

+

+    FunctionId = VA_ARG (Args, UINT64);

+

+    Status = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);

+  }

+

+  VA_END (Args);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  NewHandle = NULL;

+  *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;

+  *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;

+  return gBS->InstallProtocolInterface (

+                &NewHandle,

+                &ClassGuid,

+                EFI_NATIVE_INTERFACE,

+                NULL

+                );

+}

+

+/**

+  Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().

+  

+  This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service

+  that was previously registered with RegisterEsalClass() through this entrypoint.

+

+  @param  ClassGuidLo     GUID of function, lower 64-bits

+  @param  ClassGuidHi     GUID of function, upper 64-bits

+  @param  FunctionId      Function in ClassGuid to call

+  @param  Arg2            Argument 2 ClassGuid/FunctionId defined

+  @param  Arg3            Argument 3 ClassGuid/FunctionId defined

+  @param  Arg4            Argument 4 ClassGuid/FunctionId defined

+  @param  Arg5            Argument 5 ClassGuid/FunctionId defined

+  @param  Arg6            Argument 6 ClassGuid/FunctionId defined

+  @param  Arg7            Argument 7 ClassGuid/FunctionId defined

+  @param  Arg8            Argument 8 ClassGuid/FunctionId defined

+  

+  @retval EFI_SAL_SUCCESS ESAL procedure successfully called.

+  @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly

+                          initialized.

+  @retval Other           Status returned from ExtendedSalProc() service of

+                          EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.  

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalCall (

+  IN UINT64  ClassGuidLo,

+  IN UINT64  ClassGuidHi,

+  IN UINT64  FunctionId,

+  IN UINT64  Arg2,

+  IN UINT64  Arg3,

+  IN UINT64  Arg4,

+  IN UINT64  Arg5,

+  IN UINT64  Arg6,

+  IN UINT64  Arg7,

+  IN UINT64  Arg8

+  )

+{

+  SAL_RETURN_REGS       ReturnReg;

+  EXTENDED_SAL_PROC     EsalProc;

+

+  //

+  // Get the entrypoint of Extended SAL

+  //

+  ReturnReg = GetEsalEntryPoint ();

+  if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {

+    //

+    // The ESAL Entry Point could not be initialized

+    //

+    ReturnReg.Status = EFI_SAL_ERROR;

+    return ReturnReg;

+  }

+

+  //

+  // Test PSR.it which is BIT36

+  //

+  if ((ReturnReg.r11 & BIT36) != 0) {

+    //

+    // Virtual mode plabel to entry point

+    //

+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;

+  } else {

+    //

+    // Physical mode plabel to entry point

+    //

+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;

+  }

+

+  return EsalProc (

+           ClassGuidLo,

+           ClassGuidHi,

+           FunctionId,

+           Arg2,

+           Arg3,

+           Arg4,

+           Arg5,

+           Arg6,

+           Arg7,

+           Arg8

+           );

+}

+

+/**

+  Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.

+  

+  This function is a wrapper for the EsalStallFunctionId service of Extended SAL

+  Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.

+

+  @param  Microseconds                  The number of microseconds to delay.

+

+  @retval EFI_SAL_SUCCESS               Call completed without error.

+  @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.

+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalStall (

+  IN UINTN  Microseconds

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO, 

+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI, 

+           StallFunctionId, 

+           Microseconds, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.

+  

+  This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL

+  PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.

+

+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.

+                                         If FALSE, then PalEntryPoint is a virtual address.

+  @param  PalEntryPoint                  The PAL Entry Point being set.

+

+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.

+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before

+                                         virtual mappings for the specified Extended SAL

+                                         Procedure are available.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalSetNewPalEntry (

+  IN BOOLEAN  PhysicalAddress,

+  IN UINT64   PalEntryPoint

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO, 

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,

+           SetNewPalEntryFunctionId, 

+           PhysicalAddress, 

+           PalEntryPoint, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.

+  

+  This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL

+  PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.

+

+  @param  PhysicalAddress                If TRUE, then PalEntryPoint is a physical address.

+                                         If FALSE, then PalEntryPoint is a virtual address.

+

+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in

+                                         SAL_RETURN_REGS.r9.

+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before

+                                         virtual mappings for the specified Extended SAL

+                                         Procedure are available.

+  @return r9                             PAL entry point retrieved.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetNewPalEntry (

+  IN BOOLEAN  PhysicalAddress

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,

+           GetNewPalEntryFunctionId, 

+           PhysicalAddress, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.

+  

+  This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL

+  MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.

+

+  @param  McaType               See type parameter of SAL Procedure SAL_GET_STATE_INFO.

+  @param  McaBuffer             A pointer to the base address of the returned buffer.

+                                Copied from SAL_RETURN_REGS.r9.

+  @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.

+                                Copied from SAL_RETURN_REGS.r10.

+

+  @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.

+  @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available

+  @return r9                    Base address of the returned buffer

+  @return r10                   Size of the returned buffer in bytes

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetStateBuffer (

+  IN  UINT64  McaType,

+  OUT UINT8   **McaBuffer,

+  OUT UINTN   *BufferSize

+  )

+{

+  SAL_RETURN_REGS Regs;

+

+  Regs = EsalCall (

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+           EsalGetStateBufferFunctionId, 

+           McaType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+

+  *McaBuffer  = (UINT8 *) Regs.r9;

+  *BufferSize = Regs.r10;

+

+  return Regs;

+}

+

+/**

+  Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.

+  

+  This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL

+  MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.

+

+  @param  McaType      See type parameter of SAL Procedure SAL_GET_STATE_INFO.

+

+  @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalSaveStateBuffer (

+  IN  UINT64  McaType

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+           EsalSaveStateBufferFunctionId, 

+           McaType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL

+  Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.

+

+  @param  VectorType               The vector type to retrieve.

+                                   0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.

+

+  @retval EFI_SAL_SUCCESS          Call completed without error.

+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.

+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered

+                                   with the SAL Procedure SAL_SET_VECTORS.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetVectors (

+  IN  UINT64  VectorType

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalGetVectorsFunctionId, 

+           VectorType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL

+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.

+

+  @param  ParamInfoType            The parameter type to retrieve.

+                                   1 - rendezvous interrupt

+                                   2 - wake up

+                                   3 - Corrected Platform Error Vector.

+

+  @retval EFI_SAL_SUCCESS          Call completed without error.

+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.

+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered

+                                   with the SAL Procedure SAL_MC_SET_PARAMS.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcGetParams (

+  IN  UINT64  ParamInfoType

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalMcGetParamsFunctionId, 

+           ParamInfoType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL

+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.

+

+  @retval EFI_SAL_SUCCESS          Call completed without error.

+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered

+                                   with the SAL Procedure SAL_MC_SET_PARAMS.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcGetMcParams (

+  VOID

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalMcGetMcParamsFunctionId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL

+  Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.

+

+  @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.

+

+  @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetMcCheckinFlags (

+  IN  UINT64  CpuIndex

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalGetMcCheckinFlagsFunctionId, 

+           CpuIndex, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL

+  MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId                 The Global ID for the CPU being added.

+  @param  Enabled                     The enable flag for the CPU being added.

+                                      TRUE means the CPU is enabled.

+                                      FALSE means the CPU is disabled.

+  @param  PalCompatibility            The PAL Compatibility value for the CPU being added.

+

+  @retval EFI_SAL_SUCCESS             The CPU was added to the database.

+  @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalAddCpuData (

+  IN UINT64   CpuGlobalId,

+  IN BOOLEAN  Enabled,

+  IN UINT64   PalCompatibility

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           AddCpuDataFunctionId, 

+           CpuGlobalId, 

+           Enabled, 

+           PalCompatibility, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL

+  MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId             The Global ID for the CPU being removed.

+

+  @retval EFI_SAL_SUCCESS         The CPU was removed from the database.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalRemoveCpuData (

+  IN UINT64  CpuGlobalId

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           RemoveCpuDataFunctionId, 

+           CpuGlobalId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL

+  MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId             The Global ID for the CPU being modified.

+  @param  Enabled                 The enable flag for the CPU being modified.

+                                  TRUE means the CPU is enabled.

+                                  FALSE means the CPU is disabled.

+  @param  PalCompatibility        The PAL Compatibility value for the CPU being modified.

+

+  @retval EFI_SAL_SUCCESS         The CPU database was updated.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalModifyCpuData (

+  IN UINT64   CpuGlobalId,

+  IN BOOLEAN  Enabled,

+  IN UINT64   PalCompatibility

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           ModifyCpuDataFunctionId, 

+           CpuGlobalId, 

+           Enabled, 

+           PalCompatibility, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL

+  MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId             The Global ID for the CPU being looked up.

+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.

+                                  If FALSE, then the index of set of all CPUs of database is returned.

+

+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetCpuDataById (

+  IN UINT64   CpuGlobalId,

+  IN BOOLEAN  IndexByEnabledCpu

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           GetCpuDataByIDFunctionId, 

+           CpuGlobalId, 

+           IndexByEnabledCpu, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL

+  MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.

+

+  @param  Index                   The Global ID for the CPU being modified.

+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.

+                                  If FALSE, then the index of set of all CPUs of database is returned.

+

+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetCpuDataByIndex (

+  IN UINT64   Index,

+  IN BOOLEAN  IndexByEnabledCpu

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           GetCpuDataByIndexFunctionId, 

+           Index, 

+           IndexByEnabledCpu, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL

+  MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.

+

+  @param  IndexByEnabledCpu       If TRUE, then the index of set of enabled CPUs of database is returned.

+                                  If FALSE, then the index of set of all CPUs of database is returned.

+

+  @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.

+  @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalWhoAmI (

+  IN BOOLEAN  IndexByEnabledCpu

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           CurrentProcInfoFunctionId, 

+           IndexByEnabledCpu, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalNumProcessors service of Extended SAL

+  MP Services Class. See EsalNumProcessors of Extended SAL Specification.

+

+  @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform

+                             was returned.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalNumProcessors (

+  VOID

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           NumProcessorsFunctionId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL

+  MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId              The Global ID for the CPU whose MINSTATE pointer is being set.

+  @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU

+                                   specified by CpuGlobalId.

+

+  @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.

+  @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalSetMinState (

+  IN UINT64                CpuGlobalId,

+  IN EFI_PHYSICAL_ADDRESS  MinStatePointer

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           SetMinStateFunctionId, 

+           CpuGlobalId, 

+           MinStatePointer, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL

+  MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId            The Global ID for the CPU whose MINSTATE pointer is being retrieved.

+

+  @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.

+  @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetMinState (

+  IN UINT64  CpuGlobalId

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           GetMinStateFunctionId, 

+           CpuGlobalId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.

+  

+  This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL

+  MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.

+  @param  StateBufferPointer        A pointer to the returned MCA state buffer.

+  @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.

+

+  @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.

+  @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcaGetStateInfo (

+  IN  UINT64                CpuGlobalId,

+  OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,

+  OUT UINT64                *RequiredStateBufferSize

+  )

+{

+  SAL_RETURN_REGS  Regs;

+

+  Regs = EsalCall (

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,

+           McaGetStateInfoFunctionId, 

+           CpuGlobalId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+

+  *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;

+  *RequiredStateBufferSize = (UINT64) Regs.r10;

+

+  return Regs;

+}

+

+/**

+  Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.

+  

+  This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL

+  MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId              The Global ID for the CPU whose MCA state buffer is being set.

+  @param  StateBufferPointer       A pointer to the MCA state buffer.

+

+  @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId

+  @retval EFI_SUCCESS              Save the processor's state info successfully

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcaRegisterCpu (

+  IN UINT64                CpuGlobalId,

+  IN EFI_PHYSICAL_ADDRESS  StateBufferPointer

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,

+           McaRegisterCpuFunctionId, 

+           CpuGlobalId, 

+           StateBufferPointer, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/Ipf/AsmExtendedSalLib.s b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/Ipf/AsmExtendedSalLib.s
new file mode 100644
index 0000000..f1c4366
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtendedSalLib/Ipf/AsmExtendedSalLib.s
@@ -0,0 +1,97 @@
+/// @file

+///  Assembly procedures to get and set ESAL entry point.

+///

+/// 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

+/// 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.

+///

+

+.auto

+.text

+

+#include  "IpfMacro.i"

+

+//

+// Exports

+//

+ASM_GLOBAL GetEsalEntryPoint

+

+//-----------------------------------------------------------------------------

+//++

+// GetEsalEntryPoint

+//

+// Return Esal global and PSR register.

+//

+// On Entry :

+//

+//

+// Return Value:

+//        r8  = EFI_SAL_SUCCESS

+//        r9  = Physical Plabel

+//        r10 = Virtual Plabel

+//        r11 = psr

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (GetEsalEntryPoint)

+

+      NESTED_SETUP (0,8,0,0)

+

+EsalCalcStart:

+      mov   r8  = ip;;

+      add   r8  = (EsalEntryPoint - EsalCalcStart), r8;;

+      mov   r9  = r8;;

+      add   r10 = 0x10, r8;;

+      mov   r11 = psr;;

+      mov   r8  = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (GetEsalEntryPoint)

+

+//-----------------------------------------------------------------------------

+//++

+// SetEsalPhysicalEntryPoint

+//

+// Set the dispatcher entry point

+//

+// On Entry:

+//  in0 = Physical address of Esal Dispatcher

+//  in1 = Physical GP

+//

+// Return Value: 

+//   r8 = EFI_SAL_SUCCESS

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (SetEsalPhysicalEntryPoint)

+

+      NESTED_SETUP (2,8,0,0)

+

+EsalCalcStart1:

+      mov   r8   = ip;;

+      add   r8   = (EsalEntryPoint - EsalCalcStart1), r8;;

+      st8   [r8] = in0;;

+      add   r8   = 0x08, r8;;

+      st8   [r8] = in1;;

+      mov   r8   = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (SetEsalPhysicalEntryPoint)

+

+.align 32

+EsalEntryPoint: 

+    data8 0   // Physical Entry

+    data8 0   //         GP

+    data8 0   // Virtual Entry

+    data8 0   //         GP

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.c
new file mode 100644
index 0000000..567f091
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.c
@@ -0,0 +1,454 @@
+/** @file

+  Provide generic extract guided section functions for Dxe phase.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/ExtractGuidedSectionLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+#define EXTRACT_HANDLER_TABLE_SIZE   0x10

+

+UINT32               mNumberOfExtractHandler = 0;

+UINT32               mMaxNumberOfExtractHandler = 0;

+

+GUID                 *mExtractHandlerGuidTable = NULL;

+EXTRACT_GUIDED_SECTION_DECODE_HANDLER   *mExtractDecodeHandlerTable = NULL;

+EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *mExtractGetInfoHandlerTable = NULL;

+

+/**

+  Reallocates more global memory to store the registered guid and Handler list.

+

+  @retval  RETURN_SUCCESS            Reallocated more global memory space to store guid and function tables.

+  @retval  RETURN_OUT_OF_RESOURCES   Not enough memory to allocate.

+**/

+RETURN_STATUS

+EFIAPI

+ReallocateExtractHandlerTable (

+  )

+{ 

+  //

+  // Reallocate memory for GuidTable

+  //

+  mExtractHandlerGuidTable = ReallocatePool (

+                               mMaxNumberOfExtractHandler * sizeof (GUID), 

+                               (mMaxNumberOfExtractHandler + EXTRACT_HANDLER_TABLE_SIZE) * sizeof (GUID), 

+                               mExtractHandlerGuidTable

+                             );

+

+  if (mExtractHandlerGuidTable == NULL) {

+    goto Done;

+  }

+

+  //

+  // Reallocate memory for Decode handler Table

+  //

+  mExtractDecodeHandlerTable = ReallocatePool (

+                               mMaxNumberOfExtractHandler * sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER), 

+                               (mMaxNumberOfExtractHandler + EXTRACT_HANDLER_TABLE_SIZE) * sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER), 

+                               mExtractDecodeHandlerTable

+                             );

+

+  if (mExtractDecodeHandlerTable == NULL) {

+    goto Done;

+  }

+

+  //

+  // Reallocate memory for GetInfo handler Table

+  //

+  mExtractGetInfoHandlerTable = ReallocatePool (

+                               mMaxNumberOfExtractHandler * sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER), 

+                               (mMaxNumberOfExtractHandler + EXTRACT_HANDLER_TABLE_SIZE) * sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER), 

+                               mExtractGetInfoHandlerTable

+                             );

+

+  if (mExtractGetInfoHandlerTable == NULL) {

+    goto Done;

+  }

+  

+  //

+  // Increase max handler number

+  //

+  mMaxNumberOfExtractHandler = mMaxNumberOfExtractHandler + EXTRACT_HANDLER_TABLE_SIZE;

+  return RETURN_SUCCESS;

+

+Done:

+  if (mExtractHandlerGuidTable != NULL) {

+    FreePool (mExtractHandlerGuidTable);

+  }

+  if (mExtractDecodeHandlerTable != NULL) {

+    FreePool (mExtractDecodeHandlerTable);

+  }

+  if (mExtractGetInfoHandlerTable != NULL) {

+    FreePool (mExtractGetInfoHandlerTable);

+  }

+  

+  return RETURN_OUT_OF_RESOURCES;

+}

+/**

+  Constructor allocates the global memory to store the registered guid and Handler list.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval  RETURN_SUCCESS            Allocated the global memory space to store guid and function tables.

+  @retval  RETURN_OUT_OF_RESOURCES   Not enough memory to allocate.

+**/

+RETURN_STATUS

+EFIAPI

+DxeExtractGuidedSectionLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return ReallocateExtractHandlerTable ();

+}

+

+/**

+  Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().

+

+  Sets ExtractHandlerGuidTable so it points at a callee allocated array of registered GUIDs.

+  The total number of GUIDs in the array are returned. Since the array of GUIDs is callee allocated

+  and caller must treat this array of GUIDs as read-only data. 

+  If ExtractHandlerGuidTable is NULL, then ASSERT().

+

+  @param[out]  ExtractHandlerGuidTable  A pointer to the array of GUIDs that have been registered through

+                                        ExtractGuidedSectionRegisterHandlers().

+

+  @return The number of the supported extract guided Handler.

+

+**/

+UINTN

+EFIAPI

+ExtractGuidedSectionGetGuidList (

+  OUT  GUID  **ExtractHandlerGuidTable

+  )

+{

+  ASSERT (ExtractHandlerGuidTable != NULL);

+

+  *ExtractHandlerGuidTable = mExtractHandlerGuidTable;

+  return mNumberOfExtractHandler;

+}

+

+/**

+  Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER

+  for a specific GUID section type.

+

+  Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.

+  If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.

+  If there are not enough resources available to register the handlers  then RETURN_OUT_OF_RESOURCES is returned.

+  

+  If SectionGuid is NULL, then ASSERT().

+  If GetInfoHandler is NULL, then ASSERT().

+  If DecodeHandler is NULL, then ASSERT().

+

+  @param[in]  SectionGuid    A pointer to the GUID associated with the the handlers

+                             of the GUIDed section type being registered.

+  @param[in]  GetInfoHandler The pointer to a function that examines a GUIDed section and returns the

+                             size of the decoded buffer and the size of an optional scratch buffer

+                             required to actually decode the data in a GUIDed section.

+  @param[in]  DecodeHandler  The pointer to a function that decodes a GUIDed section into a caller

+                             allocated output buffer. 

+

+  @retval  RETURN_SUCCESS           The handlers were registered.

+  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to register the handlers.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionRegisterHandlers (

+  IN CONST  GUID                                     *SectionGuid,

+  IN        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  GetInfoHandler,

+  IN        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    DecodeHandler

+  )

+{

+  UINT32 Index;

+  VOID   *GuidData;

+

+  //

+  // Check input paramter.

+  //

+  ASSERT (SectionGuid != NULL);

+  ASSERT (GetInfoHandler != NULL);

+  ASSERT (DecodeHandler != NULL);

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  for (Index = 0; Index < mNumberOfExtractHandler; Index ++) {

+    if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionGuid)) {

+      //

+      // If the guided handler has been registered before, only update its handler.

+      //

+      mExtractDecodeHandlerTable [Index] = DecodeHandler;

+      mExtractGetInfoHandlerTable [Index] = GetInfoHandler;

+      return RETURN_SUCCESS;

+    }

+  }

+  

+  //

+  // Check the global table is enough to contain new Handler.

+  //

+  if (mNumberOfExtractHandler >= mMaxNumberOfExtractHandler) {

+    if (ReallocateExtractHandlerTable () != RETURN_SUCCESS) {

+      return RETURN_OUT_OF_RESOURCES;

+    }

+  }

+  

+  //

+  // Register new Handler and guid value.

+  //

+  CopyGuid (&mExtractHandlerGuidTable [mNumberOfExtractHandler], SectionGuid);

+  mExtractDecodeHandlerTable [mNumberOfExtractHandler] = DecodeHandler;

+  mExtractGetInfoHandlerTable [mNumberOfExtractHandler++] = GetInfoHandler;

+

+  //

+  // Install the Guided Section GUID configuration table to record the GUID itself.

+  // Then the content of the configuration table buffer will be the same as the GUID value itself.

+  //

+  GuidData = AllocateCopyPool (sizeof (GUID), (VOID *) SectionGuid);

+  if (GuidData != NULL) {

+    gBS->InstallConfigurationTable ((EFI_GUID *) SectionGuid, GuidData);

+  }

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type

+  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().

+  The selected handler is used to retrieve and return the size of the decoded buffer and the size of an

+  optional scratch buffer required to actually decode the data in a GUIDed section.

+

+  Examines a GUIDed section specified by InputSection.  

+  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),

+  then RETURN_UNSUPPORTED is returned.  

+  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler 

+  of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()

+  is used to retrieve the OututBufferSize, ScratchSize, and Attributes values. The return status from the handler of

+  type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned.

+  

+  If InputSection is NULL, then ASSERT().

+  If OutputBufferSize is NULL, then ASSERT().

+  If ScratchBufferSize is NULL, then ASSERT().

+  If SectionAttribute is NULL, then ASSERT().

+

+  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.

+  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required if the buffer

+                                 specified by InputSection were decoded.

+  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space if the buffer specified by

+                                 InputSection were decoded.

+  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section.  See the Attributes field of

+                                 EFI_GUID_DEFINED_SECTION in the PI Specification.

+

+  @retval  RETURN_SUCCESS      Successfully obtained the required information.

+  @retval  RETURN_UNSUPPORTED  The GUID from the section specified by InputSection does not match any of

+                               the GUIDs registered with ExtractGuidedSectionRegisterHandlers().

+  @retval  Others              The return status from the handler associated with the GUID retrieved from

+                               the section specified by InputSection.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionGetInfo (

+  IN  CONST VOID    *InputSection,

+  OUT       UINT32  *OutputBufferSize,

+  OUT       UINT32  *ScratchBufferSize,

+  OUT       UINT16  *SectionAttribute   

+  )

+{

+  UINT32 Index;

+  EFI_GUID *SectionDefinitionGuid;

+

+  ASSERT (InputSection != NULL);  

+  ASSERT (OutputBufferSize != NULL);

+  ASSERT (ScratchBufferSize != NULL);

+  ASSERT (SectionAttribute != NULL);

+

+  if (IS_SECTION2 (InputSection)) {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);

+  } else {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);

+  }

+ 

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  for (Index = 0; Index < mNumberOfExtractHandler; Index ++) {

+    if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionDefinitionGuid)) {

+      //

+      // Call the match handler to getinfo for the input section data.

+      //

+      return mExtractGetInfoHandlerTable [Index] (

+                InputSection,

+                OutputBufferSize,

+                ScratchBufferSize,

+                SectionAttribute

+              );

+    }

+  }

+

+  //

+  // Not found, the input guided section is not supported. 

+  //

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().

+  The selected handler is used to decode the data in a GUIDed section and return the result in a caller

+  allocated output buffer.

+

+  Decodes the GUIDed section specified by InputSection.  

+  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),

+  then RETURN_UNSUPPORTED is returned.  

+  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler

+  of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()

+  is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this

+  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the data in InputSection,

+  then OutputBuffer is set to point at the data in InputSection.  Otherwise, the decoded data will be placed in caller

+  allocated buffer specified by OutputBuffer.    This function is responsible for computing the  EFI_AUTH_STATUS_PLATFORM_OVERRIDE

+  bit of in AuthenticationStatus.  The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned. 

+   

+  If InputSection is NULL, then ASSERT().

+  If OutputBuffer is NULL, then ASSERT().

+  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().

+  If AuthenticationStatus is NULL, then ASSERT().  

+

+  @param[in]  InputSection   A pointer to a GUIDed section of an FFS formatted file.

+  @param[out] OutputBuffer   A pointer to a buffer that contains the result of a decode operation. 

+  @param[in]  ScratchBuffer  A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation. 

+  @param[out] AuthenticationStatus 

+                             A pointer to the authentication status of the decoded output buffer. See the definition

+                             of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI

+                             Specification.

+

+  @retval  RETURN_SUCCESS           The buffer specified by InputSection was decoded.

+  @retval  RETURN_UNSUPPORTED       The section specified by InputSection does not match the GUID this handler supports.

+  @retval  RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionDecode (

+  IN  CONST VOID    *InputSection,

+  OUT       VOID    **OutputBuffer,

+  IN        VOID    *ScratchBuffer,        OPTIONAL

+  OUT       UINT32  *AuthenticationStatus  

+  )

+{

+  UINT32 Index;

+  EFI_GUID *SectionDefinitionGuid;

+  

+  //

+  // Check the input parameters

+  //

+  ASSERT (InputSection != NULL);

+  ASSERT (OutputBuffer != NULL);

+  ASSERT (AuthenticationStatus != NULL);

+

+  if (IS_SECTION2 (InputSection)) {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);

+  } else {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);

+  }

+

+  //

+  // Search the match registered extract handler for the input guided section.

+  //

+  for (Index = 0; Index < mNumberOfExtractHandler; Index ++) {

+    if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionDefinitionGuid)) {

+      //

+      // Call the match handler to extract raw data for the input section data.

+      //

+      return mExtractDecodeHandlerTable [Index] (

+                InputSection,

+                OutputBuffer,

+                ScratchBuffer,

+                AuthenticationStatus

+              );

+    }

+  }

+

+  //

+  // Not found, the input guided section is not supported. 

+  //

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and 

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.

+  

+  Retrieves the handlers associated with SectionGuid and returns them in 

+  GetInfoHandler and DecodeHandler.

+

+  If the GUID value specified by SectionGuid has not been registered, then 

+  return RETURN_NOT_FOUND.

+  

+  If SectionGuid is NULL, then ASSERT().

+

+  @param[in]  SectionGuid    A pointer to the GUID associated with the handlersof the GUIDed 

+                             section type being retrieved.

+  @param[out] GetInfoHandler Pointer to a function that examines a GUIDed section and returns 

+                             the size of the decoded buffer and the size of an optional scratch 

+                             buffer required to actually decode the data in a GUIDed section.  

+                             This is an optional parameter that may be NULL. If it is NULL, then 

+                             the previously registered handler is not returned.

+  @param[out] DecodeHandler  Pointer to a function that decodes a GUIDed section into a caller

+                             allocated output buffer. This is an optional parameter that may be NULL.

+                             If it is NULL, then the previously registered handler is not returned.

+

+  @retval  RETURN_SUCCESS     The handlers were retrieved.

+  @retval  RETURN_NOT_FOUND   No handlers have been registered with the specified GUID.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionGetHandlers (

+  IN CONST   GUID                                     *SectionGuid,

+  OUT        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  *GetInfoHandler,  OPTIONAL

+  OUT        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    *DecodeHandler    OPTIONAL

+  )

+{

+  UINT32 Index; 

+

+  //

+  // Check input parameter.

+  //

+  ASSERT (SectionGuid != NULL);

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  for (Index = 0; Index < mNumberOfExtractHandler; Index ++) {

+    if (CompareGuid (&mExtractHandlerGuidTable[Index], SectionGuid)) {

+      

+      //

+      // If the guided handler has been registered before, then return the registered handlers.

+      //

+      if (GetInfoHandler != NULL) {

+        *GetInfoHandler = mExtractGetInfoHandlerTable[Index];

+      }

+      if (DecodeHandler != NULL) {

+        *DecodeHandler = mExtractDecodeHandlerTable[Index];

+      }

+      return RETURN_SUCCESS;

+    }

+  }

+  return RETURN_NOT_FOUND;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
new file mode 100644
index 0000000..c66a26b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
@@ -0,0 +1,47 @@
+## @file

+# Instance of ExtractGuidedSection Library for DXE phase.

+#

+# This library provides generic extract guided section functions for DXE module.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeExtractGuidedSectionLib

+  MODULE_UNI_FILE                = DxeExtractGuidedSectionLib.uni

+  FILE_GUID                      = f773469b-e265-4b0c-b0a6-2f971fbfe72b

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ExtractGuidedSectionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+

+  CONSTRUCTOR                    = DxeExtractGuidedSectionLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DxeExtractGuidedSectionLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  MemoryAllocationLib

+  BaseMemoryLib

+  DebugLib

+  UefiBootServicesTableLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.uni
new file mode 100644
index 0000000..0584179
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/DxeHobLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/DxeHobLib.inf
new file mode 100644
index 0000000..32cd554
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -0,0 +1,48 @@
+## @file

+# Instance of HOB Library using HOB list from EFI Configuration Table.

+#

+# HOB Library implementation that retrieves the HOB List

+#  from the System Configuration Table in the EFI System Table.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeHobLib

+  MODULE_UNI_FILE                = DxeHobLib.uni

+  FILE_GUID                      = f12b59c9-76d0-4661-ad7c-f04d1bef0558

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = HobLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+  CONSTRUCTOR                    = HobLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  HobLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  DebugLib

+  UefiLib

+    

+[Guids]

+  gEfiHobListGuid                               ## CONSUMES  ## SystemTable

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/DxeHobLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/DxeHobLib.uni
new file mode 100644
index 0000000..4bef9c3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/DxeHobLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/HobLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/HobLib.c
new file mode 100644
index 0000000..f0861ff
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHobLib/HobLib.c
@@ -0,0 +1,600 @@
+/** @file

+  HOB Library implemenation for Dxe Phase.

+

+Copyright (c) 2006 - 2014, 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 <PiDxe.h>

+

+#include <Guid/HobList.h>

+

+#include <Library/HobLib.h>

+#include <Library/UefiLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+

+VOID  *mHobList = NULL;

+

+/**

+  The constructor function caches the pointer to HOB list.

+  

+  The constructor function gets the start address of HOB list from system configuration table.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor successfully gets HobList.

+  @retval Other value   The constructor can't get HobList.

+

+**/

+EFI_STATUS

+EFIAPI

+HobLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, &mHobList);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mHobList != NULL);

+

+  return Status;

+}

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+  For PEI phase, the PEI service GetHobList() can be used to retrieve the pointer 

+  to the HOB list.  For the DXE phase, the HOB list pointer can be retrieved through

+  the EFI System Table by looking up theHOB list GUID in the System Configuration Table.

+  Since the System Configuration Table does not exist that the time the DXE Core is 

+  launched, the DXE Core uses a global variable from the DXE Core Entry Point Library 

+  to manage the pointer to the HOB list.

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+  

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+{

+  ASSERT (mHobList != NULL);

+  return mHobList;

+}

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  ASSERT (HobStart != NULL);

+   

+  Hob.Raw = (UINT8 *) HobStart;

+  //

+  // Parse the HOB list until end of list or matching type is found.

+  //

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == Type) {

+      return Hob.Raw;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return NULL;

+}

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextHob (Type, HobList);

+}

+

+/**

+  Returns the next instance of the matched GUID HOB from the starting HOB.

+  

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size information, respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  GuidHob;

+

+  GuidHob.Raw = (UINT8 *) HobStart;

+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {

+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+  return GuidHob.Raw;

+}

+

+/**

+  Returns the first instance of the matched GUID HOB among the whole HOB list.

+  

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size information, respectively.

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextGuidHob (Guid, HobList);

+}

+

+/**

+  Get the system boot mode from the HOB list.

+

+  This function returns the system boot mode information from the 

+  PHIT HOB in HOB list.

+

+  If the pointer to the HOB list is NULL, then ASSERT().

+  

+  @param  VOID

+

+  @return The Boot Mode.

+

+**/

+EFI_BOOT_MODE

+EFIAPI

+GetBootModeHob (

+  VOID

+  )

+{

+  EFI_HOB_HANDOFF_INFO_TABLE    *HandOffHob;

+

+  HandOffHob = (EFI_HOB_HANDOFF_INFO_TABLE *) GetHobList ();

+

+  return  HandOffHob->BootMode;

+}

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the module entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory with Owner GUID.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+  @param  OwnerGUID           GUID for the owner of this resource.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorWithOwnerHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes,

+  IN EFI_GUID                     *OwnerGUID

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a customized HOB tagged with a GUID for identification and returns 

+  the start address of GUID HOB data.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().

+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @retval  NULL         The GUID HOB could not be allocated.

+  @retval  others       The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Builds a customized HOB tagged with a GUID for identification, copies the input data to the HOB 

+  data field, and returns the start address of the GUID HOB data.

+

+  This function builds a customized HOB tagged with a GUID for identification and copies the input

+  data to the HOB data field and returns the start address of the GUID HOB data.  It can only be 

+  invoked during PEI phase; for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.  

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().

+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @retval  NULL         The GUID HOB could not be allocated.

+  @retval  others       The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+  return NULL;

+}

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a EFI_HOB_TYPE_FV2 HOB.

+

+  This function builds a EFI_HOB_TYPE_FV2 HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+  @param  FvName        The name of the Firmware Volume.

+  @param  FileName      The name of the file.

+  

+**/

+VOID

+EFIAPI

+BuildFv2Hob (

+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN          UINT64                      Length,

+  IN CONST    EFI_GUID                    *FvName,

+  IN CONST    EFI_GUID                    *FileName

+  )

+{

+  ASSERT (FALSE);

+}

+

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If the platform does not support Capsule Volume HOBs, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    Type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  //

+  // PEI HOB is read only for DXE phase

+  //

+  ASSERT (FALSE);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/DxeHstiLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/DxeHstiLib.inf
new file mode 100644
index 0000000..a694c2c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/DxeHstiLib.inf
@@ -0,0 +1,48 @@
+## @file

+# DXE instance of Hsti Library.

+#

+# Copyright (c) 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.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeHstiLib

+  MODULE_UNI_FILE                = DxeHstiLib.uni

+  FILE_GUID                      = 7DE1C620-F587-4116-A36D-40F3467B9A0C

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = HstiLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER

+

+[Sources]

+  HstiAip.c

+  HstiDxe.c

+  HstiDxe.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  BaseMemoryLib

+  MemoryAllocationLib

+  DebugLib

+  UefiBootServicesTableLib

+

+[Guids]

+## SOMETIMES_PRODUCES ## GUID

+## SOMETIMES_CONSUMES ## GUID

+  gAdapterInfoPlatformSecurityGuid

+

+[Protocols]

+## SOMETIMES_PRODUCES

+## SOMETIMES_CONSUMES

+  gEfiAdapterInformationProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/DxeHstiLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/DxeHstiLib.uni
new file mode 100644
index 0000000..d5b7a78
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/DxeHstiLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiAip.c b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiAip.c
new file mode 100644
index 0000000..5677cd3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiAip.c
@@ -0,0 +1,175 @@
+/** @file

+

+  Copyright (c) 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 "HstiDxe.h"

+

+/**

+  Returns the current state information for the adapter.

+

+  This function returns information of type InformationType from the adapter.

+  If an adapter does not support the requested informational type, then

+  EFI_UNSUPPORTED is returned. 

+

+  @param[in]  This                   A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.

+  @param[in]  InformationType        A pointer to an EFI_GUID that defines the contents of InformationBlock.

+  @param[out] InformationBlock       The service returns a pointer to the buffer with the InformationBlock

+                                     structure which contains details about the data specific to InformationType.

+  @param[out] InformationBlockSize   The driver returns the size of the InformationBlock in bytes.

+

+  @retval EFI_SUCCESS                The InformationType information was retrieved.

+  @retval EFI_UNSUPPORTED            The InformationType is not known.

+  @retval EFI_DEVICE_ERROR           The device reported an error.

+  @retval EFI_OUT_OF_RESOURCES       The request could not be completed due to a lack of resources.

+  @retval EFI_INVALID_PARAMETER      This is NULL. 

+  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL. 

+  @retval EFI_INVALID_PARAMETER      InformationBlockSize is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+HstiAipGetInfo (

+  IN  EFI_ADAPTER_INFORMATION_PROTOCOL  *This,

+  IN  EFI_GUID                          *InformationType,

+  OUT VOID                              **InformationBlock,

+  OUT UINTN                             *InformationBlockSize

+  )

+{

+  HSTI_AIP_PRIVATE_DATA  *HstiAip;

+

+  if ((This == NULL) || (InformationBlock == NULL) || (InformationBlockSize == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (!CompareGuid (InformationType, &gAdapterInfoPlatformSecurityGuid)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  HstiAip = HSTI_AIP_PRIVATE_DATA_FROM_THIS(This);

+

+  *InformationBlock = AllocateCopyPool (HstiAip->HstiSize, HstiAip->Hsti);

+  if (*InformationBlock == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  *InformationBlockSize = HstiAip->HstiSize;

+  return EFI_SUCCESS;

+}

+

+/**

+  Sets state information for an adapter.

+

+  This function sends information of type InformationType for an adapter.

+  If an adapter does not support the requested information type, then EFI_UNSUPPORTED

+  is returned.

+

+  @param[in]  This                   A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.

+  @param[in]  InformationType        A pointer to an EFI_GUID that defines the contents of InformationBlock.

+  @param[in]  InformationBlock       A pointer to the InformationBlock structure which contains details

+                                     about the data specific to InformationType.

+  @param[in]  InformationBlockSize   The size of the InformationBlock in bytes.

+

+  @retval EFI_SUCCESS                The information was received and interpreted successfully.

+  @retval EFI_UNSUPPORTED            The InformationType is not known.

+  @retval EFI_DEVICE_ERROR           The device reported an error.

+  @retval EFI_INVALID_PARAMETER      This is NULL.

+  @retval EFI_INVALID_PARAMETER      InformationBlock is NULL.

+  @retval EFI_WRITE_PROTECTED        The InformationType cannot be modified using EFI_ADAPTER_INFO_SET_INFO().

+

+**/

+EFI_STATUS

+EFIAPI

+HstiAipSetInfo (

+  IN  EFI_ADAPTER_INFORMATION_PROTOCOL  *This,

+  IN  EFI_GUID                          *InformationType,

+  IN  VOID                              *InformationBlock,

+  IN  UINTN                             InformationBlockSize

+  )

+{

+  HSTI_AIP_PRIVATE_DATA  *HstiAip;

+  VOID                   *NewHsti;

+

+  if ((This == NULL) || (InformationBlock == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+  if (!CompareGuid (InformationType, &gAdapterInfoPlatformSecurityGuid)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  if (!InternalHstiIsValidTable (InformationBlock, InformationBlockSize)) {

+    return EFI_VOLUME_CORRUPTED;

+  }

+

+  HstiAip = HSTI_AIP_PRIVATE_DATA_FROM_THIS(This);

+

+  if (InformationBlockSize > HstiAip->HstiMaxSize) {

+    NewHsti = AllocateZeroPool (InformationBlockSize);

+    if (NewHsti == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+    FreePool (HstiAip->Hsti);

+    HstiAip->Hsti = NewHsti;

+    HstiAip->HstiSize = 0;

+    HstiAip->HstiMaxSize = InformationBlockSize;

+  }

+

+  CopyMem (HstiAip->Hsti, InformationBlock, InformationBlockSize);

+  HstiAip->HstiSize = InformationBlockSize;

+  return EFI_SUCCESS;

+}

+

+/**

+  Get a list of supported information types for this instance of the protocol.

+

+  This function returns a list of InformationType GUIDs that are supported on an

+  adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL. The list is returned

+  in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is returned in

+  InfoTypesBufferCount.

+

+  @param[in]  This                  A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance.

+  @param[out] InfoTypesBuffer       A pointer to the array of InformationType GUIDs that are supported

+                                    by This.

+  @param[out] InfoTypesBufferCount  A pointer to the number of GUIDs present in InfoTypesBuffer.

+

+  @retval EFI_SUCCESS               The list of information type GUIDs that are supported on this adapter was

+                                    returned in InfoTypesBuffer. The number of information type GUIDs was

+                                    returned in InfoTypesBufferCount.

+  @retval EFI_INVALID_PARAMETER     This is NULL.

+  @retval EFI_INVALID_PARAMETER     InfoTypesBuffer is NULL.

+  @retval EFI_INVALID_PARAMETER     InfoTypesBufferCount is NULL.

+  @retval EFI_OUT_OF_RESOURCES      There is not enough pool memory to store the results.

+

+**/

+EFI_STATUS

+EFIAPI

+HstiAipGetSupportedTypes (

+  IN  EFI_ADAPTER_INFORMATION_PROTOCOL  *This,

+  OUT EFI_GUID                          **InfoTypesBuffer,

+  OUT UINTN                             *InfoTypesBufferCount

+  )

+{

+  if ((This == NULL) || (InfoTypesBuffer == NULL) || (InfoTypesBufferCount == NULL)) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  *InfoTypesBuffer = AllocateCopyPool (sizeof(gAdapterInfoPlatformSecurityGuid), &gAdapterInfoPlatformSecurityGuid);

+  if (*InfoTypesBuffer == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  *InfoTypesBufferCount = 1;

+

+  return EFI_SUCCESS;

+}

+

+EFI_ADAPTER_INFORMATION_PROTOCOL mAdapterInformationProtocol = {

+  HstiAipGetInfo,

+  HstiAipSetInfo,

+  HstiAipGetSupportedTypes,

+};

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiDxe.c b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiDxe.c
new file mode 100644
index 0000000..114a767
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiDxe.c
@@ -0,0 +1,609 @@
+/** @file

+

+  Copyright (c) 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 "HstiDxe.h"

+

+/**

+  Find HSTI table in AIP protocol, and return the data.

+  This API will return the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param HstiData         HSTI data. This buffer is allocated by callee, and it

+                          is the responsibility of the caller to free it after

+                          using it.

+  @param HstiSize         HSTI size

+

+  @return Aip             The AIP protocol having this HSTI.

+  @return NULL            There is not HSTI table with the Role and ImplementationID published in system.

+**/

+VOID *

+InternalHstiFindAip (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID OPTIONAL,

+  OUT VOID                    **HstiData OPTIONAL,

+  OUT UINTN                   *HstiSize OPTIONAL

+  )

+{

+  EFI_STATUS                        Status;

+  EFI_ADAPTER_INFORMATION_PROTOCOL  *Aip;

+  UINTN                             NoHandles;

+  EFI_HANDLE                        *Handles;

+  UINTN                             Index;

+  EFI_GUID                          *InfoTypesBuffer;

+  UINTN                             InfoTypesBufferCount;

+  UINTN                             InfoTypesIndex;

+  EFI_ADAPTER_INFORMATION_PROTOCOL  *AipCandidate;

+  VOID                              *InformationBlock;

+  UINTN                             InformationBlockSize;

+  ADAPTER_INFO_PLATFORM_SECURITY    *Hsti;

+

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiAdapterInformationProtocolGuid,

+                  NULL,

+                  &NoHandles,

+                  &Handles

+                  );

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+

+  Hsti = NULL;

+  Aip = NULL;

+  InformationBlock = NULL;

+  InformationBlockSize = 0;

+  for (Index = 0; Index < NoHandles; Index++) {

+    Status = gBS->HandleProtocol (

+                    Handles[Index],

+                    &gEfiAdapterInformationProtocolGuid,

+                    (VOID **)&Aip

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    //

+    // Check AIP

+    //

+    Status = Aip->GetSupportedTypes (

+                    Aip,

+                    &InfoTypesBuffer,

+                    &InfoTypesBufferCount

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    AipCandidate = NULL;

+    for (InfoTypesIndex = 0; InfoTypesIndex < InfoTypesBufferCount; InfoTypesIndex++) {

+      if (CompareGuid (&InfoTypesBuffer[InfoTypesIndex], &gAdapterInfoPlatformSecurityGuid)) {

+        AipCandidate = Aip;

+        break;

+      }

+    }

+    FreePool (InfoTypesBuffer);

+

+    if (AipCandidate == NULL) {

+      continue;

+    }

+

+    //

+    // Check HSTI Role

+    //

+    Aip = AipCandidate;

+    Status = Aip->GetInformation (

+                    Aip,

+                    &gAdapterInfoPlatformSecurityGuid,

+                    &InformationBlock,

+                    &InformationBlockSize

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    Hsti = InformationBlock;

+    if ((Hsti->Role == Role) && 

+        ((ImplementationID == NULL) || (StrCmp (ImplementationID, Hsti->ImplementationID) == 0))) {

+      break;

+    } else {

+      Hsti = NULL;

+      FreePool (InformationBlock);

+      continue;

+    }

+  }

+  FreePool (Handles);

+

+  if (Hsti == NULL) {

+    return NULL;

+  }

+

+  if (HstiData != NULL) {

+    *HstiData = InformationBlock;

+  }

+  if (HstiSize != NULL) {

+    *HstiSize = InformationBlockSize;

+  }

+  return Aip;

+}

+

+/**

+  Return if input HSTI data follows HSTI specification.

+

+  @param HstiData  HSTI data

+  @param HstiSize  HSTI size

+

+  @retval TRUE  HSTI data follows HSTI specification.

+  @retval FALSE HSTI data does not follow HSTI specification.

+**/

+BOOLEAN

+InternalHstiIsValidTable (

+  IN VOID                     *HstiData,

+  IN UINTN                    HstiSize

+  )

+{

+  ADAPTER_INFO_PLATFORM_SECURITY  *Hsti;

+  UINTN                           Index;

+  CHAR16                          *ErrorString;

+  CHAR16                          ErrorChar;

+  UINTN                           ErrorStringSize;

+  UINTN                           ErrorStringLength;

+

+  Hsti = HstiData;

+

+  //

+  // basic check for header

+  //

+  if (HstiData == NULL) {

+    DEBUG ((EFI_D_ERROR, "HstiData == NULL\n"));

+    return FALSE;

+  }

+  if (HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) {

+    DEBUG ((EFI_D_ERROR, "HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)\n"));

+    return FALSE;

+  }

+  if (((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < Hsti->SecurityFeaturesSize) {

+    DEBUG ((EFI_D_ERROR, "((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < SecurityFeaturesSize\n"));

+    return FALSE;

+  }

+

+  //

+  // Check Version

+  //

+  if (Hsti->Version != PLATFORM_SECURITY_VERSION_VNEXTCS) {

+    DEBUG ((EFI_D_ERROR, "Version != PLATFORM_SECURITY_VERSION_VNEXTCS\n"));

+    return FALSE;

+  }

+

+  //

+  // Check Role

+  //

+  if ((Hsti->Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) ||

+      (Hsti->Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM)) {

+    DEBUG ((EFI_D_ERROR, "Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE ||\n"));

+    DEBUG ((EFI_D_ERROR, "Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM\n"));

+    return FALSE;

+  }

+

+  //

+  // Check ImplementationID

+  //

+  for (Index = 0; Index < sizeof(Hsti->ImplementationID)/sizeof(Hsti->ImplementationID[0]); Index++) {

+    if (Hsti->ImplementationID[Index] == 0) {

+      break;

+    }

+  }

+  if (Index == sizeof(Hsti->ImplementationID)/sizeof(Hsti->ImplementationID[0])) {

+    DEBUG ((EFI_D_ERROR, "ImplementationID is no NUL CHAR\n"));

+    return FALSE;

+  }

+

+  ErrorStringSize = HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3;

+  ErrorString = (CHAR16 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3);

+

+  //

+  // basic check for ErrorString

+  //

+  if (ErrorStringSize == 0) {

+    DEBUG ((EFI_D_ERROR, "ErrorStringSize == 0\n"));

+    return FALSE;

+  }

+  if ((ErrorStringSize & BIT0) != 0) {

+    DEBUG ((EFI_D_ERROR, "(ErrorStringSize & BIT0) != 0\n"));

+    return FALSE;

+  }

+

+  //

+  // ErrorString might not be CHAR16 aligned.

+  //

+  CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar));

+  for (ErrorStringLength = 0; (ErrorChar != 0) && (ErrorStringLength < (ErrorStringSize/2)); ErrorStringLength++) {

+    ErrorString++;

+    CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar));

+  }

+

+  //

+  // check the length of ErrorString

+  //

+  if (ErrorChar != 0) {

+    DEBUG ((EFI_D_ERROR, "ErrorString has no NUL CHAR\n"));

+    return FALSE;

+  }

+  if (ErrorStringLength == (ErrorStringSize/2)) {

+    DEBUG ((EFI_D_ERROR, "ErrorString Length incorrect\n"));

+    return FALSE;

+  }

+

+  return TRUE;

+}

+

+/**

+  Publish HSTI table in AIP protocol.

+

+  One system should have only one PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE.

+

+  If the Role is NOT PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,

+  SecurityFeaturesRequired field will be ignored.

+

+  @param Hsti      HSTI data

+  @param HstiSize  HSTI size

+

+  @retval EFI_SUCCESS          The HSTI data is published in AIP protocol.

+  @retval EFI_ALREADY_STARTED  There is already HSTI table with Role and ImplementationID published in system.

+  @retval EFI_VOLUME_CORRUPTED The input HSTI data does not follow HSTI specification.

+  @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol.

+**/

+EFI_STATUS

+EFIAPI

+HstiLibSetTable (

+  IN VOID                     *Hsti,

+  IN UINTN                    HstiSize

+  )

+{

+  EFI_STATUS                       Status;

+  EFI_HANDLE                       Handle;

+  HSTI_AIP_PRIVATE_DATA            *HstiAip;

+  EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;

+  UINT32                           Role;

+  CHAR16                           *ImplementationID;

+  UINT32                           SecurityFeaturesSize;

+  UINT8                            *SecurityFeaturesRequired;

+

+  if (!InternalHstiIsValidTable (Hsti, HstiSize)) {

+    return EFI_VOLUME_CORRUPTED;

+  }

+

+  Role = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->Role;

+  ImplementationID = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->ImplementationID;

+  Aip = InternalHstiFindAip (Role, ImplementationID, NULL, NULL);

+  if (Aip != NULL) {

+    return EFI_ALREADY_STARTED;

+  }

+

+  HstiAip = AllocateZeroPool (sizeof(HSTI_AIP_PRIVATE_DATA));

+  if (HstiAip == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+  HstiAip->Hsti = AllocateCopyPool (HstiSize, Hsti);

+  if (HstiAip == NULL) {

+    FreePool (HstiAip);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  if (Role != PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) {

+    SecurityFeaturesRequired = (UINT8 *)HstiAip->Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY);

+    SecurityFeaturesSize = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->SecurityFeaturesSize;

+    ZeroMem (SecurityFeaturesRequired, SecurityFeaturesSize);

+  }

+

+  HstiAip->Signature = HSTI_AIP_PRIVATE_SIGNATURE;

+  CopyMem (&HstiAip->Aip, &mAdapterInformationProtocol, sizeof(EFI_ADAPTER_INFORMATION_PROTOCOL));

+  HstiAip->HstiSize = HstiSize;

+  HstiAip->HstiMaxSize = HstiSize;

+  

+  Handle = NULL;

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &Handle,

+                  &gEfiAdapterInformationProtocolGuid,

+                  &HstiAip->Aip,

+                  NULL

+                  );

+  if (EFI_ERROR (Status)) {

+    FreePool (HstiAip->Hsti);

+    FreePool (HstiAip);

+  }

+

+  return Status;

+}

+

+/**

+  Search HSTI table in AIP protocol, and return the data.

+  This API will return the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param Hsti             HSTI data. This buffer is allocated by callee, and it

+                          is the responsibility of the caller to free it after

+                          using it.

+  @param HstiSize         HSTI size

+

+  @retval EFI_SUCCESS          The HSTI data in AIP protocol is returned.

+  @retval EFI_NOT_FOUND        There is not HSTI table with the Role and ImplementationID published in system.

+**/

+EFI_STATUS

+EFIAPI

+HstiLibGetTable (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID OPTIONAL,

+  OUT VOID                    **Hsti,

+  OUT UINTN                   *HstiSize

+  )

+{

+  EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;

+

+  Aip = InternalHstiFindAip (Role, ImplementationID, Hsti, HstiSize);

+  if (Aip == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  return EFI_SUCCESS;

+}

+

+/**

+  Record FeaturesVerified in published HSTI table.

+  This API will update the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param ByteIndex        Byte index of FeaturesVerified of HSTI data.

+  @param BitMask          Bit mask of FeaturesVerified of HSTI data.

+  @param Set              TRUE means to set the FeaturesVerified bit.

+                          FALSE means to clear the FeaturesVerified bit.

+

+  @retval EFI_SUCCESS          The FeaturesVerified of HSTI data updated in AIP protocol.

+  @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.

+  @retval EFI_UNSUPPORTED      The ByteIndex is invalid.

+**/

+EFI_STATUS

+InternalHstiRecordFeaturesVerified (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID, OPTIONAL

+  IN UINT32                   ByteIndex,

+  IN UINT8                    Bit,

+  IN BOOLEAN                  Set

+  )

+{

+  EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;

+  ADAPTER_INFO_PLATFORM_SECURITY   *Hsti;

+  UINTN                            HstiSize;

+  UINT8                            *SecurityFeaturesVerified;

+  EFI_STATUS                       Status;

+

+  Aip = InternalHstiFindAip (Role, ImplementationID, (VOID **)&Hsti, &HstiSize);

+  if (Aip == NULL) {

+    return EFI_NOT_STARTED;

+  }

+

+  if (ByteIndex >= Hsti->SecurityFeaturesSize) {

+    return EFI_UNSUPPORTED;

+  }

+

+  SecurityFeaturesVerified = (UINT8 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 2);

+

+  if (Set) {

+    SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] | (Bit));

+  } else {

+    SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] & (~Bit));

+  }

+

+  Status = Aip->SetInformation (

+                  Aip,

+                  &gAdapterInfoPlatformSecurityGuid,

+                  Hsti,

+                  HstiSize

+                  );

+  return Status;

+}

+

+/**

+  Set FeaturesVerified in published HSTI table.

+  This API will update the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param ByteIndex        Byte index of FeaturesVerified of HSTI data.

+  @param BitMask          Bit mask of FeaturesVerified of HSTI data.

+

+  @retval EFI_SUCCESS          The FeaturesVerified of HSTI data updated in AIP protocol.

+  @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.

+  @retval EFI_UNSUPPORTED      The ByteIndex is invalid.

+**/

+EFI_STATUS

+EFIAPI

+HstiLibSetFeaturesVerified (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID, OPTIONAL

+  IN UINT32                   ByteIndex,

+  IN UINT8                    BitMask

+  )

+{

+  return InternalHstiRecordFeaturesVerified (

+           Role,

+           ImplementationID,

+           ByteIndex,

+           BitMask,

+           TRUE

+           );

+}

+

+/**

+  Clear FeaturesVerified in published HSTI table.

+  This API will update the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param ByteIndex        Byte index of FeaturesVerified of HSTI data.

+  @param BitMask          Bit mask of FeaturesVerified of HSTI data.

+

+  @retval EFI_SUCCESS          The FeaturesVerified of HSTI data updated in AIP protocol.

+  @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.

+  @retval EFI_UNSUPPORTED      The ByteIndex is invalid.

+**/

+EFI_STATUS

+EFIAPI

+HstiLibClearFeaturesVerified (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID, OPTIONAL

+  IN UINT32                   ByteIndex,

+  IN UINT8                    BitMask

+  )

+{

+  return InternalHstiRecordFeaturesVerified (

+           Role,

+           ImplementationID,

+           ByteIndex,

+           BitMask,

+           FALSE

+           );

+}

+

+/**

+  Record ErrorString in published HSTI table.

+  This API will update the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param ErrorString      ErrorString of HSTI data.

+  @param Append           TRUE means to append the ErrorString to HSTI table.

+                          FALSE means to set the ErrorString in HSTI table.

+

+  @retval EFI_SUCCESS          The ErrorString of HSTI data is published in AIP protocol.

+  @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.

+  @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.

+**/

+EFI_STATUS

+InternalHstiRecordErrorString (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID, OPTIONAL

+  IN CHAR16                   *ErrorString,

+  IN BOOLEAN                  Append

+  )

+{

+  EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;

+  ADAPTER_INFO_PLATFORM_SECURITY   *Hsti;

+  UINTN                            HstiSize;

+  UINTN                            StringSize;

+  VOID                             *NewHsti;

+  UINTN                            NewHstiSize;

+  UINTN                            Offset;

+  EFI_STATUS                       Status;

+

+  Aip = InternalHstiFindAip (Role, ImplementationID, (VOID **)&Hsti, &HstiSize);

+  if (Aip == NULL) {

+    return EFI_NOT_STARTED;

+  }

+

+  if (Append) {

+    Offset = HstiSize - sizeof(CHAR16);

+  } else {

+    Offset = sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 3;

+  }

+  StringSize = StrSize (ErrorString);

+

+  NewHstiSize = Offset + StringSize;

+  NewHsti = AllocatePool (NewHstiSize);

+  if (NewHsti == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  CopyMem (NewHsti, Hsti, Offset);

+  CopyMem ((UINT8 *)NewHsti + Offset, ErrorString, StringSize);

+

+  Status = Aip->SetInformation (

+                  Aip,

+                  &gAdapterInfoPlatformSecurityGuid,

+                  NewHsti,

+                  NewHstiSize

+                  );

+  return Status;

+}

+

+/**

+  Append ErrorString in published HSTI table.

+  This API will update the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param ErrorString      ErrorString of HSTI data.

+

+  @retval EFI_SUCCESS          The ErrorString of HSTI data is updated in AIP protocol.

+  @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.

+  @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.

+**/

+EFI_STATUS

+EFIAPI

+HstiLibAppendErrorString (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID, OPTIONAL

+  IN CHAR16                   *ErrorString

+  )

+{

+  return InternalHstiRecordErrorString (

+           Role,

+           ImplementationID,

+           ErrorString,

+           TRUE

+           );

+}

+

+/**

+  Set a new ErrorString in published HSTI table.

+  This API will update the HSTI table with indicated Role and ImplementationID,

+  NULL ImplementationID means to find the first HSTI table with indicated Role.

+

+  @param Role             Role of HSTI data.

+  @param ImplementationID ImplementationID of HSTI data.

+                          NULL means find the first one match Role.

+  @param ErrorString      ErrorString of HSTI data.

+

+  @retval EFI_SUCCESS          The ErrorString of HSTI data is updated in AIP protocol.

+  @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.

+  @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.

+**/

+EFI_STATUS

+EFIAPI

+HstiLibSetErrorString (

+  IN UINT32                   Role,

+  IN CHAR16                   *ImplementationID, OPTIONAL

+  IN CHAR16                   *ErrorString

+  )

+{

+  return InternalHstiRecordErrorString (

+           Role,

+           ImplementationID,

+           ErrorString,

+           FALSE

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiDxe.h b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiDxe.h
new file mode 100644
index 0000000..aaa4a0c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeHstiLib/HstiDxe.h
@@ -0,0 +1,65 @@
+/** @file

+

+  Copyright (c) 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 _HSTI_DXE_H_

+#define _HSTI_DXE_H_

+

+#include <PiDxe.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+

+#include <IndustryStandard/Hsti.h>

+

+#include <Protocol/AdapterInformation.h>

+

+#define HSTI_AIP_PRIVATE_SIGNATURE  SIGNATURE_32('H', 'S', 'T', 'I')

+

+typedef struct {

+  UINT32                            Signature;

+  LIST_ENTRY                        Link;

+  EFI_ADAPTER_INFORMATION_PROTOCOL  Aip;

+  VOID                              *Hsti;

+  UINTN                             HstiSize;

+  UINTN                             HstiMaxSize;

+} HSTI_AIP_PRIVATE_DATA;

+

+#define HSTI_AIP_PRIVATE_DATA_FROM_THIS(a) \

+  CR (a, \

+      HSTI_AIP_PRIVATE_DATA, \

+      Aip, \

+      HSTI_AIP_PRIVATE_SIGNATURE \

+      )

+

+#define HSTI_DEFAULT_ERROR_STRING_LEN  255

+

+extern EFI_ADAPTER_INFORMATION_PROTOCOL mAdapterInformationProtocol;

+

+/**

+  Return if input HSTI data follows HSTI specification.

+

+  @param HstiData  HSTI data

+  @param HstiSize  HSTI size

+

+  @retval TRUE  HSTI data follows HSTI specification.

+  @retval FALSE HSTI data does not follow HSTI specification.

+**/

+BOOLEAN

+InternalHstiIsValidTable (

+  IN VOID                     *HstiData,

+  IN UINTN                    HstiSize

+  );

+

+#endif
\ No newline at end of file
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeCpuIo2LibInternal.h b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeCpuIo2LibInternal.h
new file mode 100644
index 0000000..b459214
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeCpuIo2LibInternal.h
@@ -0,0 +1,116 @@
+/** @file

+  Internal include file of DXE CPU IO2 Library.

+  

+  Copyright (c) 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 _DXE_CPUIO2_LIB_INTERNAL_H_

+#define _DXE_CPUIO2_LIB_INTERNAL_H_

+

+#include <PiDxe.h>

+

+#include <Protocol/CpuIo2.h>

+

+#include <Library/IoLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+

+

+/**

+  Reads registers in the EFI CPU I/O space.

+

+  Reads the I/O port specified by Port with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI CPU I/O space.

+

+**/

+UINT64

+EFIAPI

+IoReadWorker (

+  IN      UINTN                     Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width

+  );

+

+/**

+  Writes registers in the EFI CPU I/O space.

+

+  Writes the I/O port specified by Port with registers width and value specified by Width

+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+

+  @return The paramter of Data.

+

+**/

+UINT64

+EFIAPI

+IoWriteWorker (

+  IN      UINTN                     Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,

+  IN      UINT64                    Data

+  );

+

+/**

+  Reads memory-mapped registers in the EFI system memory space.

+

+  Reads the MMIO registers specified by Address with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioReadWorker (

+  IN      UINTN                     Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width

+  );

+

+/**

+  Writes memory-mapped registers in the EFI system memory space.

+

+  Writes the MMIO registers specified by Address with registers width and value specified by Width

+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+  

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioWriteWorker (

+  IN      UINTN                     Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,

+  IN      UINT64                    Data

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.inf b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.inf
new file mode 100644
index 0000000..65031d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.inf
@@ -0,0 +1,53 @@
+## @file

+# I/O Library instance based on EFI_CPU_IO2_PROTOCOL.

+#

+# I/O Library implementation that uses the CPU I/O2 Protocol for I/O and MMIO operations.

+#

+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>

+# This program and the accompanying materials are licensed and made available

+# under the terms and conditions of the BSD License which accompanies this 

+# distribution. The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php.

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeIoLibCpuIo2

+  MODULE_UNI_FILE                = DxeIoLibCpuIo2.uni

+  FILE_GUID                      = 33D33BF3-349E-4768-9459-836A9F7558FB

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = IoLib|DXE_DRIVER DXE_SAL_DRIVER

+  CONSTRUCTOR                    = IoLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  IoLibMmioBuffer.c

+  DxeCpuIo2LibInternal.h

+  IoHighLevel.c

+  IoLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  UefiBootServicesTableLib

+

+[Protocols]

+  gEfiCpuIo2ProtocolGuid         ## CONSUMES

+

+[Depex]

+  gEfiCpuIo2ProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.uni b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.uni
new file mode 100644
index 0000000..dad14cb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c
new file mode 100644
index 0000000..c872ebf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoHighLevel.c
@@ -0,0 +1,2307 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  Copyright (c) 2010 - 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.

+

+**/

+

+

+#include "DxeCpuIo2LibInternal.h"

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) | OrData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) & AndData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) ((IoRead8 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, 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 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) | OrData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) & AndData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) ((IoRead16 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, 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 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, 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 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port 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  Port      The I/O port 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.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, 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 I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) | OrData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) & AndData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) ((MmioRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, 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 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) | OrData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) & AndData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) ((MmioRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, 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 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, 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 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, 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 MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoLib.c
new file mode 100644
index 0000000..9204757
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoLib.c
@@ -0,0 +1,617 @@
+/** @file

+  I/O Library instance based on EFI_CPU_IO2_PROTOCOL.

+  

+  Copyright (c) 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.

+

+**/

+

+#include "DxeCpuIo2LibInternal.h"

+

+//

+// Globle varible to cache pointer to CpuIo2 protocol.

+//

+EFI_CPU_IO2_PROTOCOL  *mCpuIo = NULL;

+

+/**

+  The constructor function caches the pointer to CpuIo2 protocol.

+

+  The constructor function locates CpuIo2 protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+IoLibConstructor (

+  IN      EFI_HANDLE                ImageHandle,

+  IN      EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) &mCpuIo);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  Reads registers in the EFI CPU I/O space.

+

+  Reads the I/O port specified by Port with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI CPU I/O space.

+

+**/

+UINT64

+EFIAPI

+IoReadWorker (

+  IN      UINTN                      Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width

+  )

+{

+  EFI_STATUS                        Status;

+  UINT64                            Data;

+

+  Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Writes registers in the EFI CPU I/O space.

+

+  Writes the I/O port specified by Port with registers width and value specified by Width

+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+

+  @return The paramter of Data.

+

+**/

+UINT64

+EFIAPI

+IoWriteWorker (

+  IN      UINTN                      Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width,

+  IN      UINT64                     Data

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Reads memory-mapped registers in the EFI system memory space.

+

+  Reads the MMIO registers specified by Address with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioReadWorker (

+  IN      UINTN                      Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width

+  )

+{

+  EFI_STATUS  Status;

+  UINT64      Data;

+

+  Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Writes memory-mapped registers in the EFI system memory space.

+

+  Writes the MMIO registers specified by Address with registers width and value specified by Width

+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+  

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioWriteWorker (

+  IN      UINTN                      Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH  Width,

+  IN      UINT64                     Data

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+ 

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoReadWorker (Port, EfiCpuIoWidthUint64);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+ 

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoLibMmioBuffer.c b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoLibMmioBuffer.c
new file mode 100644
index 0000000..9e14c25
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibCpuIo2/IoLibMmioBuffer.c
@@ -0,0 +1,413 @@
+/** @file

+  I/O Library MMIO Buffer Functions.

+

+  Copyright (c) 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.

+

+**/

+

+#include "DxeCpuIo2LibInternal.h"

+

+/**

+  Copy data from MMIO region to system memory by using 8-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 8-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioReadBuffer8 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT8       *Buffer

+  )

+{

+  UINT8   *ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ReturnBuffer = Buffer;

+

+  while (Length-- > 0) {

+    *(Buffer++) = MmioRead8 (StartAddress++);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 16-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 16-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer.

+

+**/

+UINT16 *

+EFIAPI

+MmioReadBuffer16 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT16      *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = Buffer;

+

+  while (Length > 0) {

+    *(Buffer++) = MmioRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 32-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 32-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer.

+

+**/

+UINT32 *

+EFIAPI

+MmioReadBuffer32 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT32      *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = Buffer;

+

+  while (Length > 0) {

+    *(Buffer++) = MmioRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 64-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 64-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer.

+

+**/

+UINT64 *

+EFIAPI

+MmioReadBuffer64 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT64      *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = Buffer;

+

+  while (Length > 0) {

+    *(Buffer++) = MmioRead64 (StartAddress);

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 8-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 8-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer.

+

+**/

+UINT8 *

+EFIAPI

+MmioWriteBuffer8 (

+  IN  UINTN         StartAddress,

+  IN  UINTN         Length,

+  IN  CONST UINT8   *Buffer

+  )

+{

+  VOID* ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ReturnBuffer = (UINT8 *) Buffer;

+

+  while (Length-- > 0) {

+     MmioWrite8 (StartAddress++, *(Buffer++));

+  }

+

+  return ReturnBuffer;

+

+}

+

+/**

+  Copy data from system memory to MMIO region by using 16-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 16-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer.

+

+**/

+UINT16 *

+EFIAPI

+MmioWriteBuffer16 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT16 *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = (UINT16 *) Buffer;

+

+  while (Length > 0) {

+    MmioWrite16 (StartAddress, *(Buffer++));

+

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 32-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 32-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer.

+

+**/

+UINT32 *

+EFIAPI

+MmioWriteBuffer32 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT32 *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = (UINT32 *) Buffer;

+

+  while (Length > 0) {

+    MmioWrite32 (StartAddress, *(Buffer++));

+

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to MMIO region by using 64-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 64-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer.

+

+**/

+UINT64 *

+EFIAPI

+MmioWriteBuffer64 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT64 *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = (UINT64 *) Buffer;

+

+  while (Length > 0) {

+    MmioWrite64 (StartAddress, *(Buffer++));

+

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf
new file mode 100644
index 0000000..fdfc12b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.inf
@@ -0,0 +1,49 @@
+## @file

+# I/O Library instance that layers on top of Itanium ESAL services.

+#

+# I/O Library implementation that uses Itanium ESAL services for I/O

+#  and MMIO operations.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+# This program and the accompanying materials are licensed and made available

+# under the terms and conditions of the BSD License which accompanies this 

+# distribution. The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php.

+#

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeIoLibEsal

+  MODULE_UNI_FILE                = DxeIoLibEsal.uni

+  FILE_GUID                      = 0D8E6E4E-B029-475f-9122-60A3FEDBA8C0

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = IoLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  IoHighLevel.c

+  IoLib.c

+  IoLibMmioBuffer.c

+  DxeIoLibEsalInternal.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  ExtendedSalLib

+  BaseLib

+  DebugLib

+

+[Depex]

+  gEfiExtendedSalBaseIoServicesProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.uni b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.uni
new file mode 100644
index 0000000..f9d2135
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsal.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsalInternal.h b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsalInternal.h
new file mode 100644
index 0000000..c6dd4af
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/DxeIoLibEsalInternal.h
@@ -0,0 +1,28 @@
+/** @file

+  Internal include file for the I/O Library using ESAL services.

+  

+  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 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 __DXE_IO_LIB_ESAL_INTERNAL_H_

+#define __DXE_IO_LIB_ESAL_INTERNAL_H_

+

+#include <PiDxe.h>

+

+#include <Protocol/CpuIo2.h>

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/ExtendedSalLib.h>

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c
new file mode 100644
index 0000000..7b60219
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoHighLevel.c
@@ -0,0 +1,2303 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  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.

+

+**/

+

+#include "DxeIoLibEsalInternal.h"

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8)(IoRead8 (Port) | OrData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, (UINT8)(IoRead8 (Port) & AndData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8)((IoRead8 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, 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 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 value read from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16)(IoRead16 (Port) | OrData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, (UINT16)(IoRead16 (Port) & AndData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16)((IoRead16 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, 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 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 value read from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, 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 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value read from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the value read from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port 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  Port      The I/O port 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.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 value read from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, 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 I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 value read from the I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8)(MmioRead8 (Address) | OrData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, (UINT8)(MmioRead8 (Address) & AndData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8)((MmioRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register 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  Address   MMIO register to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register 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  Address   MMIO register to write.

+  @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 value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register 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  Address   MMIO register to write.

+  @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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register 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  Address   MMIO register to write.

+  @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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, 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 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register 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  Address   MMIO register to write.

+  @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 value read from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16)(MmioRead16 (Address) | OrData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, (UINT16)(MmioRead16 (Address) & AndData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16)((MmioRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register 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  Address   MMIO register to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register 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  Address   MMIO register to write.

+  @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 value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register 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  Address   MMIO register to write.

+  @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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register 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  Address   MMIO register to write.

+  @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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, 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 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register 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  Address   MMIO register to write.

+  @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 value read from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register 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  Address   MMIO register 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 value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register 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  Address   MMIO register 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 value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register 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  Address   MMIO register 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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register 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  Address   MMIO register 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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, 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 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register 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  Address   MMIO register 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 value read from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the value read from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register 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  Address   MMIO register 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.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register 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  Address   MMIO register 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 MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register 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  Address   MMIO register 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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register 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  Address   MMIO register 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 value read from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, 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 MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register 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  Address   MMIO register 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 value read from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoLib.c
new file mode 100644
index 0000000..81b28ec
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoLib.c
@@ -0,0 +1,605 @@
+/** @file

+  I/O Library basic function implementation and worker functions.

+

+  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

+  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 "DxeIoLibEsalInternal.h"

+

+/**

+  Reads registers in the EFI CPU I/O space.

+

+  Reads the I/O port specified by Port with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI CPU I/O space.

+

+**/

+UINT64

+EFIAPI

+IoReadWorker (

+  IN      UINTN                     Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width

+  )

+{

+  SAL_RETURN_REGS  ReturnReg;

+  UINT64           Data;

+

+  Data = 0;

+

+  ReturnReg = EsalCall (

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,

+                IoReadFunctionId, 

+                (UINT64)Width, 

+                Port, 

+                1, 

+                (UINT64)&Data, 

+                0, 

+                0, 

+                0

+                );

+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);

+  return Data;

+}

+

+/**

+  Writes registers in the EFI CPU I/O space.

+

+  Writes the I/O port specified by Port with registers width and value specified by Width

+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+

+  @return The paramter of Data.

+

+**/

+UINT64

+EFIAPI

+IoWriteWorker (

+  IN      UINTN                     Port,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,

+  IN      UINT64                    Data

+  )

+{

+  SAL_RETURN_REGS  ReturnReg;

+

+  ReturnReg = EsalCall (

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,

+                IoWriteFunctionId, 

+                (UINT64)Width, 

+                Port, 

+                1, 

+                (UINT64)&Data, 

+                0, 

+                0, 

+                0

+                );

+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);

+  return Data;

+}

+

+/**

+  Reads memory-mapped registers in the EFI system memory space.

+

+  Reads the MMIO registers specified by Address with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioReadWorker (

+  IN      UINTN                     Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width

+  )

+{

+  SAL_RETURN_REGS  ReturnReg;

+  UINT64           Data;

+

+  Data = 0;

+

+  ReturnReg = EsalCall (

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,

+                MemReadFunctionId, 

+                (UINT64)Width, 

+                Address, 

+                1, 

+                (UINT64)&Data, 

+                0, 

+                0, 

+                0

+                );

+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);

+  return Data;

+}

+

+/**

+  Writes memory-mapped registers in the EFI system memory space.

+

+  Writes the MMIO registers specified by Address with registers width and value specified by Width

+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to memory-mapped registers

+

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioWriteWorker (

+  IN      UINTN                     Address,

+  IN      EFI_CPU_IO_PROTOCOL_WIDTH Width,

+  IN      UINT64                    Data

+  )

+{

+  SAL_RETURN_REGS  ReturnReg;

+

+  ReturnReg = EsalCall (

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_LO,

+                EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID_HI,

+                MemWriteFunctionId, 

+                (UINT64)Width, 

+                Address, 

+                1, 

+                (UINT64)&Data, 

+                0, 

+                0, 

+                0

+                );

+  ASSERT (ReturnReg.Status == EFI_SAL_SUCCESS);

+  return Data;

+}

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value);

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value);

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value);

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoReadWorker (Port, EfiCpuIoWidthUint64);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value);

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8);

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value);

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16);

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value);

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32);

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value);

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64);

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoLibMmioBuffer.c b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoLibMmioBuffer.c
new file mode 100644
index 0000000..5addef2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeIoLibEsal/IoLibMmioBuffer.c
@@ -0,0 +1,411 @@
+/** @file

+  I/O Library MMIO Buffer Functions.

+

+  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

+  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 "DxeIoLibEsalInternal.h"

+

+/**

+  Copy data from MMIO region to system memory by using 8-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 8-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioReadBuffer8 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT8       *Buffer

+  )

+{

+  UINT8   *ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length-- > 0) {

+    *(Buffer++) = MmioRead8 (StartAddress++);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 16-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 16-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioReadBuffer16 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT16      *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length > 0) {

+    *(Buffer++) = MmioRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 32-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 32-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioReadBuffer32 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT32      *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length > 0) {

+    *(Buffer++) = MmioRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 64-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 64-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied from.

+  @param  Length          Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioReadBuffer64 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT64      *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length > 0) {

+    *(Buffer++) = MmioRead64 (StartAddress);

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 8-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 8-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioWriteBuffer8 (

+  IN  UINTN         StartAddress,

+  IN  UINTN         Length,

+  IN  CONST UINT8   *Buffer

+  )

+{

+  VOID* ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+ 

+  ReturnBuffer = (UINT8 *) Buffer;

+  

+  while (Length-- > 0) {

+     MmioWrite8 (StartAddress++, *(Buffer++));

+  }

+

+  return ReturnBuffer;

+ 

+}

+

+/**

+  Copy data from system memory to MMIO region by using 16-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 16-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioWriteBuffer16 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT16 *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = (UINT16 *) Buffer;

+  

+  while (Length > 0) {

+    MmioWrite16 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 32-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 32-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioWriteBuffer32 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT32 *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = (UINT32 *) Buffer;

+  

+  while (Length > 0) {

+    MmioWrite32 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to MMIO region by using 64-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 64-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    Starting address for the MMIO region to be copied to.

+  @param  Length     Size in bytes of the copy.

+  @param  Buffer          Pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioWriteBuffer64 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT64 *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = (UINT64 *) Buffer;

+  

+  while (Length > 0) {

+    MmioWrite64 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.c b/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.c
new file mode 100644
index 0000000..6500320
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.c
@@ -0,0 +1,73 @@
+/** @file

+  PAL Library Class implementation built upon Extended SAL Procedures.

+

+  Copyright (c) 2007 - 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

+  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 <PiDxe.h>

+

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/PalLib.h>

+#include <Library/ExtendedSalLib.h>

+

+/**

+  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. 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 4 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.

+  This function is only available on IPF.

+

+  @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

+PalCall (

+  IN UINT64                  Index,

+  IN UINT64                  Arg2,

+  IN UINT64                  Arg3,

+  IN UINT64                  Arg4

+  )

+{

+  SAL_RETURN_REGS SalReturn;

+  PAL_CALL_RETURN *PalReturn;

+

+  SalReturn = EsalCall (

+                EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,

+                EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,

+                PalProcFunctionId, 

+                Index, 

+                Arg2, 

+                Arg3, 

+                Arg4, 

+                0, 

+                0, 

+                0

+                );

+  PalReturn = (PAL_CALL_RETURN *) (UINTN) (&SalReturn);

+  return *PalReturn;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf b/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf
new file mode 100644
index 0000000..1340d29
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.inf
@@ -0,0 +1,41 @@
+## @file

+#  Instance of PAL Library Class using Extended SAL functions

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxePalLibEsal

+  MODULE_UNI_FILE                = DxePalLibEsal.uni

+  FILE_GUID                      = 8BA65DE3-39E1-4afd-A8FE-7DD0BAFEFCC0

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PalLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION 

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources.IPF]

+  DxePalLibEsal.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  ExtendedSalLib

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiExtendedSalPalServicesProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.uni b/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.uni
new file mode 100644
index 0000000..2bffc22
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePalLibEsal/DxePalLibEsal.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.c b/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.c
new file mode 100644
index 0000000..6f3a1b2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.c
@@ -0,0 +1,1187 @@
+/** @file

+Implementation of PcdLib class library for DXE phase.

+

+Copyright (c) 2006 - 2014, 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 <PiDxe.h>

+

+#include <Protocol/Pcd.h>

+#include <Protocol/PiPcd.h>

+#include <Protocol/PcdInfo.h>

+#include <Protocol/PiPcdInfo.h>

+

+#include <Library/PcdLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/BaseMemoryLib.h>

+

+PCD_PROTOCOL                *mPcd       = NULL;

+EFI_PCD_PROTOCOL            *mPiPcd     = NULL;

+GET_PCD_INFO_PROTOCOL       *mPcdInfo   = NULL;

+EFI_GET_PCD_INFO_PROTOCOL   *mPiPcdInfo = NULL;

+

+/**

+  Retrieves the PI PCD protocol from the handle database.

+

+  @retval EFI_PCD_PROTOCOL * The pointer to the EFI_PCD_PROTOCOL.

+**/

+EFI_PCD_PROTOCOL *

+EFIAPI

+GetPiPcdProtocol (

+  VOID

+  )

+{

+  EFI_STATUS  Status;

+

+  if (mPiPcd == NULL) {

+    //

+    // PI Pcd protocol defined in PI 1.2 vol3 should be installed before the module 

+    // access DynamicEx type PCD.

+    //

+    Status = gBS->LocateProtocol (&gEfiPcdProtocolGuid, NULL, (VOID **) &mPiPcd);

+    ASSERT_EFI_ERROR (Status);

+    ASSERT (mPiPcd != NULL);

+  }

+  return mPiPcd;

+}

+

+/**

+  Retrieves the PCD protocol from the handle database.

+

+  @retval PCD_PROTOCOL * The pointer to the PCD_PROTOCOL.

+**/

+PCD_PROTOCOL *

+EFIAPI

+GetPcdProtocol (

+  VOID

+  )

+{

+  EFI_STATUS  Status;

+

+  if (mPcd == NULL) {

+    //

+    // PCD protocol need to be installed before the module access Dynamic type PCD.

+    // But dynamic type PCD is not required in PI 1.2 specification.

+    // 

+    Status = gBS->LocateProtocol (&gPcdProtocolGuid, NULL, (VOID **)&mPcd);

+    ASSERT_EFI_ERROR (Status);

+    ASSERT (mPcd != NULL);

+  }

+  return mPcd;

+}

+

+/**

+  Retrieves the PI PCD info protocol from the handle database.

+

+  @retval EFI_GET_PCD_INFO_PROTOCOL * The pointer to the EFI_GET_PCD_INFO_PROTOCOL defined in PI 1.2.1 Vol 3.

+**/

+EFI_GET_PCD_INFO_PROTOCOL *

+GetPiPcdInfoProtocolPointer (

+  VOID

+  )

+{

+  EFI_STATUS  Status;

+

+  if (mPiPcdInfo == NULL) {

+    Status = gBS->LocateProtocol (&gEfiGetPcdInfoProtocolGuid, NULL, (VOID **)&mPiPcdInfo);

+    ASSERT_EFI_ERROR (Status);

+    ASSERT (mPiPcdInfo != NULL);

+  }

+  return mPiPcdInfo;

+}

+

+/**

+  Retrieves the PCD info protocol from the handle database.

+

+  @retval GET_PCD_INFO_PROTOCOL * The pointer to the GET_PCD_INFO_PROTOCOL.

+**/

+GET_PCD_INFO_PROTOCOL *

+GetPcdInfoProtocolPointer (

+  VOID

+  ) 

+{

+  EFI_STATUS  Status;

+

+  if (mPcdInfo == NULL) {

+    Status = gBS->LocateProtocol (&gGetPcdInfoProtocolGuid, NULL, (VOID **)&mPcdInfo);

+    ASSERT_EFI_ERROR (Status);

+    ASSERT (mPcdInfo != NULL);

+  }

+  return mPcdInfo;

+}

+

+/**

+  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.

+  If SkuId >= PCD_MAX_SKU_ID, then ASSERT(). 

+

+  @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 just be set.

+

+**/

+UINTN

+EFIAPI

+LibPcdSetSku (

+  IN UINTN   SkuId

+  )

+{

+  ASSERT (SkuId < PCD_MAX_SKU_ID);

+

+  GetPcdProtocol()->SetSku (SkuId);

+

+  return 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

+  )

+{

+  return GetPcdProtocol()->Get8 (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

+  )

+{

+  return GetPcdProtocol()->Get16 (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

+  )

+{

+  return GetPcdProtocol()->Get32 (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

+  )

+{

+  return GetPcdProtocol()->Get64 (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

+  )

+{

+  return GetPcdProtocol()->GetPtr (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

+  )

+{

+  return GetPcdProtocol()->GetBool (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

+  )

+{

+  return GetPcdProtocol()->GetSize (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         The 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

+  )

+{

+  ASSERT (Guid != NULL);

+  

+  return GetPiPcdProtocol()->Get8 (Guid, 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         The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return GetPiPcdProtocol()->Get16 (Guid, TokenNumber);

+}

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid         The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return GetPiPcdProtocol()->Get32 (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+  

+  return GetPiPcdProtocol()->Get64 (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return GetPiPcdProtocol()->GetPtr (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return GetPiPcdProtocol()->GetBool (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return GetPiPcdProtocol()->GetSize (Guid, TokenNumber);

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPcdProtocol()->Set8 (TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+  

+  return 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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPcdProtocol()->Set16 (TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+  

+  return 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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+  

+  Status = GetPcdProtocol()->Set32 (TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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.

+

+  If the set operation was not correctly performed, then ASSERT().

+  

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPcdProtocol()->Set64 (TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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,

+  or ASSERT() if the set operation was not correctly 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 been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetPtr (

+  IN        UINTN             TokenNumber,

+  IN OUT    UINTN             *SizeOfBuffer,

+  IN CONST  VOID              *Buffer

+  )

+{

+  EFI_STATUS Status;

+  UINTN      InputSizeOfBuffer;

+

+  ASSERT (SizeOfBuffer != NULL);

+

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+

+  InputSizeOfBuffer = *SizeOfBuffer;

+  Status = GetPcdProtocol()->SetPtr (TokenNumber, SizeOfBuffer, (VOID *) Buffer);

+  if (EFI_ERROR (Status) && (*SizeOfBuffer < InputSizeOfBuffer)) {

+    return NULL;

+  }

+  ASSERT_EFI_ERROR (Status);

+

+  return (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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPcdProtocol()->SetBool (TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = GetPiPcdProtocol()->Set8 (Guid, TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = GetPiPcdProtocol()->Set16 (Guid, TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT32            Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = GetPiPcdProtocol()->Set32 (Guid, TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = GetPiPcdProtocol()->Set64 (Guid, TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return 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, or ASSERT() if the set operation was not corretly 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              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, 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 been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN      CONST GUID        *Guid,

+  IN      UINTN             TokenNumber,

+  IN OUT  UINTN             *SizeOfBuffer,

+  IN      VOID              *Buffer

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       InputSizeOfBuffer;

+

+  ASSERT (Guid != NULL);

+

+  ASSERT (SizeOfBuffer != NULL);

+

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+

+  InputSizeOfBuffer = *SizeOfBuffer;

+  Status = GetPiPcdProtocol()->SetPtr (Guid, TokenNumber, SizeOfBuffer, Buffer);

+  if (EFI_ERROR (Status) && (*SizeOfBuffer < InputSizeOfBuffer)) {

+    return NULL;

+  }

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = GetPiPcdProtocol()->SetBool (Guid, TokenNumber, Value);

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  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                  The 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

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (NotificationFunction != NULL);

+

+  Status = GetPiPcdProtocol()->CallbackOnSet (Guid, TokenNumber, (EFI_PCD_PROTOCOL_CALLBACK) NotificationFunction);

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  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

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (NotificationFunction != NULL);

+    

+  Status = GetPiPcdProtocol()->CancelCallback (Guid, TokenNumber, (EFI_PCD_PROTOCOL_CALLBACK) NotificationFunction);

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  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        The 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

+  )

+{

+  EFI_STATUS    Status;

+

+  Status = GetPiPcdProtocol()->GetNextToken (Guid, &TokenNumber);

+  ASSERT (!EFI_ERROR (Status) || TokenNumber == 0);

+

+  return 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  The pointer to the a PCD token space GUID.

+

+  @return The next valid token namespace.

+

+**/

+GUID *

+EFIAPI

+LibPcdGetNextTokenSpace (

+  IN CONST GUID  *TokenSpaceGuid

+  )

+{

+  GetPiPcdProtocol()->GetNextTokenSpace (&TokenSpaceGuid);

+

+  return (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[in] 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 been set.

+

+**/

+VOID *

+EFIAPI

+LibPatchPcdSetPtr (

+  IN        VOID        *PatchVariable,

+  IN        UINTN       MaximumDatumSize,

+  IN OUT    UINTN       *SizeOfBuffer,

+  IN CONST  VOID        *Buffer

+  )

+{

+  ASSERT (PatchVariable != NULL);

+  ASSERT (SizeOfBuffer  != NULL);

+  

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+

+  if ((*SizeOfBuffer > MaximumDatumSize) ||

+      (*SizeOfBuffer == MAX_ADDRESS)) {

+    *SizeOfBuffer = MaximumDatumSize;

+    return NULL;

+  }

+    

+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);

+  

+  return (VOID *) Buffer;

+}

+

+/**

+  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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPcdInfoProtocolPointer()->GetInfo (TokenNumber, (EFI_PCD_INFO *) PcdInfo);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPiPcdInfoProtocolPointer()->GetInfo (Guid, TokenNumber, (EFI_PCD_INFO *) PcdInfo);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Retrieve the currently set SKU Id.

+

+  If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().

+

+  @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

+  )

+{

+  UINTN SkuId;

+

+  SkuId = GetPiPcdInfoProtocolPointer()->GetSku ();

+  ASSERT (SkuId < PCD_MAX_SKU_ID);

+

+  return SkuId;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.inf
new file mode 100644
index 0000000..23cd5d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -0,0 +1,68 @@
+## @file

+# Instance of PCD Library using PCD Protocol.

+#

+# There are two PCD protocols as follows:

+#   1) PCD_PROTOCOL

+#      It is EDKII implementation which support Dynamic/DynamicEx Pcds.

+#   2) EFI_PCD_PROTOCOL

+#      It is defined by PI specification 1.2, Vol 3 which only support dynamicEx 

+#      type Pcd.

+#

+# For dynamicEx type PCD, it is compatible between PCD_PROTOCOL and EFI_PCD_PROTOCOL.

+#

+# This library instance uses the PCD_PROTOCOL to handle dynamic PCD request and use

+# EFI_PCD_PROTOCOL to handle dynamicEx type PCD.

+#

+# Note: A driver of type DXE_RUNTIME_DRIVER and DXE_SMM_DRIVER can only use this DxePcdLib 

+#  in their initialization without any issues to access Dynamic and DynamicEx PCD. They can't 

+#  access Dynamic and DynamicEx PCD in the implementation of runtime services and SMI handlers.

+#  Because EFI_PCD_PROTOCOL is DXE protocol that is not aviable in OS runtime phase.  

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxePcdLib

+  MODULE_UNI_FILE                = DxePcdLib.uni

+  FILE_GUID                      = af97eb89-4cc6-45f8-a514-ca025b346480

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PcdLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER 

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DxePcdLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  UefiBootServicesTableLib

+  DebugLib

+

+

+[Protocols]

+  gPcdProtocolGuid                              ## SOMETIMES_CONSUMES

+  gEfiPcdProtocolGuid                           ## CONSUMES

+  gGetPcdInfoProtocolGuid                       ## SOMETIMES_CONSUMES

+  gEfiGetPcdInfoProtocolGuid                    ## SOMETIMES_CONSUMES

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiPcdProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.uni
new file mode 100644
index 0000000..dfc4070
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePcdLib/DxePcdLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf b/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf
new file mode 100644
index 0000000..da7772d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.inf
@@ -0,0 +1,40 @@
+## @file

+#  PCI Library that uses ESAL services to perform PCI Configuration cycles.

+#

+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxePciLibEsal

+  MODULE_UNI_FILE                = DxePciLibEsal.uni

+  FILE_GUID                      = E3441740-3B41-4c90-9C9D-964056C7417D

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  PciLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  ExtendedSalLib

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.uni b/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.uni
new file mode 100644
index 0000000..5c6f539
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/DxePciLibEsal.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/PciLib.c
new file mode 100644
index 0000000..43fcef1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePciLibEsal/PciLib.c
@@ -0,0 +1,1464 @@
+/** @file

+  DXE PCI Library instance layered on top of ESAL services.

+

+  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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/PciLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/ExtendedSalLib.h>

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \

+  ASSERT (((A) & (~0xfffffff | (M))) == 0)

+

+/**

+  Converts a PCI Library Address to a ESAL PCI Service Address.

+  Based on SAL Spec 3.2, there are two SAL PCI Address:

+

+  If address type = 0

+  Bits 0..7 - Register address

+  Bits 8..10 - Function number

+  Bits 11..15 - Device number

+  Bits 16..23 - Bus number

+  Bits 24..31 - PCI segment group

+  Bits 32..63 - Reserved (0)

+

+  If address type = 1

+  Bits 0..7 - Register address

+  Bits 8..11 - Extended Register address

+  Bits 12..14 - Function number

+  Bits 15..19 - Device number

+  Bits 20..27 - Bus number

+  Bits 28..43 - PCI segment group

+  Bits 44..63 - Reserved (0)

+

+  @param  A The PCI Library Address to convert.

+

+**/

+#define CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0(Address)  ((((Address) >> 4) & 0x00ffff00) | ((Address) & 0xff))

+#define CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1(Address)  (Address)

+

+/**

+  Check a PCI Library Address is a PCI Compatible Address or not.

+**/

+#define IS_PCI_COMPATIBLE_ADDRESS(Address)  (((Address) & 0xf00) == 0)

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EsalPciConfigRead function of Extended SAL PCI

+  Services Class.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   Width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+DxePciLibEsalReadWorker (

+  IN    UINTN                       Address,

+  IN    UINTN                       Width

+  )

+{

+ SAL_RETURN_REGS Return;

+

+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {

+    Return = EsalCall (

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+               SalPciConfigReadFunctionId,

+               CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),

+               Width,

+               EFI_SAL_PCI_COMPATIBLE_ADDRESS,

+               0,

+               0,

+               0,

+               0

+               );

+  } else {

+    Return = EsalCall (

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+               SalPciConfigReadFunctionId,

+               CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),

+               Width,

+               EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,

+               0,

+               0,

+               0,

+               0

+               );

+  }

+

+  return (UINT32) Return.r9;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EsalPciConfigWrite function of Extended SAL PCI

+  Services Class.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   Width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+DxePciLibEsalWriteWorker (

+  IN    UINTN                       Address,

+  IN    UINTN                       Width,

+  IN    UINT32                      Data

+  )

+{

+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {

+    EsalCall (

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+      SalPciConfigWriteFunctionId,

+      CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),

+      Width,

+      Data,

+      EFI_SAL_PCI_COMPATIBLE_ADDRESS,

+      0,

+      0,

+      0

+      );

+  } else {

+    EsalCall (

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+      SalPciConfigWriteFunctionId,

+      CONVERT_PCI_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),

+      Width,

+      Data,

+      EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,

+      0,

+      0,

+      0

+      );

+  }

+

+  return Data;

+}

+

+/**

+  Register a PCI device so PCI configuration registers may be accessed after

+  SetVirtualAddressMap().

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  return RETURN_SUCCESS;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciLibEsalReadWorker (Address, 1);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Data

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciLibEsalWriteWorker (Address, 1, Data);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8)(PciRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (Address, (UINT8)(PciRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8)((PciRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciLibEsalReadWorker (Address, 2);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Data

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciLibEsalWriteWorker (Address, 2, Data);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16)(PciRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (Address, (UINT16)(PciRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16)((PciRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return DxePciLibEsalReadWorker (Address, 4);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Data

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return DxePciLibEsalWriteWorker (Address, 4, Data);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    *(volatile UINT32 *)Buffer = PciRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    *(volatile UINT16 *)Buffer = PciRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciWrite16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciWrite32 (StartAddress, *(UINT32*)Buffer);

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciWrite16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegementLibEsal.uni b/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegementLibEsal.uni
new file mode 100644
index 0000000..0633619
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegementLibEsal.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf b/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf
new file mode 100644
index 0000000..dad1cec
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/DxePciSegmentLibEsal.inf
@@ -0,0 +1,40 @@
+## @file

+#  PCI Segment Library that uses ESAL services to perform PCI Configuration cycles.

+#

+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxePciSegementLibEsal

+  MODULE_UNI_FILE                = DxePciSegementLibEsal.uni

+  FILE_GUID                      = 6D497A7A-D7DA-467c-B485-B7FB3493C41F

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciSegmentLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  PciLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  ExtendedSalLib

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c
new file mode 100644
index 0000000..07ddd8f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxePciSegmentLibEsal/PciLib.c
@@ -0,0 +1,1416 @@
+/** @file

+  DXE PCI Segment Library instance layered on top of ESAL services.

+

+  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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/PciSegmentLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/ExtendedSalLib.h>

+

+/**

+  Assert the validity of a PCI Segment address.

+  A valid PCI Segment address should not contain 1's in bits 31:28

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \

+  ASSERT (((A) & (0xf0000000 | (M))) == 0)

+

+/**

+  Converts a PCI Library Address to a ESAL PCI Service Address.

+  Based on SAL Spec 3.2, there are two SAL PCI Address:

+

+  If address type = 0

+  Bits 0..7 - Register address

+  Bits 8..10 - Function number

+  Bits 11..15 - Device number

+  Bits 16..23 - Bus number

+  Bits 24..31 - PCI segment group

+  Bits 32..63 - Reserved (0)

+

+  If address type = 1

+  Bits 0..7 - Register address

+  Bits 8..11 - Extended Register address

+  Bits 12..14 - Function number

+  Bits 15..19 - Device number

+  Bits 20..27 - Bus number

+  Bits 28..43 - PCI segment group

+  Bits 44..63 - Reserved (0)

+

+  @param  A The PCI Library Address to convert.

+

+**/

+#define CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0(Address)  (((Address >> 8) & 0xff000000) | (((Address) >> 4) & 0x00ffff00) | ((Address) & 0xff))

+#define CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1(Address)  (((Address >> 4) & 0xffff0000000) | ((Address) & 0xfffffff))

+

+/**

+  Check a PCI Library Address is a PCI Compatible Address or not.

+**/

+#define IS_PCI_COMPATIBLE_ADDRESS(Address)  (((Address) & 0xf00) == 0)

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EsalPciConfigRead function of Extended SAL PCI

+  Services Class.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   Width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+DxePciSegmentLibEsalReadWorker (

+  IN  UINT64        Address,

+  IN  UINTN         Width

+  )

+{

+  SAL_RETURN_REGS Return;

+

+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {

+    Return = EsalCall (

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+               SalPciConfigReadFunctionId,

+               CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),

+               Width,

+               EFI_SAL_PCI_COMPATIBLE_ADDRESS,

+               0,

+               0,

+               0,

+               0

+               );

+  } else {

+    Return = EsalCall (

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+               EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+               SalPciConfigReadFunctionId,

+               CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),

+               Width,

+               EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,

+               0,

+               0,

+               0,

+               0

+               );

+  }

+

+  return (UINT32) Return.r9;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EsalPciConfigWrite function of Extended SAL PCI

+  Services Class.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address Address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   Width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+DxePciSegmentLibEsalWriteWorker (

+  IN  UINT64           Address,

+  IN  UINTN            Width,

+  IN  UINT32           Data

+  )

+{

+  if (IS_PCI_COMPATIBLE_ADDRESS(Address)) {

+    EsalCall (

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+      SalPciConfigWriteFunctionId,

+      CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS0 (Address),

+      Width,

+      Data,

+      EFI_SAL_PCI_COMPATIBLE_ADDRESS,

+      0,

+      0,

+      0

+      );

+  } else {

+    EsalCall (

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+      EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+      SalPciConfigWriteFunctionId,

+      CONVERT_PCI_SEGMENT_LIB_ADDRESS_TO_PCI_ESAL_ADDRESS1 (Address),

+      Width,

+      Data,

+      EFI_SAL_PCI_EXTENDED_REGISTER_ADDRESS,

+      0,

+      0,

+      0

+      );

+  }

+

+  return Data;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentRead8 (

+  IN      UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciSegmentLibEsalReadWorker (Address, 1);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentWrite8 (

+  IN      UINT64                    Address,

+  IN      UINT8                     Data

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciSegmentLibEsalWriteWorker (Address, 1, Data);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentOr8 (

+  IN      UINT64                    Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAnd8 (

+  IN      UINT64                    Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAndThenOr8 (

+  IN      UINT64                    Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldRead8 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldWrite8 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldOr8 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAnd8 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAndThenOr8 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentRead16 (

+  IN      UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciSegmentLibEsalReadWorker (Address, 2);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentWrite16 (

+  IN      UINT64                    Address,

+  IN      UINT16                    Data

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciSegmentLibEsalWriteWorker (Address, 2, Data);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentOr16 (

+  IN      UINT64                    Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAnd16 (

+  IN      UINT64                    Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAndThenOr16 (

+  IN      UINT64                    Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldRead16 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldWrite16 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldOr16 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAnd16 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAndThenOr16 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentRead32 (

+  IN      UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);

+

+  return DxePciSegmentLibEsalReadWorker (Address, 4);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentWrite32 (

+  IN      UINT64                    Address,

+  IN      UINT32                    Data

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);

+

+  return DxePciSegmentLibEsalWriteWorker (Address, 4, Data);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentOr32 (

+  IN      UINT64                    Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAnd32 (

+  IN      UINT64                    Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address Address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAndThenOr32 (

+  IN      UINT64                    Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldRead32 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register 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 value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldWrite32 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldOr32 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAnd32 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAndThenOr32 (

+  IN      UINT64                    Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting Address that encodes the PCI Segment, Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciSegmentReadBuffer (

+  IN      UINT64                    StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    *(volatile UINT16 *)Buffer = PciSegmentRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    *(volatile UINT32 *)Buffer = PciSegmentRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    *(volatile UINT16 *)Buffer = PciSegmentRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  Starting Address that encodes the PCI Segment, Bus, Device,

+                        Function and Register.

+  @param  Size          Size in bytes of the transfer.

+  @param  Buffer        Pointer to a buffer containing the data to write.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciSegmentWriteBuffer (

+  IN      UINT64                    StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciSegmentWrite16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciSegmentWrite32 (StartAddress, *(UINT32*)Buffer);

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciSegmentWrite16 (StartAddress, *(UINT16*)Buffer);

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
new file mode 100644
index 0000000..4bc09f9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.inf
@@ -0,0 +1,52 @@
+## @file

+#  This library implements the Extended SAL Library Class for use in boot services and runtime.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeRuntimeExtendedSalLib

+  MODULE_UNI_FILE                = DxeRuntimeExtendedSalLib.uni

+  FILE_GUID                      = AE66715B-75F5-4423-8FAD-A4AFB3C53ACF

+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ExtendedSalLib|DXE_RUNTIME_DRIVER DXE_SAL_DRIVER 

+  CONSTRUCTOR                    = DxeRuntimeExtendedSalLibConstruct

+  DESTRUCTOR                     = DxeRuntimeExtendedSalLibDeconstruct

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources.IPF]

+  ExtendedSalLib.c

+  Ipf/AsmExtendedSalLib.s

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+  UefiRuntimeServicesTableLib

+  DebugLib

+

+[Protocols]

+  gEfiExtendedSalBootServiceProtocolGuid        ## CONSUMES

+

+[Guids]

+  gEfiEventVirtualAddressChangeGuid   ## CONSUMES  ## Event

+

+[Depex]

+  gEfiExtendedSalBootServiceProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.uni
new file mode 100644
index 0000000..7fd295d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/DxeRuntimeExtendedSalLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/ExtendedSalLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/ExtendedSalLib.c
new file mode 100644
index 0000000..f9e974b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/ExtendedSalLib.c
@@ -0,0 +1,1124 @@
+/** @file

+  This library implements the Extended SAL Library Class for use in boot services and runtime.

+

+  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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/ExtendedSalBootService.h>

+#include <Protocol/ExtendedSalServiceClasses.h>

+#include <Guid/EventGroup.h>

+

+#include <Library/ExtendedSalLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/UefiRuntimeLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Stores the virtual plabel of ESAL entrypoint.

+

+  This assembly function stores the virtual plabel of ESAL entrypoint

+  where GetEsalEntryPoint() can easily retrieve.

+

+  @param  EntryPoint  Virtual address of ESAL entrypoint

+  @param  Gp          Virtual GP of ESAL entrypoint

+

+  @return r8 = EFI_SAL_SUCCESS

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+SetEsalVirtualEntryPoint (

+  IN  UINT64  EntryPoint,

+  IN  UINT64  Gp

+  );

+

+/**

+  Stores the physical plabel of ESAL entrypoint.

+

+  This assembly function stores the physical plabel of ESAL entrypoint

+  where GetEsalEntryPoint() can easily retrieve.

+

+  @param  EntryPoint  Physical address of ESAL entrypoint

+  @param  Gp          Physical GP of ESAL entrypoint

+

+  @return r8 = EFI_SAL_SUCCESS

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+SetEsalPhysicalEntryPoint (

+  IN  UINT64  EntryPoint,

+  IN  UINT64  Gp

+  );

+

+/**

+  Retrieves plabel of ESAL entrypoint.

+

+  This function retrives plabel of ESAL entrypoint stored by

+  SetEsalPhysicalEntryPoint().

+

+  @return r8  = EFI_SAL_SUCCESS

+          r9  = Physical Plabel

+          r10 = Virtual Plabel

+          r11 = PSR

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+GetEsalEntryPoint (

+  VOID

+  );

+

+EXTENDED_SAL_BOOT_SERVICE_PROTOCOL  *mEsalBootService = NULL;

+EFI_PLABEL                          mPlabel;

+EFI_EVENT                           mEfiVirtualNotifyEvent;

+

+/**

+  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE to set virtual plabel of

+  ESAL entrypoint.

+

+  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.

+  It converts physical plabel of ESAL entrypoint to virtual plabel and stores it where

+  GetEsalEntryPoint() can easily retrieve.

+

+  @param  Event        Event whose notification function is being invoked.

+  @param  Context      Pointer to the notification function's context

+

+**/

+VOID

+EFIAPI

+ExtendedSalVirtualNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+{

+  UINT64  PhysicalEntryPoint;

+

+  PhysicalEntryPoint = mPlabel.EntryPoint;

+

+  gRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);

+

+  mPlabel.GP += mPlabel.EntryPoint - PhysicalEntryPoint;

+

+  SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);

+}

+

+/**

+  Gets Extended SAL Boot Service Protocol, and initializes physical plabel of

+  ESAL entrypoint.

+

+  This function first locates Extended SAL Boot Service Protocol and caches it in global variable.

+  Then it initializes the physical plable of ESAL entrypoint, and stores

+  it where GetEsalEntryPoint() can easily retrieve.

+

+  @retval  EFI_SUCCESS  Plable of ESAL entrypoint successfully stored.

+

+**/

+EFI_STATUS

+DxeSalLibInitialize (

+  VOID

+  )

+{

+  EFI_PLABEL  *Plabel;

+  EFI_STATUS  Status;

+

+  //

+  // The protocol contains a function pointer, which is an indirect procedure call.

+  // An indirect procedure call goes through a plabel, and pointer to a function is

+  // a pointer to a plabel. To implement indirect procedure calls that can work in

+  // both physical and virtual mode, two plabels are required (one physical and one

+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it

+  // away. We cache it in a module global, so we can register the vitrual version.

+  //

+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, (VOID **) &mEsalBootService);

+  ASSERT_EFI_ERROR (Status);

+

+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;

+  mPlabel.EntryPoint  = Plabel->EntryPoint;

+  mPlabel.GP          = Plabel->GP;

+  //

+  // Stores the physical plabel of ESAL entrypoint where GetEsalEntryPoint() can easily retrieve.

+  //

+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Constructor function to initializes physical plabel of ESAL entrypoint and register an event

+  for initialization of virtual plabel of ESAL entrypoint.

+  

+  This is the library constructor function to call a function to initialize physical plabel of ESAL entrypoint

+  and to register notification function for 

+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which sets virtual plabel of ESAL entrypoint.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   Notification function successfully registered.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeRuntimeExtendedSalLibConstruct (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE

+  //

+  ASSERT (gBS != NULL);

+

+  DxeSalLibInitialize ();

+

+  Status = gBS->CreateEventEx (

+                  EVT_NOTIFY_SIGNAL,

+                  TPL_NOTIFY,

+                  ExtendedSalVirtualNotifyEvent,

+                  NULL,

+                  &gEfiEventVirtualAddressChangeGuid,

+                  &mEfiVirtualNotifyEvent

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Destructor function to close the event created by the library constructor 

+  

+  This is the library destructor function to close the event with type of 

+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, which is created by the library constructor.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   Event successfully closed.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeRuntimeExtendedSalLibDeconstruct (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Close SetVirtualAddressMap () notify function

+  //

+  ASSERT (gBS != NULL);

+  Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Registers function of ESAL class and it's associated global.

+  

+  This function registers function of ESAL class, together with its associated global.

+  It is worker function for RegisterEsalClass().

+  It is only for boot time.

+

+  @param  FunctionId     ID of function to register

+  @param  ClassGuidLo    GUID of ESAL class, lower 64-bits

+  @param  ClassGuidHi    GUID of ESAL class, upper 64-bits

+  @param  Function       Function to register with ClassGuid/FunctionId pair

+  @param  ModuleGlobal   Module global for the function.

+

+  @return Status returned by RegisterExtendedSalProc() of Extended SAL Boot Service Protocol

+

+**/

+EFI_STATUS

+RegisterEsalFunction (

+  IN  UINT64                                    FunctionId,

+  IN  UINT64                                    ClassGuidLo,

+  IN  UINT64                                    ClassGuidHi,

+  IN  SAL_INTERNAL_EXTENDED_SAL_PROC            Function,

+  IN  VOID                                      *ModuleGlobal

+  )

+{

+  return mEsalBootService->RegisterExtendedSalProc (

+                             mEsalBootService,

+                             ClassGuidLo,

+                             ClassGuidHi,

+                             FunctionId,

+                             Function,

+                             ModuleGlobal

+                             );

+}

+

+/**

+  Registers ESAL Class and it's associated global.

+  

+  This function registers one or more Extended SAL services in a given

+  class along with the associated global context.

+  This function is only available prior to ExitBootServices().

+

+  @param  ClassGuidLo          GUID of function class, lower 64-bits

+  @param  ClassGuidHi          GUID of function class, upper 64-bits

+  @param  ModuleGlobal         Module global for the class.

+  @param  ...                  List of Function/FunctionId pairs, ended by NULL

+

+  @retval EFI_SUCCESS          The Extended SAL services were registered.

+  @retval EFI_UNSUPPORTED      This function was called after ExitBootServices().

+  @retval EFI_OUT_OF_RESOURCES There are not enough resources available to register one or more of the specified services.

+  @retval Other                ClassGuid could not be installed onto a new handle.  

+

+**/

+EFI_STATUS

+EFIAPI

+RegisterEsalClass (

+  IN  CONST UINT64    ClassGuidLo,

+  IN  CONST UINT64    ClassGuidHi,

+  IN  VOID            *ModuleGlobal,  OPTIONAL

+  ...

+  )

+{

+  VA_LIST                         Args;

+  EFI_STATUS                      Status;

+  SAL_INTERNAL_EXTENDED_SAL_PROC  Function;

+  UINT64                          FunctionId;

+  EFI_HANDLE                      NewHandle;

+  EFI_GUID                        ClassGuid;

+

+  VA_START (Args, ModuleGlobal);

+

+  //

+  // Register all functions of the class to register.

+  //

+  Status = EFI_SUCCESS;

+  while (!EFI_ERROR (Status)) {

+    Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC);

+    //

+    // NULL serves as the end mark of function list

+    //

+    if (Function == NULL) {

+      break;

+    }

+

+    FunctionId  = VA_ARG (Args, UINT64);

+

+    Status      = RegisterEsalFunction (FunctionId, ClassGuidLo, ClassGuidHi, Function, ModuleGlobal);

+  }

+

+  VA_END (Args);

+

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  NewHandle = NULL;

+  *((UINT64 *)(&ClassGuid) + 0) = ClassGuidLo;

+  *((UINT64 *)(&ClassGuid) + 1) = ClassGuidHi;

+  return gBS->InstallProtocolInterface (

+                &NewHandle,

+                &ClassGuid,

+                EFI_NATIVE_INTERFACE,

+                NULL

+                );

+}

+

+/**

+  Calls an Extended SAL Class service that was previously registered with RegisterEsalClass().

+  

+  This function gets the entrypoint of Extended SAL, and calls an Extended SAL Class service

+  that was previously registered with RegisterEsalClass() through this entrypoint.

+

+  @param  ClassGuidLo     GUID of function, lower 64-bits

+  @param  ClassGuidHi     GUID of function, upper 64-bits

+  @param  FunctionId      Function in ClassGuid to call

+  @param  Arg2            Argument 2 ClassGuid/FunctionId defined

+  @param  Arg3            Argument 3 ClassGuid/FunctionId defined

+  @param  Arg4            Argument 4 ClassGuid/FunctionId defined

+  @param  Arg5            Argument 5 ClassGuid/FunctionId defined

+  @param  Arg6            Argument 6 ClassGuid/FunctionId defined

+  @param  Arg7            Argument 7 ClassGuid/FunctionId defined

+  @param  Arg8            Argument 8 ClassGuid/FunctionId defined

+  

+  @retval EFI_SAL_SUCCESS ESAL procedure successfully called.

+  @retval EFI_SAL_ERROR   The address of ExtendedSalProc() can not be correctly

+                          initialized.

+  @retval Other           Status returned from ExtendedSalProc() service of

+                          EXTENDED_SAL_BOOT_SERVICE_PROTOCOL.  

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalCall (

+  IN  UINT64    ClassGuidLo,

+  IN  UINT64    ClassGuidHi,

+  IN  UINT64    FunctionId,

+  IN  UINT64    Arg2,

+  IN  UINT64    Arg3,

+  IN  UINT64    Arg4,

+  IN  UINT64    Arg5,

+  IN  UINT64    Arg6,

+  IN  UINT64    Arg7,

+  IN  UINT64    Arg8

+  )

+{

+  SAL_RETURN_REGS       ReturnReg;

+  EXTENDED_SAL_PROC     EsalProc;

+

+  //

+  // Get the entrypoint of Extended SAL

+  //

+  ReturnReg = GetEsalEntryPoint ();

+  if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) {

+    //

+    // The ESAL Entry Point could not be initialized

+    //

+    ReturnReg.Status = EFI_SAL_ERROR;

+    return ReturnReg;

+  }

+

+  //

+  // Test PSR.it which is BIT36

+  //

+  if ((ReturnReg.r11 & BIT36) != 0) {

+    //

+    // Virtual mode plabel to entry point

+    //

+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r10;

+  } else {

+    //

+    // Physical mode plabel to entry point

+    //

+    EsalProc = (EXTENDED_SAL_PROC) ReturnReg.r9;

+  }

+

+  return EsalProc (

+           ClassGuidLo,

+           ClassGuidHi,

+           FunctionId,

+           Arg2,

+           Arg3,

+           Arg4,

+           Arg5,

+           Arg6,

+           Arg7,

+           Arg8

+           );

+}

+

+/**

+  Wrapper for the EsalStallFunctionId service of Extended SAL Stall Services Class.

+  

+  This function is a wrapper for the EsalStallFunctionId service of Extended SAL

+  Stall Services Class. See EsalStallFunctionId of Extended SAL Specification.

+

+  @param  Microseconds         The number of microseconds to delay.

+

+  @retval EFI_SAL_SUCCESS               Call completed without error.

+  @retval EFI_SAL_INVALID_ARGUMENT      Invalid argument.

+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR Virtual address not registered

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalStall (

+  IN UINTN  Microseconds

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO, 

+           EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI, 

+           StallFunctionId, 

+           Microseconds, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.

+  

+  This function is a wrapper for the EsalSetNewPalEntryFunctionId service of Extended SAL

+  PAL Services Services Class. See EsalSetNewPalEntryFunctionId of Extended SAL Specification.

+

+  @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.

+                                 If FALSE, then PalEntryPoint is a virtual address.

+  @param  PalEntryPoint          The PAL Entry Point being set.

+

+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was set.

+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before

+                                         virtual mappings for the specified Extended SAL

+                                         Procedure are available.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalSetNewPalEntry (

+  IN BOOLEAN  PhysicalAddress,

+  IN UINT64   PalEntryPoint

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO, 

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,

+           SetNewPalEntryFunctionId, 

+           PhysicalAddress, 

+           PalEntryPoint, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL PAL Services Services Class.

+  

+  This function is a wrapper for the EsalGetNewPalEntryFunctionId service of Extended SAL

+  PAL Services Services Class. See EsalGetNewPalEntryFunctionId of Extended SAL Specification.

+

+  @param  PhysicalAddress        If TRUE, then PalEntryPoint is a physical address.

+                                 If FALSE, then PalEntryPoint is a virtual address.

+

+  @retval EFI_SAL_SUCCESS                The PAL Entry Point was retrieved and returned in

+                                         SAL_RETURN_REGS.r9.

+  @retval EFI_SAL_VIRTUAL_ADDRESS_ERROR  This function was called in virtual mode before

+                                         virtual mappings for the specified Extended SAL

+                                         Procedure are available.

+  @return r9                             PAL entry point retrieved.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetNewPalEntry (

+  IN BOOLEAN  PhysicalAddress

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,

+           GetNewPalEntryFunctionId, 

+           PhysicalAddress, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetStateBufferFunctionId service of Extended SAL MCA Log Services Class.

+  

+  This function is a wrapper for the EsalGetStateBufferFunctionId service of Extended SAL

+  MCA Log Services Class. See EsalGetStateBufferFunctionId of Extended SAL Specification.

+

+  @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.

+  @param  McaBuffer             A pointer to the base address of the returned buffer.

+                                Copied from SAL_RETURN_REGS.r9.

+  @param  BufferSize            A pointer to the size, in bytes, of the returned buffer.

+                                Copied from SAL_RETURN_REGS.r10.

+

+  @retval EFI_SAL_SUCCESS       The memory buffer to store error records was returned in r9 and r10.

+  @retval EFI_OUT_OF_RESOURCES  A memory buffer for string error records in not available

+  @return r9                    Base address of the returned buffer

+  @return r10                   Size of the returned buffer in bytes

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetStateBuffer (

+  IN  UINT64  McaType,

+  OUT UINT8   **McaBuffer,

+  OUT UINTN   *BufferSize

+  )

+{

+  SAL_RETURN_REGS Regs;

+

+  Regs = EsalCall (

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+           EsalGetStateBufferFunctionId, 

+           McaType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+

+  *McaBuffer  = (UINT8 *) Regs.r9;

+  *BufferSize = Regs.r10;

+

+  return Regs;

+}

+

+/**

+  Wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL MCA Log Services Class.

+  

+  This function is a wrapper for the EsalSaveStateBufferFunctionId service of Extended SAL

+  MCA Log Services Class. See EsalSaveStateBufferFunctionId of Extended SAL Specification.

+  

+  @param  McaType         See type parameter of SAL Procedure SAL_GET_STATE_INFO.

+

+  @retval EFI_SUCCESS  The memory buffer containing the error record was written to nonvolatile storage.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalSaveStateBuffer (

+  IN  UINT64  McaType

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+           EsalSaveStateBufferFunctionId, 

+           McaType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetVectorsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalGetVectorsFunctionId service of Extended SAL

+  Base Services Class. See EsalGetVectorsFunctionId of Extended SAL Specification.

+

+  @param  VectorType         The vector type to retrieve.

+                             0 - MCA, 1 - BSP INIT, 2 - BOOT_RENDEZ, 3 - AP INIT.

+

+  @retval EFI_SAL_SUCCESS          Call completed without error.

+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.

+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered

+                                   with the SAL Procedure SAL_SET_VECTORS.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetVectors (

+  IN  UINT64  VectorType

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalGetVectorsFunctionId, 

+           VectorType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL

+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.

+

+  @param  ParamInfoType         The parameter type to retrieve.

+                                1 - rendezvous interrupt

+                                2 - wake up

+                                3 - Corrected Platform Error Vector.

+

+  @retval EFI_SAL_SUCCESS          Call completed without error.

+  @retval EFI_SAL_INVALID_ARGUMENT Invalid argument.

+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered

+                                   with the SAL Procedure SAL_MC_SET_PARAMS.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcGetParams (

+  IN  UINT64  ParamInfoType

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalMcGetParamsFunctionId, 

+           ParamInfoType, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalMcGetParamsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalMcGetParamsFunctionId service of Extended SAL

+  Base Services Class. See EsalMcGetParamsFunctionId of Extended SAL Specification.

+  

+  @retval EFI_SAL_SUCCESS          Call completed without error.

+  @retval EFI_SAL_NO_INFORMATION   The requested vector has not been registered

+                                   with the SAL Procedure SAL_MC_SET_PARAMS.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcGetMcParams (

+  VOID

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalMcGetMcParamsFunctionId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL Base Services Class.

+  

+  This function is a wrapper for the EsalGetMcCheckinFlagsFunctionId service of Extended SAL

+  Base Services Class. See EsalGetMcCheckinFlagsFunctionId of Extended SAL Specification.

+

+  @param  CpuIndex         The index of the CPU of set of enabled CPUs to check.

+

+  @retval EFI_SAL_SUCCESS  The checkin status of the requested CPU was returned.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetMcCheckinFlags (

+  IN  UINT64  CpuIndex

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+           EsalGetMcCheckinFlagsFunctionId, 

+           CpuIndex, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalAddCpuDataFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalAddCpuDataFunctionId service of Extended SAL

+  MP Services Class. See EsalAddCpuDataFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId         The Global ID for the CPU being added.

+  @param  Enabled             The enable flag for the CPU being added.

+                              TRUE means the CPU is enabled.

+                              FALSE means the CPU is disabled.

+  @param  PalCompatibility    The PAL Compatibility value for the CPU being added.

+

+  @retval EFI_SAL_SUCCESS             The CPU was added to the database.

+  @retval EFI_SAL_NOT_ENOUGH_SCRATCH  There are not enough resource available to add the CPU.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalAddCpuData (

+  IN UINT64   CpuGlobalId,

+  IN BOOLEAN  Enabled,

+  IN UINT64   PalCompatibility

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           AddCpuDataFunctionId, 

+           CpuGlobalId, 

+           Enabled, 

+           PalCompatibility, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalRemoveCpuDataFunctionId service of Extended SAL

+  MP Services Class. See EsalRemoveCpuDataFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId         The Global ID for the CPU being removed.

+

+  @retval EFI_SAL_SUCCESS         The CPU was removed from the database.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalRemoveCpuData (

+  IN UINT64  CpuGlobalId

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           RemoveCpuDataFunctionId, 

+           CpuGlobalId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalModifyCpuDataFunctionId service of Extended SAL

+  MP Services Class. See EsalModifyCpuDataFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId         The Global ID for the CPU being modified.

+  @param  Enabled             The enable flag for the CPU being modified.

+                              TRUE means the CPU is enabled.

+                              FALSE means the CPU is disabled.

+  @param  PalCompatibility    The PAL Compatibility value for the CPU being modified.

+

+  @retval EFI_SAL_SUCCESS         The CPU database was updated.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalModifyCpuData (

+  IN UINT64   CpuGlobalId,

+  IN BOOLEAN  Enabled,

+  IN UINT64   PalCompatibility

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           ModifyCpuDataFunctionId, 

+           CpuGlobalId, 

+           Enabled, 

+           PalCompatibility, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalGetCpuDataByIdFunctionId service of Extended SAL

+  MP Services Class. See EsalGetCpuDataByIdFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId         The Global ID for the CPU being looked up.

+  @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.

+                              If FALSE, then the index of set of all CPUs of database is returned.

+

+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetCpuDataById (

+  IN UINT64   CpuGlobalId,

+  IN BOOLEAN  IndexByEnabledCpu

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           GetCpuDataByIDFunctionId, 

+           CpuGlobalId, 

+           IndexByEnabledCpu, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalGetCpuDataByIndexFunctionId service of Extended SAL

+  MP Services Class. See EsalGetCpuDataByIndexFunctionId of Extended SAL Specification.

+

+  @param  Index               The Global ID for the CPU being modified.

+  @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.

+                              If FALSE, then the index of set of all CPUs of database is returned.

+

+  @retval EFI_SAL_SUCCESS         The information on the specified CPU was returned.

+  @retval EFI_SAL_NO_INFORMATION  The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetCpuDataByIndex (

+  IN UINT64   Index,

+  IN BOOLEAN  IndexByEnabledCpu

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           GetCpuDataByIndexFunctionId, 

+           Index, 

+           IndexByEnabledCpu, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalWhoAmIFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalWhoAmIFunctionId service of Extended SAL

+  MP Services Class. See EsalWhoAmIFunctionId of Extended SAL Specification.

+

+  @param  IndexByEnabledCpu   If TRUE, then the index of set of enabled CPUs of database is returned.

+                              If FALSE, then the index of set of all CPUs of database is returned.

+

+  @retval EFI_SAL_SUCCESS         The Global ID for the calling CPU was returned.

+  @retval EFI_SAL_NO_INFORMATION  The calling CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalWhoAmI (

+  IN BOOLEAN  IndexByEnabledCpu

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           CurrentProcInfoFunctionId, 

+           IndexByEnabledCpu, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalNumProcessors service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalNumProcessors service of Extended SAL

+  MP Services Class. See EsalNumProcessors of Extended SAL Specification.

+

+  @retval EFI_SAL_SUCCESS    The information on the number of CPUs in the platform

+                             was returned.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalNumProcessors (

+  VOID

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           NumProcessorsFunctionId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalSetMinStateFnctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalSetMinStateFnctionId service of Extended SAL

+  MP Services Class. See EsalSetMinStateFnctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId       The Global ID for the CPU whose MINSTATE pointer is being set.

+  @param  MinStatePointer          The physical address of the MINSTATE buffer for the CPU

+                                   specified by CpuGlobalId.

+

+  @retval EFI_SAL_SUCCESS          The MINSTATE pointer was set for the specified CPU.

+  @retval EFI_SAL_NO_INFORMATION   The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalSetMinState (

+  IN UINT64                CpuGlobalId,

+  IN EFI_PHYSICAL_ADDRESS  MinStatePointer

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           SetMinStateFunctionId, 

+           CpuGlobalId, 

+           MinStatePointer, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalGetMinStateFunctionId service of Extended SAL MP Services Class.

+  

+  This function is a wrapper for the EsalGetMinStateFunctionId service of Extended SAL

+  MP Services Class. See EsalGetMinStateFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId   The Global ID for the CPU whose MINSTATE pointer is being retrieved.

+

+  @retval EFI_SAL_SUCCESS        The MINSTATE pointer for the specified CPU was retrieved.

+  @retval EFI_SAL_NO_INFORMATION The specified CPU is not in the database.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalGetMinState (

+  IN UINT64  CpuGlobalId

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MP_SERVICES_PROTOCOL_GUID_HI,

+           GetMinStateFunctionId, 

+           CpuGlobalId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

+

+/**

+  Wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL MCA Services Class.

+  

+  This function is a wrapper for the EsalMcsGetStateInfoFunctionId service of Extended SAL

+  MCA Services Class. See EsalMcsGetStateInfoFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId               The Global ID for the CPU whose MCA state buffer is being retrieved.

+  @param  StateBufferPointer        A pointer to the returned MCA state buffer.

+  @param  RequiredStateBufferSize   A pointer to the size, in bytes, of the returned MCA state buffer.

+

+  @retval EFI_SUCCESS               MINSTATE successfully got and size calculated.

+  @retval EFI_SAL_NO_INFORMATION    Fail to get MINSTATE.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcaGetStateInfo (

+  IN  UINT64                CpuGlobalId,

+  OUT EFI_PHYSICAL_ADDRESS  *StateBufferPointer,

+  OUT UINT64                *RequiredStateBufferSize

+  )

+{

+  SAL_RETURN_REGS  Regs;

+

+  Regs = EsalCall (

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,

+           McaGetStateInfoFunctionId, 

+           CpuGlobalId, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+

+  *StateBufferPointer      = (EFI_PHYSICAL_ADDRESS) Regs.r9;

+  *RequiredStateBufferSize = (UINT64) Regs.r10;

+

+  return Regs;

+}

+

+/**

+  Wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL MCA Services Class.

+  

+  This function is a wrapper for the EsalMcaRegisterCpuFunctionId service of Extended SAL

+  MCA Services Class. See EsalMcaRegisterCpuFunctionId of Extended SAL Specification.

+

+  @param  CpuGlobalId          The Global ID for the CPU whose MCA state buffer is being set.

+  @param  StateBufferPointer   A pointer to the MCA state buffer.

+

+  @retval EFI_SAL_NO_INFORMATION   Cannot get the processor info with the CpuId

+  @retval EFI_SUCCESS              Save the processor's state info successfully

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+EsalMcaRegisterCpu (

+  IN UINT64                CpuGlobalId,

+  IN EFI_PHYSICAL_ADDRESS  StateBufferPointer

+  )

+{

+  return EsalCall (

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_LO,

+           EFI_EXTENDED_SAL_MCA_SERVICES_PROTOCOL_GUID_HI,

+           McaRegisterCpuFunctionId, 

+           CpuGlobalId, 

+           StateBufferPointer, 

+           0, 

+           0, 

+           0, 

+           0, 

+           0

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/Ipf/AsmExtendedSalLib.s b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/Ipf/AsmExtendedSalLib.s
new file mode 100644
index 0000000..ddabc76
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimeExtendedSalLib/Ipf/AsmExtendedSalLib.s
@@ -0,0 +1,131 @@
+/// @file

+///  Assembly procedures to get and set ESAL entry point.

+///

+/// 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

+/// 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.

+///

+

+.auto

+.text

+

+#include  "IpfMacro.i"

+

+//

+// Exports

+//

+ASM_GLOBAL GetEsalEntryPoint

+

+//-----------------------------------------------------------------------------

+//++

+// GetEsalEntryPoint

+//

+// Return Esal global and PSR register.

+//

+// On Entry :

+//

+//

+// Return Value:

+//        r8  = EFI_SAL_SUCCESS

+//        r9  = Physical Plabel

+//        r10 = Virtual Plabel

+//        r11 = psr

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (GetEsalEntryPoint)

+

+      NESTED_SETUP (0,8,0,0)

+

+EsalCalcStart:

+      mov   r8  = ip;;

+      add   r8  = (EsalEntryPoint - EsalCalcStart), r8;;

+      mov   r9  = r8;;

+      add   r10 = 0x10, r8;;

+      mov   r11 = psr;;

+      mov   r8  = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (GetEsalEntryPoint)

+

+//-----------------------------------------------------------------------------

+//++

+// SetEsalPhysicalEntryPoint

+//

+// Set the dispatcher entry point

+//

+// On Entry:

+//  in0 = Physical address of Esal Dispatcher

+//  in1 = Physical GP

+//

+// Return Value: 

+//   r8 = EFI_SAL_SUCCESS

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (SetEsalPhysicalEntryPoint)

+

+      NESTED_SETUP (2,8,0,0)

+

+EsalCalcStart1:

+      mov   r8   = ip;;

+      add   r8   = (EsalEntryPoint - EsalCalcStart1), r8;;

+      st8   [r8] = in0;;

+      add   r8   = 0x08, r8;;

+      st8   [r8] = in1;;

+      mov   r8   = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (SetEsalPhysicalEntryPoint)

+

+//-----------------------------------------------------------------------------

+//++

+// SetEsalVirtualEntryPoint

+//

+// Register physical address of Esal globals.

+//

+// On Entry :

+//  in0 = Virtual address of Esal Dispatcher

+//  in1 = Virtual GP

+//

+// Return Value: 

+//  r8 = EFI_SAL_ERROR

+// 

+// As per static calling conventions. 

+// 

+//--

+//---------------------------------------------------------------------------

+PROCEDURE_ENTRY (SetEsalVirtualEntryPoint)

+

+      NESTED_SETUP (2,8,0,0)

+

+EsalCalcStart2:

+      mov   r8   = ip;;

+      add   r8   = (EsalEntryPoint - EsalCalcStart2), r8;;

+      add   r8   = 0x10, r8;;

+      st8   [r8] = in0;;

+      add   r8   = 0x08, r8;;

+      st8   [r8] = in1;;

+      mov   r8   = r0;;

+

+      NESTED_RETURN

+

+PROCEDURE_EXIT (SetEsalVirtualEntryPoint)

+

+.align 32

+EsalEntryPoint: 

+    data8 0   // Physical Entry

+    data8 0   //         GP

+    data8 0   // Virtual Entry

+    data8 0   //         GP

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.inf
new file mode 100644
index 0000000..5d73570
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.inf
@@ -0,0 +1,58 @@
+## @file

+# Instance of PCI Express Library using the 256 MB PCI Express MMIO window that 

+# is safe for runtime use.

+#

+# PCI Express Library that uses the 256 MB PCI Express MMIO window to perform

+#  PCI Configuration cycles. Layers on top of an I/O Library instance.  A table of 

+#  PCI devices that are registered for for runtime access is maintained so the 

+#  proper virtual address is used to perform the PCI Express Configuration cycle.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeRuntimePciExpressLib

+  MODULE_UNI_FILE                = DxeRuntimePciExpressLib.uni

+  FILE_GUID                      = 54DCBCE5-92AD-41f5-AAAF-1170F16DA6A8

+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciExpressLib|DXE_RUNTIME_DRIVER 

+  CONSTRUCTOR                    = DxeRuntimePciExpressLibConstructor

+  DESTRUCTOR                     = DxeRuntimePciExpressLibDestructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciExpressLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  IoLib

+  DebugLib

+  PcdLib

+  MemoryAllocationLib

+  UefiBootServicesTableLib

+  DxeServicesTableLib

+  UefiRuntimeLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES

+

+[Guids]

+  gEfiEventVirtualAddressChangeGuid         ## CONSUMES ## Event

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.uni
new file mode 100644
index 0000000..9e02f6b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
new file mode 100644
index 0000000..01bd961
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeRuntimePciExpressLib/PciExpressLib.c
@@ -0,0 +1,1660 @@
+/** @file

+  Functions in this library instance make use of MMIO functions in IoLib to

+  access memory mapped PCI configuration space.

+

+  All assertions for I/O operations are handled in MMIO functions in the IoLib

+  Library.

+

+  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.

+

+**/

+

+

+#include <PiDxe.h>

+

+#include <Guid/EventGroup.h>

+

+#include <Library/BaseLib.h>

+#include <Library/PciExpressLib.h>

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/UefiRuntimeLib.h>

+

+///

+/// Define table for mapping PCI Express MMIO physical addresses to virtual addresses at OS runtime

+///

+typedef struct {

+  UINTN  PhysicalAddress;

+  UINTN  VirtualAddress;

+} PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE;

+

+///

+/// Set Virtual Address Map Event

+///

+EFI_EVENT                               mDxeRuntimePciExpressLibVirtualNotifyEvent = NULL;

+

+///

+/// Module global that contains the base physical address of the PCI Express MMIO range.

+///

+UINTN                                   mDxeRuntimePciExpressLibPciExpressBaseAddress = 0;

+

+///

+/// The number of PCI devices that have been registered for runtime access.

+///

+UINTN                                   mDxeRuntimePciExpressLibNumberOfRuntimeRanges = 0;

+

+///

+/// The table of PCI devices that have been registered for runtime access.

+///

+PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE  *mDxeRuntimePciExpressLibRegistrationTable = NULL;

+

+///

+/// The table index of the most recent virtual address lookup.

+///

+UINTN                                   mDxeRuntimePciExpressLibLastRuntimeRange = 0;

+

+

+/**

+  Convert the physical PCI Express MMIO addresses for all registered PCI devices

+  to virtual addresses.

+

+  @param[in]    Event   The event that is being processed.

+  @param[in]    Context The Event Context.

+**/

+VOID

+EFIAPI

+DxeRuntimePciExpressLibVirtualNotify (

+  IN EFI_EVENT  Event,

+  IN VOID       *Context

+  )

+{

+  UINTN  Index;

+

+  //

+  // If there have been no runtime registrations, then just return

+  //

+  if (mDxeRuntimePciExpressLibRegistrationTable == NULL) {

+    return;

+  }

+

+  //

+  // Convert physical addresses associated with the set of registered PCI devices to

+  // virtual addresses.

+  //

+  for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {

+    EfiConvertPointer (0, (VOID **) &(mDxeRuntimePciExpressLibRegistrationTable[Index].VirtualAddress));

+  }

+

+  //

+  // Convert table pointer that is allocated from EfiRuntimeServicesData to a virtual address.

+  //

+  EfiConvertPointer (0, (VOID **) &mDxeRuntimePciExpressLibRegistrationTable);

+}

+

+/**

+  The constructor function caches the PCI Express Base Address and creates a 

+  Set Virtual Address Map event to convert physical address to virtual addresses.

+  

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor completed successfully.

+  @retval Other value   The constructor did not complete successfully.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeRuntimePciExpressLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Cache the physical address of the PCI Express MMIO range into a module global variable

+  //

+  mDxeRuntimePciExpressLibPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress);

+

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+  Status = gBS->CreateEventEx (

+                  EVT_NOTIFY_SIGNAL,

+                  TPL_NOTIFY,

+                  DxeRuntimePciExpressLibVirtualNotify,

+                  NULL,

+                  &gEfiEventVirtualAddressChangeGuid,

+                  &mDxeRuntimePciExpressLibVirtualNotifyEvent

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  The destructor function frees any allocated buffers and closes the Set Virtual 

+  Address Map event.

+  

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The destructor completed successfully.

+  @retval Other value   The destructor did not complete successfully.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeRuntimePciExpressLibDestructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // If one or more PCI devices have been registered for runtime access, then 

+  // free the registration table.

+  //

+  if (mDxeRuntimePciExpressLibRegistrationTable != NULL) {

+    FreePool (mDxeRuntimePciExpressLibRegistrationTable);

+  }

+

+  //

+  // Close the Set Virtual Address Map event

+  //

+  Status = gBS->CloseEvent (mDxeRuntimePciExpressLibVirtualNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  Gets the base address of PCI Express.

+  

+  This internal functions retrieves PCI Express Base Address via a PCD entry

+  PcdPciExpressBaseAddress.

+  

+  @param  Address  The address that encodes the PCI Bus, Device, Function and Register.

+  @return          The base address of PCI Express.

+

+**/

+UINTN

+GetPciExpressAddress (

+  IN UINTN  Address

+  )

+{

+  UINTN  Index;

+

+  //

+  // Make sure Address is valid

+  //

+  ASSERT (((Address) & ~0xfffffff) == 0);

+

+  //

+  // Convert Address to a physical address in the MMIO PCI Express range

+  //

+  Address += mDxeRuntimePciExpressLibPciExpressBaseAddress;

+

+  //

+  // If SetVirtualAddressMap() has not been called, then just return the physical address

+  //

+  if (!EfiGoneVirtual ()) {

+    return Address;

+  }

+

+  //

+  // See if there is a physical address match at the exact same index as the last address match

+  //

+  if (mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibLastRuntimeRange].PhysicalAddress == (Address & (~0x00000fff))) {

+    //

+    // Convert the physical address to a virtual address and return the virtual address

+    //

+    return (Address & 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibLastRuntimeRange].VirtualAddress;

+  }

+

+  //

+  // Search the entire table for a physical address match

+  //

+  for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {

+    if (mDxeRuntimePciExpressLibRegistrationTable[Index].PhysicalAddress == (Address & (~0x00000fff))) {

+      //

+      // Cache the matching index value

+      //

+      mDxeRuntimePciExpressLibLastRuntimeRange = Index;

+      //

+      // Convert the physical address to a virtual address and return the virtual address

+      //

+      return (Address & 0x00000fff) + mDxeRuntimePciExpressLibRegistrationTable[Index].VirtualAddress;

+    }

+  }

+

+  //

+  // No match was found.  This is a critical error at OS runtime, so ASSERT() and force a breakpoint.

+  //

+  ASSERT (FALSE);

+  CpuBreakpoint();

+

+  //

+  // Return the physical address 

+  //

+  return Address;

+}

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration 

+  registers associated with that PCI device may be accessed after SetVirtualAddressMap() 

+  is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciExpressRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  EFI_STATUS                       Status;

+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR  Descriptor;

+  UINTN                            Index;

+  VOID                             *NewTable;

+

+  //

+  // Return an error if this function is called after ExitBootServices().

+  //

+  if (EfiAtRuntime ()) {

+    return RETURN_UNSUPPORTED;

+  }

+

+  //

+  // Make sure Address is valid

+  //

+  ASSERT (((Address) & ~0xfffffff) == 0);

+

+  //

+  // Convert Address to a physical address in the MMIO PCI Express range

+  // at the beginning of the PCI Configuration header for the specified

+  // PCI Bus/Dev/Func

+  //

+  Address = GetPciExpressAddress (Address & 0x0ffff000);

+

+  //

+  // See if Address has already been registerd for runtime access

+  //

+  for (Index = 0; Index < mDxeRuntimePciExpressLibNumberOfRuntimeRanges; Index++) {

+    if (mDxeRuntimePciExpressLibRegistrationTable[Index].PhysicalAddress == Address) {

+      return RETURN_SUCCESS;

+    }

+  }

+

+  //

+  // Get the GCD Memory Descriptor for the PCI Express Bus/Dev/Func specified by Address

+  //

+  Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor);

+  if (EFI_ERROR (Status)) {

+    return RETURN_UNSUPPORTED;

+  }

+

+  //

+  // Mark the 4KB region for the PCI Express Bus/Dev/Func as EFI_RUNTIME_MEMORY so the OS

+  // will allocate a virtual address range for the 4KB PCI Configuration Header.

+  //

+  Status = gDS->SetMemorySpaceAttributes (Address, 0x1000, Descriptor.Attributes | EFI_MEMORY_RUNTIME);

+  if (EFI_ERROR (Status)) {

+    return RETURN_UNSUPPORTED;

+  }

+

+  //

+  // Grow the size of the registration table

+  //

+  NewTable = ReallocateRuntimePool (

+               (mDxeRuntimePciExpressLibNumberOfRuntimeRanges + 0) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE), 

+               (mDxeRuntimePciExpressLibNumberOfRuntimeRanges + 1) * sizeof (PCI_EXPRESS_RUNTIME_REGISTRATION_TABLE), 

+               mDxeRuntimePciExpressLibRegistrationTable

+               );

+  if (NewTable == NULL) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  mDxeRuntimePciExpressLibRegistrationTable = NewTable;

+  mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibNumberOfRuntimeRanges].PhysicalAddress = Address;

+  mDxeRuntimePciExpressLibRegistrationTable[mDxeRuntimePciExpressLibNumberOfRuntimeRanges].VirtualAddress  = Address;

+  mDxeRuntimePciExpressLibNumberOfRuntimeRanges++;

+

+  return RETURN_SUCCESS;

+}

+

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return MmioRead8 (GetPciExpressAddress (Address));

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (GetPciExpressAddress (Address), Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioOr8 (GetPciExpressAddress (Address), OrData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioAnd8 (GetPciExpressAddress (Address), AndData);

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioAndThenOr8 (

+           GetPciExpressAddress (Address),

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return MmioBitFieldRead8 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioBitFieldWrite8 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioBitFieldOr8 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioBitFieldAnd8 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciExpressBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioBitFieldAndThenOr8 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressRead16 (

+  IN      UINTN                     Address

+  )

+{

+  return MmioRead16 (GetPciExpressAddress (Address));

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (GetPciExpressAddress (Address), Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioOr16 (GetPciExpressAddress (Address), OrData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioAnd16 (GetPciExpressAddress (Address), AndData);

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioAndThenOr16 (

+           GetPciExpressAddress (Address),

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return MmioBitFieldRead16 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioBitFieldWrite16 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioBitFieldOr16 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioBitFieldAnd16 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciExpressBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioBitFieldAndThenOr16 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressRead32 (

+  IN      UINTN                     Address

+  )

+{

+  return MmioRead32 (GetPciExpressAddress (Address));

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (GetPciExpressAddress (Address), Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioOr32 (GetPciExpressAddress (Address), OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioAnd32 (GetPciExpressAddress (Address), AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioAndThenOr32 (

+           GetPciExpressAddress (Address),

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return MmioBitFieldRead32 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit

+           );

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioBitFieldWrite32 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           Value

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioBitFieldOr32 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           OrData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioBitFieldAnd32 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           AndData

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciExpressBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioBitFieldAndThenOr32 (

+           GetPciExpressAddress (Address),

+           StartBit,

+           EndBit,

+           AndData,

+           OrData

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size read data from StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciExpressReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN   ReturnValue;

+

+  //

+  // Make sure Address is valid

+  //

+  ASSERT (((StartAddress) & ~0xfffffff) == 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));

+

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 ((UINT32 *) Buffer, (UINT32) PciExpressRead32 (StartAddress));

+

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 ((UINT16 *) Buffer, (UINT16) PciExpressRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciExpressWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  //

+  // Make sure Address is valid

+  //

+  ASSERT (((StartAddress) & ~0xfffffff) == 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & 1) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciExpressWrite32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciExpressWrite16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciExpressWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.c b/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.c
new file mode 100644
index 0000000..8d1dd9a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.c
@@ -0,0 +1,286 @@
+/** @file

+  This library implements the SAL Library Class using Extended SAL functions

+

+  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

+  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 <PiDxe.h>

+

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/SalLib.h>

+#include <Library/ExtendedSalLib.h>

+

+/**

+  Makes a SAL procedure call.

+  

+  This is a wrapper function to make a SAL procedure call.  

+  No parameter checking is performed on the 8 input parameters,

+  but there are some common rules that the caller should follow

+  when making a SAL call.  Any address passed to SAL 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.

+  This function is only available on IPF.

+

+  @param  Index       The SAL procedure Index number

+  @param  Arg2        The 2nd parameter for SAL procedure calls

+  @param  Arg3        The 3rd parameter for SAL procedure calls

+  @param  Arg4        The 4th parameter for SAL procedure calls

+  @param  Arg5        The 5th parameter for SAL procedure calls

+  @param  Arg6        The 6th parameter for SAL procedure calls

+  @param  Arg7        The 7th parameter for SAL procedure calls

+  @param  Arg8        The 8th parameter for SAL procedure calls

+

+  @return SAL returned registers.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+SalCall (

+  IN UINT64  Index,

+  IN UINT64  Arg2,

+  IN UINT64  Arg3,

+  IN UINT64  Arg4,

+  IN UINT64  Arg5,

+  IN UINT64  Arg6,

+  IN UINT64  Arg7,

+  IN UINT64  Arg8

+  )

+{

+  SAL_RETURN_REGS Regs;

+  

+  //

+  // Initial all members in this structure.

+  //

+  Regs.r9     = 0;

+  Regs.r10    = 0;

+  Regs.r11    = 0;

+  Regs.Status = EFI_SAL_INVALID_ARGUMENT;

+

+  switch (Index) {

+  case EFI_SAL_SET_VECTORS:

+    return EsalCall (

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+             SalSetVectorsFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_GET_STATE_INFO:

+    return EsalCall (

+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+             SalGetStateInfoFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_GET_STATE_INFO_SIZE:

+    return EsalCall (

+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+             SalGetStateInfoSizeFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_CLEAR_STATE_INFO:

+    return EsalCall (

+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_MCA_LOG_SERVICES_PROTOCOL_GUID_HI,

+             SalClearStateInfoFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_MC_RENDEZ:

+    return EsalCall (

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+             SalMcRendezFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+   break;

+

+  case EFI_SAL_MC_SET_PARAMS:

+    return EsalCall (

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+             SalMcSetParamsFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_REGISTER_PHYSICAL_ADDR:

+    return EsalCall (

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+             EsalRegisterPhysicalAddrFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_CACHE_FLUSH:

+    return EsalCall (

+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_HI,

+             SalCacheFlushFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_CACHE_INIT:

+    return EsalCall (

+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_CACHE_SERVICES_PROTOCOL_GUID_HI,

+             SalCacheInitFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_PCI_CONFIG_READ:

+    return EsalCall (

+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+             SalPciConfigReadFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_PCI_CONFIG_WRITE:

+    return EsalCall (

+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_PCI_SERVICES_PROTOCOL_GUID_HI,

+             SalPciConfigWriteFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_FREQ_BASE:

+    return EsalCall (

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+             EsalGetPlatformBaseFreqFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_PHYSICAL_ID_INFO:

+    return EsalCall (

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_BASE_SERVICES_PROTOCOL_GUID_HI,

+             EsalPhysicalIdInfoFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  case EFI_SAL_UPDATE_PAL:

+    return EsalCall (

+             EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_LO,

+             EFI_EXTENDED_SAL_PAL_SERVICES_PROTOCOL_GUID_HI,

+             EsalUpdatePalFunctionId, 

+             Arg2, 

+             Arg3, 

+             Arg4, 

+             Arg5, 

+             Arg6, 

+             Arg7, 

+             Arg8

+             );

+    break;

+

+  default:

+    return Regs;

+    break;

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf b/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf
new file mode 100644
index 0000000..656d949
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.inf
@@ -0,0 +1,38 @@
+## @file

+#  This library implements the SAL Library Class using Extended SAL functions

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeSalLibEsal

+  MODULE_UNI_FILE                = DxeSalLibEsal.uni

+  FILE_GUID                      = 2B73B074-2E67-498b-82AC-CE38FB770FFC

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SalLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION 

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources.IPF]

+  DxeSalLibEsal.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  ExtendedSalLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.uni b/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.uni
new file mode 100644
index 0000000..0c76dd2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSalLibEsal/DxeSalLibEsal.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
new file mode 100644
index 0000000..ef7c9ba
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.c
@@ -0,0 +1,927 @@
+/** @file

+  MDE DXE Services Library provides functions that simplify the development of DXE Drivers.  

+  These functions help access data from sections of FFS files or from file path.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiDxe.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DevicePathLib.h>

+#include <Library/UefiLib.h>

+#include <Library/DxeServicesLib.h>

+#include <Protocol/FirmwareVolume2.h>

+#include <Protocol/LoadedImage.h>

+#include <Protocol/LoadFile2.h>

+#include <Protocol/LoadFile.h>

+#include <Protocol/SimpleFileSystem.h>

+#include <Guid/FileInfo.h>

+

+/**

+  Identify the device handle from which the Image is loaded from. As this device handle is passed to

+  GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL 

+  protocol instance should be located succesfully by calling gBS->HandleProtocol ().

+

+  This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed

+  on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.

+  

+  If ImageHandle is NULL, then ASSERT ();

+  If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();

+  

+  @param  ImageHandle         The firmware allocated handle for UEFI image.

+

+  @retval  EFI_HANDLE         The device handle from which the Image is loaded from.

+

+**/

+EFI_HANDLE

+InternalImageHandleToFvHandle (

+  EFI_HANDLE ImageHandle

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;

+  

+  ASSERT (ImageHandle != NULL);

+

+  Status = gBS->HandleProtocol (

+             (EFI_HANDLE *) ImageHandle,

+             &gEfiLoadedImageProtocolGuid,

+             (VOID **) &LoadedImage

+             );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return LoadedImage->DeviceHandle;

+

+}

+

+/**

+  Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware 

+  Section type and instance number from the specified Firmware Volume.

+

+  This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to 

+  carry out the Firmware Volume read operation. The function then reads the Firmware Section found sepcifed 

+  by NameGuid, SectionType and SectionInstance. 

+  

+  The details of this search order is defined in description of EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection () 

+  found in PI Specification.

+  

+  If SectionType is EFI_SECTION_TE, EFI_SECTION_TE is used as section type to start the search. If EFI_SECTION_TE section 

+  is not found, EFI_SECTION_PE32 will be used to try the search again. If no EFI_SECTION_PE32 section is found, EFI_NOT_FOUND 

+  is returned.

+  

+  The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated 

+  by this function. This function can be only called at TPL_NOTIFY and below.

+  

+  If FvHandle is NULL, then ASSERT ();

+  If NameGuid is NULL, then ASSERT();

+  If Buffer is NULL, then ASSERT();

+  If Size is NULL, then ASSERT().

+

+  @param  FvHandle                The device handle that contains a instance of 

+                                  EFI_FIRMWARE_VOLUME2_PROTOCOL instance.

+  @param  NameGuid                The GUID name of a Firmware File.

+  @param  SectionType             The Firmware Section type.

+  @param  SectionInstance         The instance number of Firmware Section to  

+                                  read from starting from 0.

+  @param  Buffer                  On output, Buffer contains the the data read 

+                                  from the section in the Firmware File found.

+  @param  Size                    On output, the size of Buffer.

+

+  @retval  EFI_SUCCESS            The image is found and data and size is returned.

+  @retval  EFI_NOT_FOUND          The image specified by NameGuid and SectionType 

+                                  can't be found.

+  @retval  EFI_OUT_OF_RESOURCES   There were not enough resources to allocate the 

+                                  output data buffer or complete the operations.

+  @retval  EFI_DEVICE_ERROR       A hardware error occurs during reading from the 

+                                  Firmware Volume.

+  @retval  EFI_ACCESS_DENIED      The firmware volume containing the searched 

+                                  Firmware File is configured to disallow reads.

+  

+**/

+EFI_STATUS

+InternalGetSectionFromFv (

+  IN  EFI_HANDLE                    FvHandle,

+  IN  CONST EFI_GUID                *NameGuid,

+  IN  EFI_SECTION_TYPE              SectionType,

+  IN  UINTN                         SectionInstance,

+  OUT VOID                          **Buffer,

+  OUT UINTN                         *Size

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;

+  UINT32                        AuthenticationStatus;

+

+  ASSERT (NameGuid != NULL);

+  ASSERT (Buffer != NULL);

+  ASSERT (Size != NULL);

+  

+  ASSERT (FvHandle != NULL);

+

+  Status = gBS->HandleProtocol (

+                  FvHandle,

+                  &gEfiFirmwareVolume2ProtocolGuid,

+                  (VOID **) &Fv

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_NOT_FOUND;

+  }

+

+  //

+  // Read desired section content in NameGuid file

+  //

+  *Buffer     = NULL;

+  *Size       = 0;

+  Status      = Fv->ReadSection (

+                      Fv,

+                      NameGuid,

+                      SectionType,

+                      SectionInstance,

+                      Buffer,

+                      Size,

+                      &AuthenticationStatus

+                      );

+

+  if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {

+    //

+    // Try reading PE32 section, if the required section is TE type 

+    //

+    *Buffer = NULL;

+    *Size   = 0;

+    Status  = Fv->ReadSection (

+                    Fv,

+                    NameGuid,

+                    EFI_SECTION_PE32,

+                    SectionInstance,

+                    Buffer,

+                    Size,

+                    &AuthenticationStatus

+                    );

+  }

+

+  return Status;

+}

+

+/**

+  Searches all the available firmware volumes and returns the first matching FFS section. 

+

+  This function searches all the firmware volumes for FFS files with FV file type specified by FileType

+  The order that the firmware volumes is searched is not deterministic. For each available FV a search 

+  is made for FFS file of type FileType. If the FV contains more than one FFS file with the same FileType, 

+  the FileInstance instance will be the matched FFS file. For each FFS file found a search 

+  is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances 

+  of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer. 

+  Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. 

+  It is the caller's responsibility to use FreePool() to free the allocated buffer.  

+  See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections 

+  are retrieved from an FFS file based on SectionType and SectionInstance.

+

+  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, 

+  the search will be retried with a section type of EFI_SECTION_PE32.

+  This function must be called with a TPL <= TPL_NOTIFY.

+

+  If Buffer is NULL, then ASSERT().

+  If Size is NULL, then ASSERT().

+

+  @param  FileType             Indicates the FV file type to search for within all 

+                               available FVs.

+  @param  FileInstance         Indicates which file instance within all available 

+                               FVs specified by FileType.

+                               FileInstance starts from zero.

+  @param  SectionType          Indicates the FFS section type to search for 

+                               within the FFS file 

+                               specified by FileType with FileInstance.

+  @param  SectionInstance      Indicates which section instance within the FFS file 

+                               specified by FileType with FileInstance to retrieve. 

+                               SectionInstance starts from zero.

+  @param  Buffer               On output, a pointer to a callee allocated buffer 

+                               containing the FFS file section that was found.

+                               Is it the caller's responsibility to free this 

+                               buffer using FreePool().

+  @param  Size                 On output, a pointer to the size, in bytes, of Buffer.

+

+  @retval  EFI_SUCCESS          The specified FFS section was returned.

+  @retval  EFI_NOT_FOUND        The specified FFS section could not be found.

+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve 

+                                the matching FFS section.

+  @retval  EFI_DEVICE_ERROR     The FFS section could not be retrieves due to a 

+                                device error.

+  @retval  EFI_ACCESS_DENIED    The FFS section could not be retrieves because 

+                                the firmware volume that 

+                                contains the matching FFS section does not allow reads.

+**/

+EFI_STATUS

+EFIAPI

+GetSectionFromAnyFvByFileType  (

+  IN  EFI_FV_FILETYPE               FileType,

+  IN  UINTN                         FileInstance,

+  IN  EFI_SECTION_TYPE              SectionType,

+  IN  UINTN                         SectionInstance,

+  OUT VOID                          **Buffer,

+  OUT UINTN                         *Size

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_HANDLE                    *HandleBuffer;

+  UINTN                         HandleCount;

+  UINTN                         IndexFv;

+  UINTN                         IndexFile;

+  UINTN                         Key;

+  EFI_GUID                      NameGuid;

+  EFI_FV_FILE_ATTRIBUTES        Attributes;

+  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;

+

+  //

+  // Locate all available FVs.

+  //

+  HandleBuffer = NULL;

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiFirmwareVolume2ProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Go through FVs one by one to find the required section data.

+  //

+  for (IndexFv = 0; IndexFv < HandleCount; IndexFv++) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[IndexFv],

+                    &gEfiFirmwareVolume2ProtocolGuid,

+                    (VOID **)&Fv

+                    );

+    if (EFI_ERROR (Status)) {

+      continue;

+    }

+

+    //

+    // Use Firmware Volume 2 Protocol to search for a file of type FileType in all FVs.

+    //

+    IndexFile = FileInstance + 1;

+    Key = 0;

+    do {

+      Status = Fv->GetNextFile (Fv, &Key, &FileType, &NameGuid, &Attributes, Size);

+      if (EFI_ERROR (Status)) {

+        break;

+      }

+      IndexFile --;

+    } while (IndexFile > 0);

+

+    //

+    // Fv File with the required FV file type is found.

+    // Search the section file in the found FV file.

+    //

+    if (IndexFile == 0) {

+      Status = InternalGetSectionFromFv (

+                 HandleBuffer[IndexFv], 

+                 &NameGuid,

+                 SectionType,

+                 SectionInstance,

+                 Buffer,

+                 Size

+                 );

+

+      if (!EFI_ERROR (Status)) {

+        goto Done;

+      }

+    }

+  }

+

+  //

+  // The required FFS section file is not found. 

+  //

+  if (IndexFv == HandleCount) {

+    Status = EFI_NOT_FOUND;

+  }

+

+Done:

+  if (HandleBuffer != NULL) {  

+    FreePool(HandleBuffer);

+  }

+

+  return Status;

+}

+

+/**

+  Searches all the availables firmware volumes and returns the first matching FFS section. 

+

+  This function searches all the firmware volumes for FFS files with an FFS filename specified by NameGuid.  

+  The order that the firmware volumes is searched is not deterministic. For each FFS file found a search 

+  is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance instances 

+  of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer. 

+  Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. 

+  It is the caller's responsibility to use FreePool() to free the allocated buffer.  

+  See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections 

+  are retrieved from an FFS file based on SectionType and SectionInstance.

+

+  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, 

+  the search will be retried with a section type of EFI_SECTION_PE32.

+  This function must be called with a TPL <= TPL_NOTIFY.

+

+  If NameGuid is NULL, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If Size is NULL, then ASSERT().

+

+

+  @param  NameGuid             A pointer to to the FFS filename GUID to search for  

+                               within any of the firmware volumes in the platform. 

+  @param  SectionType          Indicates the FFS section type to search for within 

+                               the FFS file specified by NameGuid.

+  @param  SectionInstance      Indicates which section instance within the FFS file 

+                               specified by NameGuid to retrieve.

+  @param  Buffer               On output, a pointer to a callee allocated buffer 

+                               containing the FFS file section that was found.  

+                               Is it the caller's responsibility to free this buffer 

+                               using FreePool().

+  @param  Size                 On output, a pointer to the size, in bytes, of Buffer.

+

+  @retval  EFI_SUCCESS          The specified FFS section was returned.

+  @retval  EFI_NOT_FOUND        The specified FFS section could not be found.

+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to 

+                                retrieve the matching FFS section.

+  @retval  EFI_DEVICE_ERROR     The FFS section could not be retrieves due to a 

+                                device error.

+  @retval  EFI_ACCESS_DENIED    The FFS section could not be retrieves because the 

+                                firmware volume that 

+                                contains the matching FFS section does not allow reads.

+**/

+EFI_STATUS

+EFIAPI

+GetSectionFromAnyFv  (

+  IN CONST  EFI_GUID           *NameGuid,

+  IN        EFI_SECTION_TYPE   SectionType,

+  IN        UINTN              SectionInstance,

+  OUT       VOID               **Buffer,

+  OUT       UINTN              *Size

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_HANDLE                    *HandleBuffer;

+  UINTN                         HandleCount;

+  UINTN                         Index;

+  EFI_HANDLE                    FvHandle;

+

+  //

+  // Search the FV that contain the caller's FFS first.

+  // FV builder can choose to build FFS into the this FV

+  // so that this implementation of GetSectionFromAnyFv

+  // will locate the FFS faster.

+  //

+  FvHandle = InternalImageHandleToFvHandle (gImageHandle);

+  Status = InternalGetSectionFromFv (

+             FvHandle,

+             NameGuid,

+             SectionType,

+             SectionInstance,

+             Buffer,

+             Size

+             );

+  if (!EFI_ERROR (Status)) {

+    return EFI_SUCCESS;

+  }

+

+  HandleBuffer = NULL;

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiFirmwareVolume2ProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  if (EFI_ERROR (Status)) {

+    goto Done;

+  }

+

+  for (Index = 0; Index < HandleCount; Index++) {

+    //

+    // Skip the FV that contain the caller's FFS

+    //

+    if (HandleBuffer[Index] != FvHandle) {

+      Status = InternalGetSectionFromFv (

+                 HandleBuffer[Index], 

+                 NameGuid, 

+                 SectionType, 

+                 SectionInstance,

+                 Buffer, 

+                 Size

+                 );

+

+      if (!EFI_ERROR (Status)) {

+        goto Done;

+      }

+    }

+

+  }

+

+  if (Index == HandleCount) {

+    Status = EFI_NOT_FOUND;

+  }

+

+Done:

+  

+  if (HandleBuffer != NULL) {  

+    FreePool(HandleBuffer);

+  }

+  return Status;

+  

+}

+

+/**

+  Searches the firmware volume that the currently executing module was loaded from and returns the first matching FFS section. 

+

+  This function searches the firmware volume that the currently executing module was loaded 

+  from for an FFS file with an FFS filename specified by NameGuid. If the FFS file is found a search 

+  is made for FFS sections of type SectionType. If the FFS file contains at least SectionInstance 

+  instances of the FFS section specified by SectionType, then the SectionInstance instance is returned in Buffer.

+  Buffer is allocated using AllocatePool(), and the size of the allocated buffer is returned in Size. 

+  It is the caller's responsibility to use FreePool() to free the allocated buffer. 

+  See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from 

+  an FFS file based on SectionType and SectionInstance.

+

+  If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned.

+  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, 

+  the search will be retried with a section type of EFI_SECTION_PE32.

+  

+  This function must be called with a TPL <= TPL_NOTIFY.

+  If NameGuid is NULL, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If Size is NULL, then ASSERT().

+

+  @param  NameGuid             A pointer to to the FFS filename GUID to search for 

+                               within the firmware volumes that the currently 

+                               executing module was loaded from.

+  @param  SectionType          Indicates the FFS section type to search for within 

+                               the FFS file specified by NameGuid.

+  @param  SectionInstance      Indicates which section instance within the FFS file 

+                               specified by NameGuid to retrieve.

+  @param  Buffer               On output, a pointer to a callee allocated buffer 

+                               containing the FFS file section that was found.  

+                               Is it the caller's responsibility to free this buffer 

+                               using FreePool().

+  @param  Size                 On output, a pointer to the size, in bytes, of Buffer.

+

+

+  @retval  EFI_SUCCESS          The specified FFS section was returned.

+  @retval  EFI_NOT_FOUND        The specified FFS section could not be found.

+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve 

+                                the matching FFS section.

+  @retval  EFI_DEVICE_ERROR     The FFS section could not be retrieves due to a 

+                                device error.

+  @retval  EFI_ACCESS_DENIED    The FFS section could not be retrieves because the 

+                                firmware volume that contains the matching FFS 

+                                section does not allow reads.  

+**/

+EFI_STATUS

+EFIAPI

+GetSectionFromFv (

+  IN  CONST EFI_GUID                *NameGuid,

+  IN  EFI_SECTION_TYPE              SectionType,

+  IN  UINTN                         SectionInstance,

+  OUT VOID                          **Buffer,

+  OUT UINTN                         *Size

+    )

+{

+  return InternalGetSectionFromFv (

+           InternalImageHandleToFvHandle(gImageHandle),

+           NameGuid,

+           SectionType,

+           SectionInstance,

+           Buffer,

+           Size

+           );

+}

+

+

+/**

+  Searches the FFS file the the currently executing module was loaded from and returns the first matching FFS section.

+

+  This function searches the FFS file that the currently executing module was loaded from for a FFS sections of type SectionType.

+  If the FFS file contains at least SectionInstance instances of the FFS section specified by SectionType, 

+  then the SectionInstance instance is returned in Buffer. Buffer is allocated using AllocatePool(), 

+  and the size of the allocated buffer is returned in Size. It is the caller's responsibility 

+  to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for 

+  details on how sections are retrieved from an FFS file based on SectionType and SectionInstance.

+

+  If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned.

+  If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, 

+  the search will be retried with a section type of EFI_SECTION_PE32.

+  This function must be called with a TPL <= TPL_NOTIFY.

+  

+  If Buffer is NULL, then ASSERT().

+  If Size is NULL, then ASSERT().

+

+

+  @param  SectionType          Indicates the FFS section type to search for within 

+                               the FFS file that the currently executing module 

+                               was loaded from.

+  @param  SectionInstance      Indicates which section instance to retrieve within 

+                               the FFS file that the currently executing module 

+                               was loaded from.

+  @param  Buffer               On output, a pointer to a callee allocated buffer 

+                               containing the FFS file section that was found.  

+                               Is it the caller's responsibility to free this buffer 

+                               using FreePool().

+  @param  Size                 On output, a pointer to the size, in bytes, of Buffer.

+

+  @retval  EFI_SUCCESS          The specified FFS section was returned.

+  @retval  EFI_NOT_FOUND        The specified FFS section could not be found.

+  @retval  EFI_OUT_OF_RESOURCES There are not enough resources available to retrieve 

+                                the matching FFS section.

+  @retval  EFI_DEVICE_ERROR     The FFS section could not be retrieves due to a 

+                                device error.

+  @retval  EFI_ACCESS_DENIED    The FFS section could not be retrieves because the 

+                                firmware volume that contains the matching FFS 

+                                section does not allow reads.  

+  

+**/

+EFI_STATUS

+EFIAPI

+GetSectionFromFfs (

+  IN  EFI_SECTION_TYPE              SectionType,

+  IN  UINTN                         SectionInstance,

+  OUT VOID                          **Buffer,

+  OUT UINTN                         *Size

+    )

+{

+  return InternalGetSectionFromFv(

+           InternalImageHandleToFvHandle(gImageHandle),

+           &gEfiCallerIdGuid,

+           SectionType,

+           SectionInstance,

+           Buffer,

+           Size

+           );

+}

+

+

+/**

+  Get the image file buffer data and buffer size by its device path. 

+  

+  Access the file either from a firmware volume, from a file system interface, 

+  or from the load file interface.

+  

+  Allocate memory to store the found image. The caller is responsible to free memory.

+

+  If FilePath is NULL, then NULL is returned.

+  If FileSize is NULL, then NULL is returned.

+  If AuthenticationStatus is NULL, then NULL is returned.

+

+  @param[in]       BootPolicy           Policy for Open Image File.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. If FALSE, then FilePath must 

+                                        match an exact file to be loaded.

+  @param[in]       FilePath             The pointer to the device path of the file

+                                        that is absracted to the file buffer.

+  @param[out]      FileSize             The pointer to the size of the abstracted 

+                                        file buffer.

+  @param[out]      AuthenticationStatus Pointer to the authentication status.

+

+  @retval NULL   FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found.

+  @retval other  The abstracted file buffer. The caller is responsible to free memory.

+**/

+VOID *

+EFIAPI

+GetFileBufferByFilePath (

+  IN BOOLEAN                           BootPolicy,

+  IN CONST EFI_DEVICE_PATH_PROTOCOL    *FilePath,

+  OUT      UINTN                       *FileSize,

+  OUT UINT32                           *AuthenticationStatus

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;

+  EFI_DEVICE_PATH_PROTOCOL          *OrigDevicePathNode;

+  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePathNode;

+  EFI_HANDLE                        Handle;

+  EFI_GUID                          *FvNameGuid;

+  EFI_FIRMWARE_VOLUME2_PROTOCOL     *FwVol;

+  EFI_SECTION_TYPE                  SectionType;

+  UINT8                             *ImageBuffer;

+  UINTN                             ImageBufferSize;

+  EFI_FV_FILETYPE                   Type;

+  EFI_FV_FILE_ATTRIBUTES            Attrib;

+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;

+  EFI_FILE_HANDLE                   FileHandle;

+  EFI_FILE_HANDLE                   LastHandle;

+  EFI_FILE_INFO                     *FileInfo;

+  UINTN                             FileInfoSize;

+  EFI_LOAD_FILE_PROTOCOL            *LoadFile;

+  EFI_LOAD_FILE2_PROTOCOL           *LoadFile2;

+  EFI_STATUS                        Status;

+

+  //

+  // Check input File device path.

+  //

+  if (FilePath == NULL || FileSize == NULL || AuthenticationStatus == NULL) {

+    return NULL;

+  }

+

+  //

+  // Init local variable

+  //

+  TempDevicePathNode  = NULL;

+  FvNameGuid          = NULL;

+  FileInfo            = NULL;

+  FileHandle          = NULL;

+  ImageBuffer         = NULL;

+  ImageBufferSize     = 0;

+  *AuthenticationStatus = 0;

+  

+  //

+  // Copy File Device Path

+  //

+  OrigDevicePathNode = DuplicateDevicePath (FilePath);

+  if (OrigDevicePathNode == NULL) {

+    return NULL;

+  }

+

+  //

+  // Check whether this device path support FV2 protocol.

+  // Is so, this device path may contain a Image.

+  //

+  DevicePathNode = OrigDevicePathNode;

+  Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);

+  if (!EFI_ERROR (Status)) {

+    //

+    // For FwVol File system there is only a single file name that is a GUID.

+    //

+    FvNameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePathNode);

+    if (FvNameGuid == NULL) {

+      Status = EFI_INVALID_PARAMETER;

+    } else {

+      //

+      // Read image from the firmware file

+      //

+      Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol);

+      if (!EFI_ERROR (Status)) {

+        SectionType = EFI_SECTION_PE32;

+        ImageBuffer = NULL;

+        Status = FwVol->ReadSection (

+                          FwVol,

+                          FvNameGuid,

+                          SectionType,

+                          0,

+                          (VOID **)&ImageBuffer,

+                          &ImageBufferSize,

+                          AuthenticationStatus

+                          );

+        if (EFI_ERROR (Status)) {

+          //

+          // Try a raw file, since a PE32 SECTION does not exist

+          //

+          if (ImageBuffer != NULL) {

+            FreePool (ImageBuffer);

+            *AuthenticationStatus = 0;

+          }

+          ImageBuffer = NULL;

+          Status = FwVol->ReadFile (

+                            FwVol,

+                            FvNameGuid,

+                            (VOID **)&ImageBuffer,

+                            &ImageBufferSize,

+                            &Type,

+                            &Attrib,

+                            AuthenticationStatus

+                            );

+        }

+      }

+    }

+    if (!EFI_ERROR (Status)) {

+      goto Finish;

+    }

+  }

+

+  //

+  // Attempt to access the file via a file system interface

+  //

+  DevicePathNode = OrigDevicePathNode;

+  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);

+    if (!EFI_ERROR (Status)) {

+      //

+      // Open the Volume to get the File System handle

+      //

+      Status = Volume->OpenVolume (Volume, &FileHandle);

+      if (!EFI_ERROR (Status)) {

+        //

+        // Duplicate the device path to avoid the access to unaligned device path node.

+        // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH

+        // nodes, It assures the fields in device path nodes are 2 byte aligned.

+        //

+        TempDevicePathNode = DuplicateDevicePath (DevicePathNode);

+        if (TempDevicePathNode == NULL) {

+          FileHandle->Close (FileHandle);

+          //

+          // Setting Status to an EFI_ERROR value will cause the rest of

+          // the file system support below to be skipped.

+          //

+          Status = EFI_OUT_OF_RESOURCES;

+        }

+        //

+        // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the

+        // directory information and filename can be seperate. The goal is to inch

+        // our way down each device path node and close the previous node

+        //

+        DevicePathNode = TempDevicePathNode;

+        while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {

+          if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||

+              DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {

+            Status = EFI_UNSUPPORTED;

+            break;

+          }

+  

+          LastHandle = FileHandle;

+          FileHandle = NULL;

+  

+          Status = LastHandle->Open (

+                                LastHandle,

+                                &FileHandle,

+                                ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,

+                                EFI_FILE_MODE_READ,

+                                0

+                                );

+  

+          //

+          // Close the previous node

+          //

+          LastHandle->Close (LastHandle);

+  

+          DevicePathNode = NextDevicePathNode (DevicePathNode);

+        }

+  

+        if (!EFI_ERROR (Status)) {

+          //

+          // We have found the file. Now we need to read it. Before we can read the file we need to

+          // figure out how big the file is.

+          //

+          FileInfo = NULL;

+          FileInfoSize = 0;

+          Status = FileHandle->GetInfo (

+                                FileHandle,

+                                &gEfiFileInfoGuid,

+                                &FileInfoSize,

+                                FileInfo

+                                );

+  

+          if (Status == EFI_BUFFER_TOO_SMALL) {

+            FileInfo = AllocatePool (FileInfoSize);

+            if (FileInfo == NULL) {

+              Status = EFI_OUT_OF_RESOURCES;

+            } else {

+              Status = FileHandle->GetInfo (

+                                    FileHandle,

+                                    &gEfiFileInfoGuid,

+                                    &FileInfoSize,

+                                    FileInfo

+                                    );

+            }

+          }

+          

+          if (!EFI_ERROR (Status) && (FileInfo != NULL)) {

+            //

+            // Allocate space for the file

+            //

+            ImageBuffer = AllocatePool ((UINTN)FileInfo->FileSize);

+            if (ImageBuffer == NULL) {

+              Status = EFI_OUT_OF_RESOURCES;

+            } else {

+              //

+              // Read the file into the buffer we allocated

+              //

+              ImageBufferSize = (UINTN)FileInfo->FileSize;

+              Status          = FileHandle->Read (FileHandle, &ImageBufferSize, ImageBuffer);

+            }

+          }

+        }

+        //

+        // Close the file and Free FileInfo and TempDevicePathNode since we are done

+        // 

+        if (FileInfo != NULL) {

+          FreePool (FileInfo);

+        }

+        if (FileHandle != NULL) {

+          FileHandle->Close (FileHandle);

+        }

+        if (TempDevicePathNode != NULL) {

+          FreePool (TempDevicePathNode);

+        }

+      }

+    }

+    if (!EFI_ERROR (Status)) {

+      goto Finish;

+    }

+  }

+

+  //

+  // Attempt to access the file via LoadFile2 interface

+  //

+  if (!BootPolicy) {

+    DevicePathNode = OrigDevicePathNode;

+    Status = gBS->LocateDevicePath (&gEfiLoadFile2ProtocolGuid, &DevicePathNode, &Handle);

+    if (!EFI_ERROR (Status)) {

+      Status = gBS->HandleProtocol (Handle, &gEfiLoadFile2ProtocolGuid, (VOID**)&LoadFile2);

+      if (!EFI_ERROR (Status)) {

+        //

+        // Call LoadFile2 with the correct buffer size

+        //

+        ImageBufferSize = 0;

+        ImageBuffer     = NULL;

+        Status = LoadFile2->LoadFile (

+                             LoadFile2,

+                             DevicePathNode,

+                             FALSE,

+                             &ImageBufferSize,

+                             ImageBuffer

+                             );

+        if (Status == EFI_BUFFER_TOO_SMALL) {

+          ImageBuffer = AllocatePool (ImageBufferSize);

+          if (ImageBuffer == NULL) {

+            Status = EFI_OUT_OF_RESOURCES;

+          } else {

+            Status = LoadFile2->LoadFile (

+                                 LoadFile2,

+                                 DevicePathNode,

+                                 FALSE,

+                                 &ImageBufferSize,

+                                 ImageBuffer

+                                 );

+          }

+        }

+      }

+      if (!EFI_ERROR (Status)) {

+        goto Finish;

+      }

+    }

+  }

+

+  //

+  // Attempt to access the file via LoadFile interface

+  //

+  DevicePathNode = OrigDevicePathNode;

+  Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &DevicePathNode, &Handle);

+  if (!EFI_ERROR (Status)) {

+    Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID**)&LoadFile);

+    if (!EFI_ERROR (Status)) {

+      //

+      // Call LoadFile with the correct buffer size

+      //

+      ImageBufferSize = 0;

+      ImageBuffer     = NULL;

+      Status = LoadFile->LoadFile (

+                           LoadFile,

+                           DevicePathNode,

+                           BootPolicy,

+                           &ImageBufferSize,

+                           ImageBuffer

+                           );

+      if (Status == EFI_BUFFER_TOO_SMALL) {

+        ImageBuffer = AllocatePool (ImageBufferSize);

+        if (ImageBuffer == NULL) {

+          Status = EFI_OUT_OF_RESOURCES;

+        } else {

+          Status = LoadFile->LoadFile (

+                               LoadFile,

+                               DevicePathNode,

+                               BootPolicy,

+                               &ImageBufferSize,

+                               ImageBuffer

+                               );

+        }

+      }

+    }

+  }

+

+Finish:

+

+  if (EFI_ERROR (Status)) {

+    if (ImageBuffer != NULL) {

+      FreePool (ImageBuffer);

+      ImageBuffer = NULL;

+    }

+    *FileSize = 0;

+  } else {

+    *FileSize = ImageBufferSize;

+  }

+

+  FreePool (OrigDevicePathNode);

+

+  return ImageBuffer;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
new file mode 100644
index 0000000..bd2faf2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
@@ -0,0 +1,56 @@
+## @file

+# DXE Services Library instance provides functions that simplify the development of DXE Drivers.

+#

+# DXE Services Library provides access data from sections of FFS files based on FV protocol.

+# It also provides access file based on file path from a firmware volume, 

+# from a file system interface, or from the load file interface.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeServicesLib

+  MODULE_UNI_FILE                = DxeServicesLib.uni

+  FILE_GUID                      = EE680C58-FFC0-4a5d-858F-66FF9C84BC9F

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DxeServicesLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DxeServicesLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  MemoryAllocationLib

+  DebugLib

+  DevicePathLib

+  UefiLib

+  UefiBootServicesTableLib

+

+[Guids]

+  gEfiFileInfoGuid                              ## SOMETIMES_CONSUMES ## UNDEFINED

+

+[Protocols]

+  gEfiFirmwareVolume2ProtocolGuid               ## SOMETIMES_CONSUMES

+  gEfiLoadedImageProtocolGuid                   ## SOMETIMES_CONSUMES

+  gEfiLoadFileProtocolGuid                      ## SOMETIMES_CONSUMES

+  gEfiLoadFile2ProtocolGuid                     ## SOMETIMES_CONSUMES 

+  gEfiSimpleFileSystemProtocolGuid              ## SOMETIMES_CONSUMES 

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni
new file mode 100644
index 0000000..18923e9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeServicesLib/DxeServicesLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.c
new file mode 100644
index 0000000..7cb94ce
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.c
@@ -0,0 +1,68 @@
+/** @file

+  This library implement library class DxeServiceTableLib.

+  It produce EFI_DXE_SERVICE pointer in global variable gDS in library's constructure.

+  

+  A DXE driver can use gDS pointer to access services in EFI_DXE_SERVICE, if this

+  DXE driver declare that use DxeServicesTableLib library class and link to this 

+  library instance.

+

+  Please attention this library instance can not be used util EFI_SYSTEM_TABLE was 

+  initialized.

+  

+  This library contains contruct function to retrieve EFI_DXE_SERIVCE, this construct

+  function will be invoked in DXE driver's autogen file.

+

+  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.

+

+**/

+

+#include <PiDxe.h>

+#include <Guid/DxeServices.h>

+#include <Library/DxeServicesTableLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiLib.h>

+

+//

+// Cache copy of the DXE Services Table

+//

+EFI_DXE_SERVICES  *gDS      = NULL;

+

+/**

+  The constructor function caches the pointer of DXE Services Table.

+

+  The constructor function caches the pointer of DXE Services Table.

+  It will ASSERT() if that operation fails.

+  It will ASSERT() if the pointer of DXE Services Table is NULL.

+  It will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+DxeServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Cache copy of the DXE Services Table

+  //

+  Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &gDS);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (gDS != NULL);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
new file mode 100644
index 0000000..8ad198c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
@@ -0,0 +1,49 @@
+## @file

+# Instance of DXE Services Table Library using EFI Configuration Table.

+#

+# DXE Services Table Library that retrieves a pointer to the DXE Services

+# Table from the Configuration Table in the EFI System Table.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeServicesTableLib

+  MODULE_UNI_FILE                = DxeServicesTableLib.uni

+  FILE_GUID                      = baa1baa3-0a8d-402c-8042-985115fae953

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DxeServicesTableLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+  CONSTRUCTOR                    = DxeServicesTableLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DxeServicesTableLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  UefiLib

+  DebugLib

+

+

+[Guids]

+  gEfiDxeServicesTableGuid                      ## CONSUMES  ## SystemTable

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.uni
new file mode 100644
index 0000000..099d7ad
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.c
new file mode 100644
index 0000000..985085c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.c
@@ -0,0 +1,104 @@
+/** @file

+Implementation of SmBusLib class library for DXE phase.

+

+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.

+

+

+**/

+

+

+#include "InternalSmbusLib.h"

+

+

+//

+// Globle varible to cache pointer to Smbus protocol.

+//

+EFI_SMBUS_HC_PROTOCOL      *mSmbus = NULL;

+

+/**

+  The constructor function caches the pointer to Smbus protocol.

+

+  The constructor function locates Smbus protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmbusLibConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  Status = gBS->LocateProtocol (&gEfiSmbusHcProtocolGuid, NULL, (VOID**) &mSmbus);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mSmbus != NULL);

+

+  return Status;

+}

+

+/**

+  Executes an SMBus operation to an SMBus controller.

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance 

+                          that it will use to execute the SMBus transactions.

+  @param  SmBusAddress    The address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will do. 

+                          The maximum number of bytes can be revision specific 

+                          and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave 

+                          device. Not all operations require this argument. The 

+                          length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation.

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  )

+{

+  RETURN_STATUS             ReturnStatus;

+  EFI_SMBUS_DEVICE_ADDRESS  SmbusDeviceAddress;

+

+  SmbusDeviceAddress.SmbusDeviceAddress = SMBUS_LIB_SLAVE_ADDRESS (SmBusAddress);

+

+  ReturnStatus = mSmbus->Execute (

+                           mSmbus,

+                           SmbusDeviceAddress,

+                           SMBUS_LIB_COMMAND (SmBusAddress),

+                           SmbusOperation,

+                           SMBUS_LIB_PEC (SmBusAddress),

+                           &Length,

+                           Buffer

+                           );

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+

+  return Length;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
new file mode 100644
index 0000000..d4f082e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
@@ -0,0 +1,51 @@
+## @file

+# SMBUS Library that layers on top of the SMBUS Protocol.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeSmbusLib

+  MODULE_UNI_FILE                = DxeSmbusLib.uni

+  FILE_GUID                      = 4F369FB1-31A7-423c-960E-B3EFD337894F

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmbusLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER

+

+  CONSTRUCTOR                    = SmbusLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  SmbusLib.c

+  DxeSmbusLib.c

+  InternalSmbusLib.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  UefiBootServicesTableLib

+  DebugLib

+

+

+[Protocols]

+  gEfiSmbusHcProtocolGuid                        ## CONSUMES

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiSmbusHcProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.uni b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.uni
new file mode 100644
index 0000000..abe7244
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/DxeSmbusLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/InternalSmbusLib.h b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/InternalSmbusLib.h
new file mode 100644
index 0000000..da7e58f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/InternalSmbusLib.h
@@ -0,0 +1,85 @@
+/** @file

+Internal header file for Smbus library.

+

+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 __INTERNAL_SMBUS_LIB_H_

+#define __INTERNAL_SMBUS_LIB_H_

+

+

+#include <PiDxe.h>

+

+#include <Protocol/SmbusHc.h>

+

+#include <Library/SmbusLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/BaseMemoryLib.h>

+

+#include <IndustryStandard/SmBus.h>

+

+//

+// Declaration for internal functions

+//

+/**

+  Executes an SMBus operation to an SMBus controller.

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance 

+                          that it will use toexecute the SMBus transactions.

+  @param  SmBusAddress    The address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will 

+                          do. The maximum number of bytes can be revision specific 

+                          and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave

+                          device. Not all operations require this argument. The 

+                          length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation.

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  );

+

+/**

+  The constructor function caches the pointer to Smbus protocol.

+

+  The constructor function locates Smbus protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmbusLibConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/SmbusLib.c b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/SmbusLib.c
new file mode 100644
index 0000000..fe1a094
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeSmbusLib/SmbusLib.c
@@ -0,0 +1,592 @@
+/** @file

+Implementation of SmBusLib class library for DXE phase.

+

+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.

+

+

+**/

+

+#include "InternalSmbusLib.h"

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS:  The SMBUS command was executed.

+                        RETURN_TIMEOUT:  A timeout occurred while executing the 

+                        SMBUS command. 

+                        RETURN_DEVICE_ERROR: The request was not 

+                        completed because a failure reflected in the Host Status 

+                        Register bit.  Device errors are a result of a transaction 

+                        collision, illegal command field, unclaimed cycle (host 

+                        initiated), or bus errors (collisions). 

+                        RETURN_UNSUPPORTED: The SMBus operation is not supported.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickRead, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickWrite, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle(host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)  == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte, Status);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 8-bit value to send.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle(host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Byte   = Value;

+  InternalSmBusExec (EfiSmbusSendByte, SmBusAddress, 1, &Byte, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failurereflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle (host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, 1, &Byte, Status);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 8-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Byte = Value;

+  InternalSmBusExec (EfiSmbusWriteByte, SmBusAddress, 1, &Byte, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is 

+                        incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);

+

+  return Word;

+}

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 16-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the SMBUS 

+                        command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. 

+                        (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Word = Value;

+  InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 16-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is 

+                        incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer        The pointer to the buffer to store the bytes read from 

+                        the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the SMBUS 

+                        command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle (host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is 

+                        incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        MBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer        The pointer to the buffer to store the bytes read from 

+                        the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle (host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is 

+                        incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN  Length;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Length = SMBUS_LIB_LENGTH (SmBusAddress);

+  return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If WriteBuffer is NULL, then ASSERT().

+  If ReadBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  WriteBuffer   The pointer to the buffer of bytes to write to the SMBUS.

+  @param  ReadBuffer    The pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR: The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle (host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is 

+                        incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *WriteBuffer,

+  OUT VOID           *ReadBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN   Length;

+

+  ASSERT (WriteBuffer != NULL);

+  ASSERT (ReadBuffer  != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Length = SMBUS_LIB_LENGTH (SmBusAddress);

+  //

+  // Assuming that ReadBuffer is large enough to save another memory copy.

+  //

+  ReadBuffer = CopyMem (ReadBuffer, WriteBuffer, Length);

+  return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, ReadBuffer, Status);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c b/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c
new file mode 100644
index 0000000..8ca3ec6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.c
@@ -0,0 +1,223 @@
+/** @file

+  This library implements the Timer Library using the Extended SAL Stall Services Class.

+

+  Copyright (c) 2007 - 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

+  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 <PiDxe.h>

+

+#include <Protocol/ExtendedSalServiceClasses.h>

+

+#include <Library/TimerLib.h>

+#include <Library/BaseLib.h>

+#include <Library/ExtendedSalLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PalLib.h>

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  This function wraps EsalStall function of Extended SAL Stall Services Class.

+  It stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return MicroSeconds

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  EsalCall (

+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO,

+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI,

+    StallFunctionId, 

+    MicroSeconds, 

+    0, 

+    0, 

+    0, 

+    0, 

+    0, 

+    0

+    );

+  return MicroSeconds;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  This function wraps EsalStall function of Extended SAL Stall Services Class.

+  It stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return NanoSeconds

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  UINT64          MicroSeconds;

+

+  //

+  // The unit of ESAL Stall service is microsecond, so we turn the time interval

+  // from nanosecond to microsecond, using the ceiling value to ensure stalling

+  // at least the given number of nanoseconds.

+  //

+  MicroSeconds = DivU64x32 (NanoSeconds + 999, 1000);

+  EsalCall (

+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_LO,

+    EFI_EXTENDED_SAL_STALL_SERVICES_PROTOCOL_GUID_HI,

+    StallFunctionId, 

+    MicroSeconds, 

+    0, 

+    0, 

+    0, 

+    0, 

+    0, 

+    0

+    );

+  return NanoSeconds;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  Retrieves the current value of a 64-bit free running performance counter. The

+  counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  return AsmReadItc ();

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  OUT      UINT64                    *StartValue,  OPTIONAL

+  OUT      UINT64                    *EndValue     OPTIONAL

+  )

+{

+  PAL_CALL_RETURN                   PalRet;

+  UINT64                            BaseFrequence;

+

+  //

+  // Get processor base frequency

+  //

+  PalRet = PalCall (PAL_FREQ_BASE, 0, 0, 0);

+  ASSERT (PalRet.Status == 0);

+  BaseFrequence = PalRet.r9;

+

+  //

+  // Get processor frequency ratio

+  //

+  PalRet = PalCall (PAL_FREQ_RATIOS, 0, 0, 0);

+  ASSERT (PalRet.Status == 0);

+

+  //

+  // Start value of counter is 0

+  //

+  if (StartValue != NULL) {

+    *StartValue = 0;

+  }

+

+  //

+  // End value of counter is 0xFFFFFFFFFFFFFFFF

+  //

+  if (EndValue != NULL) {

+    *EndValue = (UINT64)(-1);

+  }

+

+  return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11;

+}

+

+/**

+  Converts elapsed ticks of performance counter to time in nanoseconds.

+

+  This function converts the elapsed ticks of running performance counter to

+  time value in unit of nanoseconds.

+

+  @param  Ticks     The number of elapsed ticks of running performance counter.

+

+  @return The elapsed time in nanoseconds.

+

+**/

+UINT64

+EFIAPI

+GetTimeInNanoSecond (

+  IN      UINT64                     Ticks

+  )

+{

+  UINT64  Frequency;

+  UINT64  NanoSeconds;

+  UINT64  Remainder;

+  INTN    Shift;

+

+  Frequency = GetPerformanceCounterProperties (NULL, NULL);

+

+  //

+  //          Ticks

+  // Time = --------- x 1,000,000,000

+  //        Frequency

+  //

+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);

+

+  //

+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.

+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,

+  // i.e. highest bit set in Remainder should <= 33.

+  //

+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);

+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);

+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);

+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);

+

+  return NanoSeconds;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf b/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf
new file mode 100644
index 0000000..0f24989
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.inf
@@ -0,0 +1,41 @@
+## @file

+#  This library implements the Timer Library using the Extended SAL Stall Services Class.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = DxeTimerLibEsal

+  MODULE_UNI_FILE                = DxeTimerLibEsal.uni

+  FILE_GUID                      = F672AE85-3769-4fb8-A5A0-70B38FB0A7C4

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = TimerLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION 

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  DxeTimerLibEsal.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  ExtendedSalLib

+  BaseLib

+  PalLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.uni b/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.uni
new file mode 100644
index 0000000..2a113bd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/DxeTimerLibEsal/DxeTimerLibEsal.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c b/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c
new file mode 100644
index 0000000..5662ccf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.c
@@ -0,0 +1,101 @@
+/** @file

+  Entry point to a the PEI Core.

+

+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.

+

+**/

+

+

+#include <PiPei.h>

+

+//

+// The Library classes this module produced

+//

+#include <Library/PeiCoreEntryPoint.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  The entry point of PE/COFF Image for the PEI Core.

+

+  This function is the entry point for the PEI Foundation, which allows the SEC phase

+  to pass information about the stack, temporary RAM and the Boot Firmware Volume.

+  In addition, it also allows the SEC phase to pass services and data forward for use

+  during the PEI phase in the form of one or more PPIs.

+  There is no limit to the number of additional PPIs that can be passed from SEC into

+  the PEI Foundation. As part of its initialization phase, the PEI Foundation will add

+  these SEC-hosted PPIs to its PPI database such that both the PEI Foundation and any

+  modules can leverage the associated service calls and/or code in these early PPIs.

+  This function is required to call ProcessModuleEntryPointList() with the Context

+  parameter set to NULL.  ProcessModuleEntryPoint() is never expected to return.

+  The PEI Core is responsible for calling ProcessLibraryConstructorList() as soon as

+  the PEI Services Table and the file handle for the PEI Core itself have been established.

+  If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.

+

+  @param SecCoreData  Points to a data structure containing information about the 

+                      PEI core's operating environment, such as the size and 

+                      location of temporary RAM, the stack location and the BFV 

+                      location.

+                      

+  @param PpiList      Points to a list of one or more PPI descriptors to be 

+                      installed initially by the PEI core. An empty PPI list 

+                      consists of a single descriptor with the end-tag 

+                      EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST.

+                      As part of its initialization phase, the PEI Foundation will

+                      add these SEC-hosted PPIs to its PPI database, such that both 

+                      the PEI Foundation and any modules can leverage the associated 

+                      service calls and/or code in these early PPIs.

+

+**/

+VOID

+EFIAPI 

+_ModuleEntryPoint(

+  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,

+  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList

+)

+{

+  ProcessModuleEntryPointList (SecCoreData, PpiList, NULL);

+  

+  //

+  // Should never return

+  //

+  ASSERT(FALSE);

+  CpuDeadLoop ();  

+}

+

+

+/**

+  Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().

+

+  This function is required to call _ModuleEntryPoint() passing in SecCoreData and PpiList.

+

+  @param SecCoreData  Points to a data structure containing information about the PEI core's

+                      operating environment, such as the size and location of temporary RAM,

+                      the stack location and the BFV location. 

+

+  @param PpiList      Points to a list of one or more PPI descriptors to be installed

+                      initially by the PEI core.  An empty PPI list consists of 

+                      a single descriptor with the end-tag 

+                      EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST.

+                      As part of its initialization phase, the PEI Foundation will 

+                      add these SEC-hosted PPIs to its PPI database, such that both 

+                      the PEI Foundationand any modules can leverage the associated 

+                      service calls and/or code in these early PPIs.

+

+**/

+VOID

+EFIAPI

+EfiMain (

+  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,

+  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList

+  )

+{

+  _ModuleEntryPoint (SecCoreData, PpiList);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf b/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
new file mode 100644
index 0000000..d920306
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
@@ -0,0 +1,39 @@
+## @file

+# Module entry point library for PEI core.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiCoreEntryPoint

+  MODULE_UNI_FILE                = PeiCoreEntryPoint.uni

+  FILE_GUID                      = b3b0654a-969d-4096-86cb-27e262a02083

+  MODULE_TYPE                    = PEI_CORE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeiCoreEntryPoint|PEI_CORE

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiCoreEntryPoint.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.uni b/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.uni
new file mode 100644
index 0000000..c9c3ea4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PeiDxePostCodeLibReportStatusCode.inf b/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PeiDxePostCodeLibReportStatusCode.inf
new file mode 100644
index 0000000..68854ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PeiDxePostCodeLibReportStatusCode.inf
@@ -0,0 +1,45 @@
+## @file

+# Instance of Post Code Library based on Report Status Code Libray.

+#

+# Post Code Library that layers on top of a Report Status Code Libray instance.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiDxePostCodeLibReportStatusCode

+  MODULE_UNI_FILE                = PeiDxePostCodeLibReportStatusCode.uni

+  FILE_GUID                      = e062c52d-78dc-4cc5-b246-b13497a8123c

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PostCodeLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER PEIM PEI_CORE UEFI_APPLICATION UEFI_DRIVER

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PostCode.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  PcdLib

+  ReportStatusCodeLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask     ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PeiDxePostCodeLibReportStatusCode.uni b/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PeiDxePostCodeLibReportStatusCode.uni
new file mode 100644
index 0000000..1406688
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PeiDxePostCodeLibReportStatusCode.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PostCode.c b/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PostCode.c
new file mode 100644
index 0000000..e4a05d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiDxePostCodeLibReportStatusCode/PostCode.c
@@ -0,0 +1,159 @@
+/** @file

+  Post code library instace bases on report status code library

+  PostCode Library for PEIMs and DXE drivers that send PostCode to ReportStatusCode

+

+  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.

+

+**/

+

+

+#include <PiPei.h>

+

+#include <Library/PostCodeLib.h>

+#include <Library/ReportStatusCodeLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+

+/**

+  Converts POST code value to status code value.

+

+  This macro converts the post code to status code value. Bits 0..4 of PostCode

+  are mapped to bits 16..20 of status code value, and bits 5..7 of PostCode are mapped to bits

+  24..26 of status code value.

+

+  @param  PostCode  POST code value.

+

+  @return The converted status code value.

+

+**/

+#define POST_CODE_TO_STATUS_CODE_VALUE(PostCode)  \

+  ((EFI_STATUS_CODE_VALUE) (((PostCode & 0x1f) << 16) | ((PostCode & 0x3) << 19)))

+

+/**

+  Sends an 32-bit value to a POST card.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.  

+  Some implementations of this library function may perform I/O operations 

+  directly to a POST card device.  Other implementations may send Value to 

+  ReportStatusCode(), and the status code reporting mechanism will eventually 

+  display the 32-bit value on the status reporting device.

+  

+  PostCode() must actively prevent recursion.  If PostCode() is called while 

+  processing another any other Post Code Library function, then 

+  PostCode() must return Value immediately.

+

+  @param  Value  The 32-bit value to write to the POST card.

+

+  @return The 32-bit value to write to the POST card.

+

+**/

+UINT32

+EFIAPI

+PostCode (

+  IN UINT32  Value

+  )

+{

+  REPORT_STATUS_CODE (EFI_PROGRESS_CODE, POST_CODE_TO_STATUS_CODE_VALUE (Value));

+  return Value;

+}

+

+

+/**

+  Sends an 32-bit value to a POST and associated ASCII string.

+

+  Sends the 32-bit value specified by Value to a POST card, and returns Value.

+  If Description is not NULL, then the ASCII string specified by Description is 

+  also passed to the handler that displays the POST card value.  Some 

+  implementations of this library function may perform I/O operations directly 

+  to a POST card device.  Other implementations may send Value to ReportStatusCode(), 

+  and the status code reporting mechanism will eventually display the 32-bit 

+  value on the status reporting device.  

+

+  PostCodeWithDescription()must actively prevent recursion.  If 

+  PostCodeWithDescription() is called while processing another any other Post 

+  Code Library function, then PostCodeWithDescription() must return Value 

+  immediately.

+

+  @param  Value        The 32-bit value to write to the POST card.

+  @param  Description  The pointer to an ASCII string that is a description of the 

+                       POST code value.  This is an optional parameter that may 

+                       be NULL.

+

+  @return The 32-bit value to write to the POST card.

+

+**/

+UINT32

+EFIAPI

+PostCodeWithDescription (

+  IN UINT32       Value,

+  IN CONST CHAR8  *Description  OPTIONAL

+  )

+{

+  if (Description == NULL) {

+    REPORT_STATUS_CODE (

+      EFI_PROGRESS_CODE,

+      POST_CODE_TO_STATUS_CODE_VALUE (Value)

+      );

+  } else {

+    REPORT_STATUS_CODE_WITH_EXTENDED_DATA (

+      EFI_PROGRESS_CODE,

+      POST_CODE_TO_STATUS_CODE_VALUE (Value),

+      Description,

+      AsciiStrSize (Description)

+      );

+  }

+

+  return Value;

+}

+

+

+/**

+  Returns TRUE if POST Codes are enabled.

+

+  This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_ENABLED 

+  bit of PcdPostCodePropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdPostCodeProperyMask is set.

+  @retval  FALSE  The POST_CODE_PROPERTY_POST_CODE_ENABLED bit of 

+                  PcdPostCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PostCodeEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_ENABLED) != 0);

+}

+

+

+/**

+  Returns TRUE if POST code descriptions are enabled.

+

+  This function returns TRUE if the POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED

+  bit of PcdPostCodePropertyMask is set.  Otherwise FALSE is returned.

+

+  @retval  TRUE   The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of

+                  PcdPostCodeProperyMask is set.

+  @retval  FALSE  The POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED bit of

+                  PcdPostCodeProperyMask is clear.

+

+**/

+BOOLEAN

+EFIAPI

+PostCodeDescriptionEnabled (

+  VOID

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdPostCodePropertyMask) & POST_CODE_PROPERTY_POST_CODE_DESCRIPTION_ENABLED) != 0);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.c
new file mode 100644
index 0000000..c471ae9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.c
@@ -0,0 +1,519 @@
+/** @file

+  Provide generic extract guided section functions for PEI phase.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiPei.h>

+

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/HobLib.h>

+#include <Library/ExtractGuidedSectionLib.h>

+

+#define PEI_EXTRACT_HANDLER_INFO_SIGNATURE SIGNATURE_32 ('P', 'E', 'H', 'I')

+

+typedef struct {

+  UINT32                                  Signature;

+  UINT32                                  NumberOfExtractHandler;

+  GUID                                    *ExtractHandlerGuidTable;

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER   *ExtractDecodeHandlerTable;

+  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;

+} PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO;

+

+/**

+  Build guid hob for the global memory to store the registered guid and Handler list.

+  If GuidHob exists, HandlerInfo will be directly got from Guid hob data.

+

+  @param[in, out]  InfoPointer   The pointer to pei handler information structure.

+

+  @retval  RETURN_SUCCESS            Build Guid hob for the global memory space to store guid and function tables.

+  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to allocated.

+**/

+RETURN_STATUS

+PeiGetExtractGuidedSectionHandlerInfo (

+  IN OUT PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO **InfoPointer

+  )

+{

+  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+  EFI_PEI_HOB_POINTERS                    Hob;

+  

+  //

+  // First try to get handler information from guid hob specified by CallerId.

+  //

+  Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GetHobList ());

+  while (Hob.Raw != NULL) {

+    if (CompareGuid (&(Hob.Guid->Name), &gEfiCallerIdGuid)) {

+      HandlerInfo = (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *) GET_GUID_HOB_DATA (Hob.Guid);

+      if (HandlerInfo->Signature == PEI_EXTRACT_HANDLER_INFO_SIGNATURE) {

+        //

+        // Update Table Pointer when hob start address is changed.

+        //

+        if (HandlerInfo->ExtractHandlerGuidTable != (GUID *) (HandlerInfo + 1)) {

+          HandlerInfo->ExtractHandlerGuidTable    = (GUID *) (HandlerInfo + 1);

+          HandlerInfo->ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (

+                                                      (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + 

+                                                      PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)

+                                                     );

+          HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (

+                                                      (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + 

+                                                      PcdGet32 (PcdMaximumGuidedExtractHandler) * 

+                                                      sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)

+                                                     );

+        }

+        //

+        // Return HandlerInfo pointer.

+        //

+        *InfoPointer = HandlerInfo;

+        return EFI_SUCCESS;

+      }

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, Hob.Raw);

+  }

+  

+  //

+  // If Guid Hob is not found, Build CallerId Guid hob to store Handler Info

+  //

+  HandlerInfo = BuildGuidHob (

+                 &gEfiCallerIdGuid, 

+                 sizeof (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO) +

+                 PcdGet32 (PcdMaximumGuidedExtractHandler) * 

+                 (sizeof (GUID) + sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) + sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER))

+                );

+  if (HandlerInfo == NULL) {

+    //

+    // No enough resource to build guid hob.

+    //

+    *InfoPointer = NULL;

+    return EFI_OUT_OF_RESOURCES;

+  }

+  //

+  // Init HandlerInfo structure

+  //

+  HandlerInfo->Signature = PEI_EXTRACT_HANDLER_INFO_SIGNATURE;

+  HandlerInfo->NumberOfExtractHandler     = 0;

+  HandlerInfo->ExtractHandlerGuidTable    = (GUID *) (HandlerInfo + 1);

+  HandlerInfo->ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (

+                                              (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + 

+                                              PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)

+                                             );

+  HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (

+                                              (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + 

+                                              PcdGet32 (PcdMaximumGuidedExtractHandler) * 

+                                              sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)

+                                             );

+  //

+  // return the created HandlerInfo.

+  //

+  *InfoPointer = HandlerInfo;

+  return EFI_SUCCESS;

+}

+

+/**

+  Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().

+

+  Sets ExtractHandlerGuidTable so it points at a callee allocated array of registered GUIDs.

+  The total number of GUIDs in the array are returned. Since the array of GUIDs is callee allocated

+  and caller must treat this array of GUIDs as read-only data. 

+  If ExtractHandlerGuidTable is NULL, then ASSERT().

+

+  @param[out]  ExtractHandlerGuidTable  A pointer to the array of GUIDs that have been registered through

+                                        ExtractGuidedSectionRegisterHandlers().

+

+  @return the number of the supported extract guided Handler.

+

+**/

+UINTN

+EFIAPI

+ExtractGuidedSectionGetGuidList (

+  OUT  GUID  **ExtractHandlerGuidTable

+  )

+{

+  EFI_STATUS Status;

+  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+

+  ASSERT (ExtractHandlerGuidTable != NULL);

+

+  //

+  // Get all registered handler information

+  //

+  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (EFI_ERROR (Status)) {

+    *ExtractHandlerGuidTable = NULL;

+    return 0;

+  }

+

+  //

+  // Get GuidTable and Table Number

+  //

+  ASSERT (HandlerInfo != NULL);

+  *ExtractHandlerGuidTable = HandlerInfo->ExtractHandlerGuidTable;

+  return HandlerInfo->NumberOfExtractHandler;

+}

+

+/**

+  Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER

+  for a specific GUID section type.

+

+  Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.

+  If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.

+  If there are not enough resources available to register the handlers  then RETURN_OUT_OF_RESOURCES is returned.

+  

+  If SectionGuid is NULL, then ASSERT().

+  If GetInfoHandler is NULL, then ASSERT().

+  If DecodeHandler is NULL, then ASSERT().

+

+  @param[in]  SectionGuid    A pointer to the GUID associated with the the handlers

+                             of the GUIDed section type being registered.

+  @param[in]  GetInfoHandler The pointer to a function that examines a GUIDed section and returns the

+                             size of the decoded buffer and the size of an optional scratch buffer

+                             required to actually decode the data in a GUIDed section.

+  @param[in]  DecodeHandler  The pointer to a function that decodes a GUIDed section into a caller

+                             allocated output buffer. 

+

+  @retval  RETURN_SUCCESS           The handlers were registered.

+  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to register the handlers.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionRegisterHandlers (

+  IN CONST  GUID                                     *SectionGuid,

+  IN        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  GetInfoHandler,

+  IN        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    DecodeHandler

+  )

+{

+  EFI_STATUS Status;

+  UINT32     Index;

+  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+

+  //

+  // Check input paramter

+  //

+  ASSERT (SectionGuid != NULL);

+  ASSERT (GetInfoHandler != NULL);

+  ASSERT (DecodeHandler != NULL);

+

+

+

+  //

+  // Get the registered handler information

+  //

+  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {

+      //

+      // If the guided handler has been registered before, only update its handler.

+      //

+      HandlerInfo->ExtractDecodeHandlerTable [Index] = DecodeHandler;

+      HandlerInfo->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;

+      return RETURN_SUCCESS;

+    }

+  }

+

+  //

+  // Check the global table is enough to contain new Handler.

+  //

+  if (HandlerInfo->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {

+    return RETURN_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Register new Handler and guid value.

+  //

+  CopyGuid (HandlerInfo->ExtractHandlerGuidTable + HandlerInfo->NumberOfExtractHandler, SectionGuid);

+  HandlerInfo->ExtractDecodeHandlerTable [HandlerInfo->NumberOfExtractHandler] = DecodeHandler;

+  HandlerInfo->ExtractGetInfoHandlerTable [HandlerInfo->NumberOfExtractHandler++] = GetInfoHandler;

+

+  //

+  // Build the Guided Section GUID HOB to record the GUID itself.

+  // Then the content of the GUIDed HOB will be the same as the GUID value itself.

+  //

+  BuildGuidDataHob (

+    (EFI_GUID *) SectionGuid,

+    (VOID *) SectionGuid,

+    sizeof (GUID)

+    );

+

+  return RETURN_SUCCESS;

+}

+

+/**

+  Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type

+  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().

+  The selected handler is used to retrieve and return the size of the decoded buffer and the size of an

+  optional scratch buffer required to actually decode the data in a GUIDed section.

+

+  Examines a GUIDed section specified by InputSection.  

+  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),

+  then RETURN_UNSUPPORTED is returned.  

+  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler 

+  of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()

+  is used to retrieve the OututBufferSize, ScratchSize, and Attributes values. The return status from the handler of

+  type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned.

+  

+  If InputSection is NULL, then ASSERT().

+  If OutputBufferSize is NULL, then ASSERT().

+  If ScratchBufferSize is NULL, then ASSERT().

+  If SectionAttribute is NULL, then ASSERT().

+

+  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.

+  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required if the buffer

+                                 specified by InputSection were decoded.

+  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space if the buffer specified by

+                                 InputSection were decoded.

+  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section.  See the Attributes field of

+                                 EFI_GUID_DEFINED_SECTION in the PI Specification.

+

+  @retval  RETURN_SUCCESS      Get the required information successfully.

+  @retval  RETURN_UNSUPPORTED  The GUID from the section specified by InputSection does not match any of

+                               the GUIDs registered with ExtractGuidedSectionRegisterHandlers().

+  @retval  Others              The return status from the handler associated with the GUID retrieved from

+                               the section specified by InputSection.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionGetInfo (

+  IN  CONST VOID    *InputSection,

+  OUT       UINT32  *OutputBufferSize,

+  OUT       UINT32  *ScratchBufferSize,

+  OUT       UINT16  *SectionAttribute   

+  )

+{

+  UINT32 Index;

+  EFI_STATUS Status;

+  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+  EFI_GUID *SectionDefinitionGuid;

+  

+  //

+  // Check input paramter

+  //

+  ASSERT (InputSection != NULL);

+  ASSERT (OutputBufferSize != NULL);

+  ASSERT (ScratchBufferSize != NULL);

+  ASSERT (SectionAttribute != NULL);

+

+  //

+  // Get all registered handler information.

+  //

+  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (IS_SECTION2 (InputSection)) {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);

+  } else {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);

+  }

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {

+      //

+      // Call the match handler to get information for the input section data.

+      //

+      return HandlerInfo->ExtractGetInfoHandlerTable [Index] (

+                InputSection,

+                OutputBufferSize,

+                ScratchBufferSize,

+                SectionAttribute

+              );

+    }

+  }

+

+  //

+  // Not found, the input guided section is not supported. 

+  //

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().

+  The selected handler is used to decode the data in a GUIDed section and return the result in a caller

+  allocated output buffer.

+

+  Decodes the GUIDed section specified by InputSection.  

+  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),

+  then RETURN_UNSUPPORTED is returned.  

+  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler

+  of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()

+  is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this

+  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the data in InputSection,

+  then OutputBuffer is set to point at the data in InputSection.  Otherwise, the decoded data will be placed in caller

+  allocated buffer specified by OutputBuffer.    This function is responsible for computing the  EFI_AUTH_STATUS_PLATFORM_OVERRIDE

+  bit of in AuthenticationStatus.  The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned. 

+   

+  If InputSection is NULL, then ASSERT().

+  If OutputBuffer is NULL, then ASSERT().

+  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().

+  If AuthenticationStatus is NULL, then ASSERT().  

+

+  @param[in]  InputSection   A pointer to a GUIDed section of an FFS formatted file.

+  @param[out] OutputBuffer   A pointer to a buffer that contains the result of a decode operation. 

+  @param[in]  ScratchBuffer  A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation. 

+  @param[out] AuthenticationStatus 

+                             A pointer to the authentication status of the decoded output buffer. See the definition

+                             of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI

+                             Specification.

+

+  @retval  RETURN_SUCCESS           The buffer specified by InputSection was decoded.

+  @retval  RETURN_UNSUPPORTED       The section specified by InputSection does not match the GUID this handler supports.

+  @retval  RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionDecode (

+  IN  CONST VOID    *InputSection,

+  OUT       VOID    **OutputBuffer,

+  IN        VOID    *ScratchBuffer,        OPTIONAL

+  OUT       UINT32  *AuthenticationStatus  

+  )

+{

+  UINT32     Index;

+  EFI_STATUS Status;

+  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

+  EFI_GUID *SectionDefinitionGuid;

+  

+  //

+  // Check input parameter

+  //

+  ASSERT (InputSection != NULL);

+  ASSERT (OutputBuffer != NULL);

+  ASSERT (AuthenticationStatus != NULL);

+

+  //

+  // Get all registered handler information.

+  //  

+  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  if (IS_SECTION2 (InputSection)) {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);

+  } else {

+    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);

+  }

+

+  //

+  // Search the match registered Extract handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {

+      //

+      // Call the match handler to extract raw data for the input guided section.

+      //

+      return HandlerInfo->ExtractDecodeHandlerTable [Index] (

+                InputSection,

+                OutputBuffer,

+                ScratchBuffer,

+                AuthenticationStatus

+              );

+    }

+  }

+

+  //

+  // Not found, the input guided section is not supported. 

+  //

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and 

+  EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.

+  

+  Retrieves the handlers associated with SectionGuid and returns them in 

+  GetInfoHandler and DecodeHandler.

+

+  If the GUID value specified by SectionGuid has not been registered, then 

+  return RETURN_NOT_FOUND.

+  

+  If SectionGuid is NULL, then ASSERT().

+

+  @param[in]  SectionGuid    A pointer to the GUID associated with the handlersof the GUIDed 

+                             section type being retrieved.

+  @param[out] GetInfoHandler Pointer to a function that examines a GUIDed section and returns 

+                             the size of the decoded buffer and the size of an optional scratch 

+                             buffer required to actually decode the data in a GUIDed section.  

+                             This is an optional parameter that may be NULL. If it is NULL, then 

+                             the previously registered handler is not returned.

+  @param[out] DecodeHandler  Pointer to a function that decodes a GUIDed section into a caller

+                             allocated output buffer. This is an optional parameter that may be NULL.

+                             If it is NULL, then the previously registered handler is not returned.

+

+  @retval  RETURN_SUCCESS     The handlers were retrieved.

+  @retval  RETURN_NOT_FOUND   No handlers have been registered with the specified GUID.

+

+**/

+RETURN_STATUS

+EFIAPI

+ExtractGuidedSectionGetHandlers (

+  IN CONST   GUID                                     *SectionGuid,

+  OUT        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  *GetInfoHandler,  OPTIONAL

+  OUT        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    *DecodeHandler    OPTIONAL

+  )

+{

+  EFI_STATUS                               Status;

+  UINT32                                   Index;

+  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO  *HandlerInfo;

+

+  //

+  // Check input parameter

+  //

+  ASSERT (SectionGuid != NULL);

+

+  //

+  // Get the registered handler information

+  //

+  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

+

+  //

+  // Search the match registered GetInfo handler for the input guided section.

+  //

+  ASSERT (HandlerInfo != NULL);

+  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {

+    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {

+

+      //

+      // If the guided handler has been registered before, then return the registered handlers.

+      //

+      if (GetInfoHandler != NULL) {

+        *GetInfoHandler = HandlerInfo->ExtractGetInfoHandlerTable[Index];

+      }

+      if (DecodeHandler != NULL) {

+        *DecodeHandler = HandlerInfo->ExtractDecodeHandlerTable[Index];

+      }

+      return RETURN_SUCCESS;

+    }

+  }

+  return RETURN_NOT_FOUND;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
new file mode 100644
index 0000000..1b6e6a8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
@@ -0,0 +1,48 @@
+## @file

+# Instance of ExtractGuidedSection Library for PEI phase.

+#

+# This library provides generic extract guided section functions for PEIM and PEI_CORE module.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiExtractGuidedSectionLib

+  MODULE_UNI_FILE                = PeiExtractGuidedSectionLib.uni

+  FILE_GUID                      = 41ddf016-2a11-415f-8880-00d938e9541a

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ExtractGuidedSectionLib|PEIM PEI_CORE

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiExtractGuidedSectionLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  DebugLib

+  HobLib

+  PcdLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler     ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.uni
new file mode 100644
index 0000000..f723344
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/HobLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/HobLib.c
new file mode 100644
index 0000000..f3ce93a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/HobLib.c
@@ -0,0 +1,736 @@
+/** @file

+  Provide Hob Library functions for Pei phase.

+

+Copyright (c) 2007 - 2014, 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 <PiPei.h>

+

+#include <Guid/MemoryAllocationHob.h>

+

+#include <Library/HobLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/BaseMemoryLib.h>

+

+/**

+  Returns the pointer to the HOB list.

+

+  This function returns the pointer to first HOB in the list.

+  For PEI phase, the PEI service GetHobList() can be used to retrieve the pointer 

+  to the HOB list.  For the DXE phase, the HOB list pointer can be retrieved through

+  the EFI System Table by looking up theHOB list GUID in the System Configuration Table.

+  Since the System Configuration Table does not exist that the time the DXE Core is 

+  launched, the DXE Core uses a global variable from the DXE Core Entry Point Library 

+  to manage the pointer to the HOB list.

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+  

+  @return The pointer to the HOB list.

+

+**/

+VOID *

+EFIAPI

+GetHobList (

+  VOID

+  )

+{

+  EFI_STATUS            Status;

+  VOID                  *HobList;

+

+  Status = PeiServicesGetHobList (&HobList);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (HobList != NULL);

+

+  return HobList;

+}

+

+/**

+  Returns the next instance of a HOB type from the starting HOB.

+

+  This function searches the first instance of a HOB type from the starting HOB pointer. 

+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  

+  If HobStart is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+  @param  HobStart      The starting HOB pointer to search from.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextHob (

+  IN UINT16                 Type,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  ASSERT (HobStart != NULL);

+   

+  Hob.Raw = (UINT8 *) HobStart;

+  //

+  // Parse the HOB list until end of list or matching type is found.

+  //

+  while (!END_OF_HOB_LIST (Hob)) {

+    if (Hob.Header->HobType == Type) {

+      return Hob.Raw;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+  }

+  return NULL;

+}

+

+/**

+  Returns the first instance of a HOB type among the whole HOB list.

+

+  This function searches the first instance of a HOB type among the whole HOB list. 

+  If there does not exist such HOB type in the HOB list, it will return NULL. 

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+

+  @param  Type          The HOB type to return.

+

+  @return The next instance of a HOB type from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetFirstHob (

+  IN UINT16                 Type

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextHob (Type, HobList);

+}

+

+/**

+  Returns the next instance of the matched GUID HOB from the starting HOB.

+  

+  This function searches the first instance of a HOB from the starting HOB pointer. 

+  Such HOB should satisfy two conditions: 

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size information, respectively.

+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer

+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;

+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.

+  

+  If Guid is NULL, then ASSERT().

+  If HobStart is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+  @param  HobStart      A pointer to a Guid.

+

+  @return The next instance of the matched GUID HOB from the starting HOB.

+

+**/

+VOID *

+EFIAPI

+GetNextGuidHob (

+  IN CONST EFI_GUID         *Guid,

+  IN CONST VOID             *HobStart

+  )

+{

+  EFI_PEI_HOB_POINTERS  GuidHob;

+

+  GuidHob.Raw = (UINT8 *) HobStart;

+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {

+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {

+      break;

+    }

+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);

+  }

+  return GuidHob.Raw;

+}

+

+/**

+  Returns the first instance of the matched GUID HOB among the whole HOB list.

+  

+  This function searches the first instance of a HOB among the whole HOB list. 

+  Such HOB should satisfy two conditions:

+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.

+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.

+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()

+  to extract the data section and its size information, respectively.

+  

+  If the pointer to the HOB list is NULL, then ASSERT().

+  If Guid is NULL, then ASSERT().

+

+  @param  Guid          The GUID to match with in the HOB list.

+

+  @return The first instance of the matched GUID HOB among the whole HOB list.

+

+**/

+VOID *

+EFIAPI

+GetFirstGuidHob (

+  IN CONST EFI_GUID         *Guid

+  )

+{

+  VOID      *HobList;

+

+  HobList = GetHobList ();

+  return GetNextGuidHob (Guid, HobList);

+}

+

+/**

+  Get the system boot mode from the HOB list.

+

+  This function returns the system boot mode information from the 

+  PHIT HOB in HOB list.

+

+  If the pointer to the HOB list is NULL, then ASSERT().

+  

+  @param  VOID.

+

+  @return The Boot Mode.

+

+**/

+EFI_BOOT_MODE

+EFIAPI

+GetBootModeHob (

+  VOID

+  )

+{

+  EFI_STATUS             Status;

+  EFI_BOOT_MODE          BootMode;

+

+  Status = PeiServicesGetBootMode (&BootMode);

+  ASSERT_EFI_ERROR (Status);

+

+  return BootMode;

+}

+

+/**

+  Adds a new HOB to the HOB List.

+

+  This internal function enables PEIMs to create various types of HOBs.

+

+  @param  Type          Type of the new HOB.

+  @param  Length        Length of the new HOB to allocate.

+

+  @retval  NULL         The HOB could not be allocated.

+  @retval  others       The address of new HOB.

+

+**/

+VOID *

+EFIAPI

+InternalPeiCreateHob (

+  IN UINT16                      Type,

+  IN UINT16                      Length

+  )

+{

+  EFI_STATUS        Status;

+  VOID              *Hob;

+

+  Status = PeiServicesCreateHob (Type, Length, &Hob);

+  if (EFI_ERROR (Status)) {

+    Hob = NULL;

+  }

+  //

+  // Assume the process of HOB building is always successful.

+  //

+  ASSERT (Hob != NULL);

+  return Hob;

+}

+

+/**

+  Builds a HOB for a loaded PE32 module.

+

+  This function builds a HOB for a loaded PE32 module.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If ModuleName is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ModuleName              The GUID File Name of the module.

+  @param  MemoryAllocationModule  The 64 bit physical address of the module.

+  @param  ModuleLength            The length of the module in bytes.

+  @param  EntryPoint              The 64 bit physical address of the module entry point.

+

+**/

+VOID

+EFIAPI

+BuildModuleHob (

+  IN CONST EFI_GUID         *ModuleName,

+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,

+  IN UINT64                 ModuleLength,

+  IN EFI_PHYSICAL_ADDRESS   EntryPoint

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;

+

+  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&

+          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));

+  if (Hob == NULL) {

+    return;

+  }

+

+  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);

+  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;

+  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;

+  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;

+

+  //

+  // Zero the reserved space to match HOB spec

+  //

+  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));

+  

+  CopyGuid (&Hob->ModuleName, ModuleName);

+  Hob->EntryPoint = EntryPoint;

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory with Owner GUID.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+  @param  OwnerGUID           GUID for the owner of this resource.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorWithOwnerHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes,

+  IN EFI_GUID                     *OwnerGUID

+  )

+{

+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (UINT16) sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));

+  if (Hob == NULL) {

+    return;

+  }

+

+  Hob->ResourceType      = ResourceType;

+  Hob->ResourceAttribute = ResourceAttribute;

+  Hob->PhysicalStart     = PhysicalStart;

+  Hob->ResourceLength    = NumberOfBytes;

+

+  CopyGuid (&Hob->Owner, OwnerGUID);

+}

+

+/**

+  Builds a HOB that describes a chunk of system memory.

+

+  This function builds a HOB that describes a chunk of system memory.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  ResourceType        The type of resource described by this HOB.

+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.

+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.

+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.

+

+**/

+VOID

+EFIAPI

+BuildResourceDescriptorHob (

+  IN EFI_RESOURCE_TYPE            ResourceType,

+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,

+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,

+  IN UINT64                       NumberOfBytes

+  )

+{

+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (UINT16) sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));

+  if (Hob == NULL) {

+    return;

+  }

+

+  Hob->ResourceType      = ResourceType;

+  Hob->ResourceAttribute = ResourceAttribute;

+  Hob->PhysicalStart     = PhysicalStart;

+  Hob->ResourceLength    = NumberOfBytes;

+  ZeroMem (&(Hob->Owner), sizeof (EFI_GUID));

+}

+

+/**

+  Builds a customized HOB tagged with a GUID for identification and returns 

+  the start address of GUID HOB data.

+

+  This function builds a customized HOB tagged with a GUID for identification 

+  and returns the start address of GUID HOB data so that caller can fill the customized data. 

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If Guid is NULL, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().

+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @retval  NULL         The GUID HOB could not be allocated.

+  @retval  others       The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidHob (

+  IN CONST EFI_GUID              *Guid,

+  IN UINTN                       DataLength

+  )

+{

+  EFI_HOB_GUID_TYPE *Hob;

+

+  //

+  // Make sure Guid is valid

+  //

+  ASSERT (Guid != NULL);

+  

+  //

+  // Make sure that data length is not too long.

+  //

+  ASSERT (DataLength <= (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)));

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));

+  if (Hob == NULL) {

+    return Hob;

+  }

+  CopyGuid (&Hob->Name, Guid);

+  return Hob + 1;

+}

+

+/**

+  Builds a customized HOB tagged with a GUID for identification, copies the input data to the HOB 

+  data field, and returns the start address of the GUID HOB data.

+

+  This function builds a customized HOB tagged with a GUID for identification and copies the input

+  data to the HOB data field and returns the start address of the GUID HOB data.  It can only be 

+  invoked during PEI phase; for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.  

+  The HOB Header and Name field is already stripped.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If Guid is NULL, then ASSERT().

+  If Data is NULL and DataLength > 0, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+  If DataLength > (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().

+  HobLength is UINT16 and multiples of 8 bytes, so the max HobLength is 0xFFF8.

+

+  @param  Guid          The GUID to tag the customized HOB.

+  @param  Data          The data to be copied into the data field of the GUID HOB.

+  @param  DataLength    The size of the data payload for the GUID HOB.

+

+  @retval  NULL         The GUID HOB could not be allocated.

+  @retval  others       The start address of GUID HOB data.

+

+**/

+VOID *

+EFIAPI

+BuildGuidDataHob (

+  IN CONST EFI_GUID              *Guid,

+  IN VOID                        *Data,

+  IN UINTN                       DataLength

+  )

+{

+  VOID  *HobData;

+

+  ASSERT (Data != NULL || DataLength == 0);

+

+  HobData = BuildGuidHob (Guid, DataLength);

+  if (HobData == NULL) {

+    return HobData;

+  }

+

+  return CopyMem (HobData, Data, DataLength);

+}

+

+/**

+  Builds a Firmware Volume HOB.

+

+  This function builds a Firmware Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildFvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  EFI_HOB_FIRMWARE_VOLUME  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV, (UINT16) sizeof (EFI_HOB_FIRMWARE_VOLUME));

+  if (Hob == NULL) {

+    return;

+  }

+

+  Hob->BaseAddress = BaseAddress;

+  Hob->Length      = Length;

+}

+

+/**

+  Builds a EFI_HOB_TYPE_FV2 HOB.

+

+  This function builds a EFI_HOB_TYPE_FV2 HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Firmware Volume.

+  @param  Length        The size of the Firmware Volume in bytes.

+  @param  FvName        The name of the Firmware Volume.

+  @param  FileName      The name of the file.

+  

+**/

+VOID

+EFIAPI

+BuildFv2Hob (

+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN          UINT64                      Length,

+  IN CONST    EFI_GUID                    *FvName,

+  IN CONST    EFI_GUID                    *FileName

+  )

+{

+  EFI_HOB_FIRMWARE_VOLUME2  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV2, (UINT16) sizeof (EFI_HOB_FIRMWARE_VOLUME2));

+  if (Hob == NULL) {

+    return;

+  }

+

+  Hob->BaseAddress = BaseAddress;

+  Hob->Length      = Length;

+  CopyGuid (&Hob->FvName, FvName);

+  CopyGuid (&Hob->FileName, FileName);

+}

+

+/**

+  Builds a Capsule Volume HOB.

+

+  This function builds a Capsule Volume HOB.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If the platform does not support Capsule Volume HOBs, then ASSERT().

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The base address of the Capsule Volume.

+  @param  Length        The size of the Capsule Volume in bytes.

+

+**/

+VOID

+EFIAPI

+BuildCvHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  EFI_HOB_UEFI_CAPSULE  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_UEFI_CAPSULE, (UINT16) sizeof (EFI_HOB_UEFI_CAPSULE));

+  if (Hob == NULL) {

+    return;

+  }

+

+  Hob->BaseAddress  = BaseAddress;

+  Hob->Length       = Length;

+}

+

+/**

+  Builds a HOB for the CPU.

+

+  This function builds a HOB for the CPU.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.

+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.

+

+**/

+VOID

+EFIAPI

+BuildCpuHob (

+  IN UINT8                       SizeOfMemorySpace,

+  IN UINT8                       SizeOfIoSpace

+  )

+{

+  EFI_HOB_CPU  *Hob;

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CPU, (UINT16) sizeof (EFI_HOB_CPU));

+  if (Hob == NULL) {

+    return;

+  }

+

+  Hob->SizeOfMemorySpace = SizeOfMemorySpace;

+  Hob->SizeOfIoSpace     = SizeOfIoSpace;

+

+  //

+  // Zero the reserved space to match HOB spec

+  //

+  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved)); 

+}

+

+/**

+  Builds a HOB for the Stack.

+

+  This function builds a HOB for the stack.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the Stack.

+  @param  Length        The length of the stack in bytes.

+

+**/

+VOID

+EFIAPI

+BuildStackHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;

+

+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&

+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));

+  if (Hob == NULL) {

+    return;

+  }

+

+  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);

+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;

+  Hob->AllocDescriptor.MemoryLength      = Length;

+  Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;

+

+  //

+  // Zero the reserved space to match HOB spec

+  //

+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));

+}

+

+/**

+  Builds a HOB for the BSP store.

+

+  This function builds a HOB for BSP store.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the BSP.

+  @param  Length        The length of the BSP store in bytes.

+  @param  MemoryType    The type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildBspStoreHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION_BSP_STORE  *Hob;

+

+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&

+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));

+

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_BSP_STORE));

+  if (Hob == NULL) {

+    return;

+  }

+

+  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocBspStoreGuid);

+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;

+  Hob->AllocDescriptor.MemoryLength      = Length;

+  Hob->AllocDescriptor.MemoryType        = MemoryType;

+

+  //

+  // Zero the reserved space to match HOB spec

+  //

+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));

+}

+

+/**

+  Builds a HOB for the memory allocation.

+

+  This function builds a HOB for the memory allocation.

+  It can only be invoked during PEI phase;

+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.

+  

+  If there is no additional space for HOB creation, then ASSERT().

+

+  @param  BaseAddress   The 64 bit physical address of the memory.

+  @param  Length        The length of the memory allocation in bytes.

+  @param  MemoryType    The type of memory allocated by this HOB.

+

+**/

+VOID

+EFIAPI

+BuildMemoryAllocationHob (

+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,

+  IN UINT64                      Length,

+  IN EFI_MEMORY_TYPE             MemoryType

+  )

+{

+  EFI_HOB_MEMORY_ALLOCATION  *Hob;

+

+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&

+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));

+  

+  Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION));

+  if (Hob == NULL) {

+    return;

+  }

+  

+  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));

+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;

+  Hob->AllocDescriptor.MemoryLength      = Length;

+  Hob->AllocDescriptor.MemoryType        = MemoryType;

+  //

+  // Zero the reserved space to match HOB spec

+  //

+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/PeiHobLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/PeiHobLib.inf
new file mode 100644
index 0000000..027ba6f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -0,0 +1,56 @@
+## @file

+# Instance of HOB Library using PEI Services.

+#

+# HOB Library implementation that uses PEI Services to retrieve the HOB List.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiHobLib

+  MODULE_UNI_FILE                = PeiHobLib.uni

+  FILE_GUID                      = 9643128f-ac24-4b3e-b6be-d8849a306153

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = HobLib|PEIM PEI_CORE SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  HobLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  PeiServicesLib

+  DebugLib

+

+[Guids]

+  gEfiHobMemoryAllocStackGuid                   ## SOMETIMES_PRODUCES ## HOB # MemoryAllocation StackHob

+  gEfiHobMemoryAllocBspStoreGuid                ## SOMETIMES_PRODUCES ## HOB # MemoryAllocation BspStoreHob

+  gEfiHobMemoryAllocModuleGuid                  ## SOMETIMES_PRODUCES ## HOB # MemoryAllocation ModuleHob

+

+#

+# [Hob]

+#   MEMORY_ALLOCATION     ## SOMETIMES_PRODUCES

+#   RESOURCE_DESCRIPTOR   ## SOMETIMES_PRODUCES

+#   FIRMWARE_VOLUME       ## SOMETIMES_PRODUCES

+#   

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/PeiHobLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/PeiHobLib.uni
new file mode 100644
index 0000000..2def867
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiHobLib/PeiHobLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
new file mode 100644
index 0000000..ce73658
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoHighLevel.c
@@ -0,0 +1,2356 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  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.

+

+**/

+

+

+#include <PiPei.h>

+

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) | OrData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) & AndData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) ((IoRead8 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. 

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, 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 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) | OrData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) & AndData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) ((IoRead16 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, 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 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, 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 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, 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 I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) | OrData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) & AndData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) ((MmioRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, 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 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) | OrData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) & AndData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) ((MmioRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, 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 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, 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 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise 

+  OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise 

+  OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, 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 MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoLib.c
new file mode 100644
index 0000000..1f50a12
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoLib.c
@@ -0,0 +1,574 @@
+/** @file

+  I/O Library. The implementations are based on EFI_PEI_SERVICE->CpuIo interface.

+

+  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.

+

+**/

+

+

+#include <PiPei.h>

+

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  return CpuIo->IoRead8 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  CpuIo->IoWrite8 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return CpuIo->IoRead16 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  CpuIo->IoWrite16 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return CpuIo->IoRead32 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+  

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  CpuIo->IoWrite32 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return CpuIo->IoRead64 (PeiServices, CpuIo, (UINT64) Port);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  CpuIo->IoWrite64 (PeiServices, CpuIo, (UINT64) Port, Value);

+  return Value;;

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  return CpuIo->MemRead8 (PeiServices, CpuIo, (UINT64) Address);

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+

+  CpuIo->MemWrite8 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return CpuIo->MemRead16 (PeiServices, CpuIo, (UINT64) Address);

+

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  CpuIo->MemWrite16 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return CpuIo->MemRead32 (PeiServices, CpuIo, (UINT64) Address);

+

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+  

+  @return Value.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  CpuIo->MemWrite32 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & (sizeof (UINT64) - 1)) == 0);

+  return CpuIo->MemRead64 (PeiServices, CpuIo, (UINT64) Address);

+

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  CONST EFI_PEI_SERVICES            **PeiServices;

+  EFI_PEI_CPU_IO_PPI                *CpuIo;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  CpuIo       = (*PeiServices)->CpuIo;

+  ASSERT (CpuIo != NULL);

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  CpuIo->MemWrite64 (PeiServices, CpuIo, (UINT64) Address, Value);

+  return Value;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoLibMmioBuffer.c b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoLibMmioBuffer.c
new file mode 100644
index 0000000..328d03c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/IoLibMmioBuffer.c
@@ -0,0 +1,418 @@
+/** @file

+  I/O Library MMIO Buffer Functions.

+  The implementations are based on EFI_PEI_SERVICE->CpuIo interface.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+

+#include <PiPei.h>

+

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+

+/**

+  Copy data from MMIO region to system memory by using 8-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 8-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioReadBuffer8 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT8       *Buffer

+  )

+{

+  UINT8   *ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length-- != 0) {

+    *(Buffer++) = MmioRead8 (StartAddress++);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 16-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 16-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioReadBuffer16 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT16      *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length != 0) {

+    *(Buffer++) = MmioRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 32-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 32-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioReadBuffer32 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT32      *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length != 0) {

+    *(Buffer++) = MmioRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 64-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress 

+  to system memory specified by Buffer by using 64-bit access. The total 

+  number of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioReadBuffer64 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT64      *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+ 

+  ReturnBuffer = Buffer;

+  

+  while (Length != 0) {

+    *(Buffer++) = MmioRead64 (StartAddress);

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 8-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 8-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioWriteBuffer8 (

+  IN  UINTN         StartAddress,

+  IN  UINTN         Length,

+  IN  CONST UINT8   *Buffer

+  )

+{

+  VOID* ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+ 

+  ReturnBuffer = (UINT8 *) Buffer;

+  

+  while (Length-- != 0) {

+     MmioWrite8 (StartAddress++, *(Buffer++));

+  }

+

+  return ReturnBuffer;

+ 

+}

+

+/**

+  Copy data from system memory to MMIO region by using 16-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 16-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioWriteBuffer16 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT16 *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = (UINT16 *) Buffer;

+  

+  while (Length != 0) {

+    MmioWrite16 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 32-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 32-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioWriteBuffer32 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT32 *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = (UINT32 *) Buffer;

+  

+  while (Length != 0) {

+    MmioWrite32 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to MMIO region by using 64-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified 

+  by starting address StartAddress by using 64-bit access. The total number 

+  of byte to be copied is specified by Length. Buffer is returned.

+  

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size, in bytes, of Buffer.

+  @param  Buffer          The pointer to a system memory buffer containing the data to write.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioWriteBuffer64 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT64 *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+  

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = (UINT64 *) Buffer;

+  

+  while (Length != 0) {

+    MmioWrite64 (StartAddress, *(Buffer++));

+    

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
new file mode 100644
index 0000000..d124181
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
@@ -0,0 +1,48 @@
+## @file

+# Instance of I/O Library using CPU I/O PPI.

+#

+# I/O Library implementation that uses the CPU I/O PPI for I/O

+#  and MMIO operations.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiIoLibCpuIo

+  MODULE_UNI_FILE                = PeiIoLibCpuIo.uni

+  FILE_GUID                      = b2585b69-fb63-4220-844a-8fbea8bf01af

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = IoLib|PEIM PEI_CORE SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  IoHighLevel.c

+  IoLib.c

+  IoLibMmioBuffer.c

+ 

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PeiServicesTablePointerLib

+  BaseLib

+  DebugLib

+

+[Depex.common.PEIM]

+  gEfiPeiCpuIoPpiInstalledGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.uni b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.uni
new file mode 100644
index 0000000..86459ba
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
new file mode 100644
index 0000000..afc3909
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
@@ -0,0 +1,965 @@
+/** @file

+  Support routines for memory allocation routines 

+  based on PeiService for PEI phase drivers.

+

+  Copyright (c) 2006 - 2014, 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 <PiPei.h>

+

+

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/HobLib.h>

+

+

+/**

+  Allocates one or more 4KB pages of a certain memory type.

+

+  Allocates the number of 4KB pages of a certain memory type 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  MemoryType            The type of memory to allocate.

+  @param  Pages                 The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory; 

+  EFI_MEMORY_TYPE       RequestType;

+  EFI_PEI_HOB_POINTERS  Hob;

+

+  if (Pages == 0) {

+    return NULL;

+  }

+

+  RequestType = MemoryType;

+  if (MemoryType == EfiReservedMemoryType) {

+    //

+    // PEI AllocatePages() doesn't support EfiReservedMemoryType. 

+    // Change RequestType to EfiBootServicesData for memory allocation.

+    //

+    RequestType = EfiBootServicesData;

+  }

+

+  Status = PeiServicesAllocatePages (RequestType, Pages, &Memory);

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+  

+  if (MemoryType == EfiReservedMemoryType) {

+    //

+    // Memory type needs to be updated to EfiReservedMemoryType. Per PI spec Volume 1, 

+    // PEI AllocatePages() will automate the creation of the Memory Allocation HOB types. 

+    // Search Memory Allocation HOB and find the matched memory region,

+    // then change its memory type to EfiReservedMemoryType.

+    //

+    Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);

+    while (Hob.Raw != NULL && Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress != Memory) {

+      Hob.Raw = GET_NEXT_HOB (Hob);

+      Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);

+    }

+    ASSERT (Hob.Raw != NULL);

+    Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiReservedMemoryType;

+  }

+

+  return (VOID *) (UINTN) Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocatePages (EfiBootServicesData, 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

+  )

+{

+  return InternalAllocatePages (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocatePages (EfiReservedMemoryType, 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                The 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

+  )

+{

+  ASSERT (Pages != 0);

+  //

+  // PEI phase does not support to free pages, so leave it as NOP.

+  //

+}

+

+/**

+  Allocates one or more 4KB pages of a certain memory type at a specified alignment.

+

+  Allocates the number of 4KB pages specified by Pages of a certain memory type 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  MemoryType            The type of memory to allocate.

+  @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 *

+InternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  EFI_PHYSICAL_ADDRESS   Memory;

+  EFI_PHYSICAL_ADDRESS   AlignedMemory;

+  EFI_PEI_HOB_POINTERS   Hob;

+  BOOLEAN                SkipBeforeMemHob;

+  BOOLEAN                SkipAfterMemHob;

+  EFI_PHYSICAL_ADDRESS   HobBaseAddress;

+  UINT64                 HobLength;

+  EFI_MEMORY_TYPE        HobMemoryType;

+  UINTN                  TotalPages;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+

+  if (Pages == 0) {

+    return NULL;

+  }

+  //

+  // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.

+  //

+  ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); 

+

+  //

+  // We would rather waste some memory to save PEI code size.

+  // meaning in addition to the requested size for the aligned mem,

+  // we simply reserve an overhead memory equal to Alignmemt(page-aligned), no matter what.

+  // The overhead mem size could be reduced later with more involved malloc mechanisms

+  // (e.g., somthing that can detect the alignment boundary before allocating memory or 

+  //  can request that memory be allocated at a certain address that is aleady aligned).

+  //

+  TotalPages = Pages + (Alignment <= EFI_PAGE_SIZE ? 0 : EFI_SIZE_TO_PAGES(Alignment));

+  Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) InternalAllocatePages (MemoryType, TotalPages);

+  if (Memory == 0) {

+    DEBUG((DEBUG_INFO, "Out of memory resource! \n"));

+    return NULL;

+  }

+  DEBUG ((DEBUG_INFO, "Allocated Memory unaligned: Address = 0x%LX, Pages = 0x%X, Type = %d \n", Memory, TotalPages, (UINTN) MemoryType));

+

+  //

+  // Alignment calculation

+  //

+  AlignedMemory = Memory;

+  if (Alignment > EFI_PAGE_SIZE) {

+    AlignedMemory = ALIGN_VALUE (Memory, Alignment);

+  }

+  DEBUG ((DEBUG_INFO, "After aligning to 0x%X bytes: Address = 0x%LX, Pages = 0x%X \n", Alignment, AlignedMemory, Pages));

+

+  //

+  // In general three HOBs cover the total allocated space.

+  // The aligned portion is covered by the aligned mem HOB and

+  // the unaligned(to be freed) portions before and after the aligned portion are covered by newly created HOBs.

+  //

+  // Before mem HOB covers the region between "Memory" and "AlignedMemory"

+  // Aligned mem HOB covers the region between "AlignedMemory" and "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)"

+  // After mem HOB covers the region between "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" and "Memory + EFI_PAGES_TO_SIZE(TotalPages)"

+  //

+  // The before or after mem HOBs need to be skipped under special cases where the aligned portion

+  // touches either the top or bottom of the original allocated space.

+  //

+  SkipBeforeMemHob = FALSE;

+  SkipAfterMemHob  = FALSE;

+  if (Memory == AlignedMemory) {

+    SkipBeforeMemHob = TRUE;

+  }

+  if ((Memory + EFI_PAGES_TO_SIZE(TotalPages)) == (AlignedMemory + EFI_PAGES_TO_SIZE(Pages))) {

+    //

+    // This condition is never met in the current implementation.

+    // There is always some after-mem since the overhead mem(used in TotalPages)

+    // is no less than Alignment.

+    //

+    SkipAfterMemHob = TRUE;

+  }

+

+  //  

+  // Search for the mem HOB referring to the original(unaligned) allocation 

+  // and update the size and type if needed.

+  //

+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);

+  while (Hob.Raw != NULL) {

+    if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == Memory) {

+      break;

+    }

+    Hob.Raw = GET_NEXT_HOB (Hob);

+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);

+  }

+  ASSERT (Hob.Raw != NULL);

+  if (SkipBeforeMemHob) {

+    //

+    // Use this HOB as aligned mem HOB as there is no portion before it.

+    //

+    HobLength = EFI_PAGES_TO_SIZE(Pages);

+    Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength;

+  } else {

+    //

+    // Use this HOB as before mem HOB and create a new HOB for the aligned portion 

+    //

+    HobLength = (AlignedMemory - Memory); 

+    Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength;

+    Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiConventionalMemory;

+  }

+

+  HobBaseAddress = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;

+  HobMemoryType = Hob.MemoryAllocation->AllocDescriptor.MemoryType;

+

+  //

+  // Build the aligned mem HOB if needed

+  //

+  if (!SkipBeforeMemHob) {

+    DEBUG((DEBUG_INFO, "Updated before-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",

+      HobBaseAddress, HobLength, (UINTN) HobMemoryType));

+

+    HobBaseAddress = AlignedMemory;

+    HobLength = EFI_PAGES_TO_SIZE(Pages);

+    HobMemoryType = MemoryType;

+

+    BuildMemoryAllocationHob (

+      HobBaseAddress,

+      HobLength,

+      HobMemoryType

+      );

+

+    DEBUG((DEBUG_INFO, "Created aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",

+      HobBaseAddress, HobLength, (UINTN) HobMemoryType));

+  } else {

+    if (HobBaseAddress != 0) {

+      DEBUG((DEBUG_INFO, "Updated aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",

+        HobBaseAddress, HobLength, (UINTN) HobMemoryType));

+    }

+  }

+

+

+  //

+  // Build the after mem HOB if needed

+  //

+  if (!SkipAfterMemHob) {

+    HobBaseAddress = AlignedMemory + EFI_PAGES_TO_SIZE(Pages);

+    HobLength = (Memory + EFI_PAGES_TO_SIZE(TotalPages)) - (AlignedMemory + EFI_PAGES_TO_SIZE(Pages));

+    HobMemoryType = EfiConventionalMemory;

+

+    BuildMemoryAllocationHob (

+      HobBaseAddress,

+      HobLength,

+      HobMemoryType

+      );

+

+    DEBUG((DEBUG_INFO, "Created after-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",

+      HobBaseAddress, HobLength, (UINTN) HobMemoryType));

+  }

+

+  return (VOID *) (UINTN) AlignedMemory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateAlignedPages (EfiBootServicesData, Pages, 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

+  )

+{

+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, 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

+  )

+{

+  return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, 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                The 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

+  )

+{

+  ASSERT (Pages != 0);

+  //

+  // PEI phase does not support to free pages, so leave it as NOP.

+  //

+}

+

+/**

+  Allocates a buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type 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  MemoryType            The type of memory to allocate.

+  @param  AllocationSize        The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            AllocationSize

+  )

+{

+  //

+  // If we need lots of small runtime/reserved memory type from PEI in the future, 

+  // we can consider providing a more complex algorithm that allocates runtime pages and 

+  // provide pool allocations from those pages. 

+  //

+  return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));

+}

+

+/**

+  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

+  )

+{

+  EFI_STATUS        Status;

+  VOID              *Buffer;

+  

+  Status = PeiServicesAllocatePool (AllocationSize, &Buffer);

+  if (EFI_ERROR (Status)) {

+    Buffer = NULL;

+  }

+  return Buffer;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocatePool (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type, 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  PoolType              The type of memory to allocate.

+  @param  AllocationSize        The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize

+  ) 

+{

+  VOID  *Memory;

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  VOID  *Memory;

+

+  Memory = AllocatePool (AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateZeroPool (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Copies a buffer to an allocated buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type, 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  PoolType              The type of pool to allocate.

+  @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 *

+InternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  ) 

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+} 

+

+/**

+  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

+  )

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = AllocatePool (AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, 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

+  )

+{

+  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);

+}

+

+/**

+  Reallocates a buffer of a specified memory type.

+

+  Allocates and zeros the number bytes specified by NewSize from memory of the type

+  specified by PoolType.  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  PoolType       The type of pool to allocate.

+  @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 *

+InternalReallocatePool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            OldSize,

+  IN UINTN            NewSize,

+  IN VOID             *OldBuffer  OPTIONAL

+  )

+{

+  VOID  *NewBuffer;

+

+  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);

+  if (NewBuffer != NULL && OldBuffer != NULL) {

+    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));

+    FreePool (OldBuffer);

+  }

+  return NewBuffer;

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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                The pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreePool (

+  IN VOID   *Buffer

+  )

+{

+  //

+  // PEI phase does not support to free pool, so leave it as NOP.

+  //

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
new file mode 100644
index 0000000..db15813
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -0,0 +1,45 @@
+## @file

+# Instance of Memory Allocation Library using PEI Services.

+#

+# Memory Allocation Library that uses PEI Services to allocate memory.

+#  Free operations are ignored.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiMemoryAllocationLib

+  MODULE_UNI_FILE                = PeiMemoryAllocationLib.uni

+  FILE_GUID                      = b694e0dc-cd4e-4b30-885b-9c164ed3e74a

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = MemoryAllocationLib|PEIM PEI_CORE SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  MemoryAllocationLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+  BaseMemoryLib

+  PeiServicesLib

+  HobLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.uni
new file mode 100644
index 0000000..db198ee
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/CompareMemWrapper.c
new file mode 100644
index 0000000..f525c17
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/CopyMemWrapper.c
new file mode 100644
index 0000000..9b76f0f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLib.c
new file mode 100644
index 0000000..4f1f017
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLib.c
@@ -0,0 +1,71 @@
+/** @file

+  Base Memory Library functions implementation bases on PeiServcie.

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copies a source buffer to a destination buffer, and returns the destination buffer.

+

+  This function wraps the gPS->CopyMem ().

+  

+  @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

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  (*GetPeiServicesTablePointer ())->CopyMem (

+                                      Destination,

+                                      (VOID*)Source,

+                                      Length

+                                      );

+  return Destination;

+}

+

+/**

+  Fills a target buffer with a byte value, and returns the target buffer.

+

+  This function wraps the gPS->SetMem ().

+  

+  @param  Buffer    Memory to set.

+  @param  Size      The number of bytes to set.

+  @param  Value     Value of the set operation.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  (*GetPeiServicesTablePointer ())->SetMem (

+                                      Buffer,

+                                      Size,

+                                      Value

+                                      );

+  return Buffer;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibGeneric.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibGeneric.c
new file mode 100644
index 0000000..53f1caf
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibGeneric.c
@@ -0,0 +1,260 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer

+  @param  SourceBuffer      The second memory buffer

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibGuid.c
new file mode 100644
index 0000000..c04af6e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibInternals.h
new file mode 100644
index 0000000..8a1e1df
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/MemLibInternals.h
@@ -0,0 +1,232 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  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 __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <PiPei.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+

+/**

+  Copies a source buffer to a destination buffer, and returns the destination buffer.

+

+  This function wraps the (*PeiServices)->CopyMem ().

+  

+  @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

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  );

+

+/**

+  Fills a target buffer with a byte value, and returns the target buffer.

+

+  This function wraps the (*PeiServices)->SetMem ().

+  

+  @param  Buffer    The memory to set.

+  @param  Size      The number of bytes to set.

+  @param  Value     Value of the set operation.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer

+  @param  SourceBuffer      The second memory buffer

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence, or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.inf
new file mode 100644
index 0000000..58af9d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.inf
@@ -0,0 +1,59 @@
+## @file

+# Instance of Base Memory Library using PEI Services.

+#

+# Base Memory Library implementation that uses PEI Services

+#  where possible for size reduction.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiMemoryLib

+  MODULE_UNI_FILE                = PeiMemoryLib.uni

+  FILE_GUID                      = 3a9759d2-53bc-4eb2-abcd-c93099419063

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib|PEIM

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGeneric.c

+  MemLibGuid.c

+  MemLib.c

+  MemLibInternals.h

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  PeiServicesTablePointerLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.uni
new file mode 100644
index 0000000..8cbc005
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/PeiMemoryLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem16Wrapper.c
new file mode 100644
index 0000000..69a2ce9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem32Wrapper.c
new file mode 100644
index 0000000..31f1d55
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem64Wrapper.c
new file mode 100644
index 0000000..3819456
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem8Wrapper.c
new file mode 100644
index 0000000..efbbe20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem16Wrapper.c
new file mode 100644
index 0000000..b15a4ea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem32Wrapper.c
new file mode 100644
index 0000000..ea6a5a9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem64Wrapper.c
new file mode 100644
index 0000000..7349565
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMemWrapper.c
new file mode 100644
index 0000000..8a33927
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ZeroMemWrapper.c
new file mode 100644
index 0000000..5adddbb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiMemoryLib/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.c
new file mode 100644
index 0000000..8209e1d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.c
@@ -0,0 +1,99 @@
+/** @file

+  PAL Call Services Function.

+

+  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. 

+    

+**/

+

+

+#include <PiPei.h>

+

+#include <Ppi/SecPlatformInformation.h>

+

+#include <Library/PalLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  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. 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 4 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.

+  This function is only available on IPF.

+

+  @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

+PalCall (

+  IN UINT64                  Index,

+  IN UINT64                  Arg2,

+  IN UINT64                  Arg3,

+  IN UINT64                  Arg4

+  )

+{

+  UINT64                              PalCallAddress;

+  PAL_CALL_RETURN                     ReturnVal;

+  CONST EFI_PEI_SERVICES              **PeiServices;

+  EFI_STATUS                          Status;

+  EFI_SEC_PLATFORM_INFORMATION_PPI    *SecPlatformPpi;

+  EFI_SEC_PLATFORM_INFORMATION_RECORD SecPlatformInfoRecord;

+  UINT64                              RecordSize;

+

+  //

+  // Get PEI Service Table Pointer

+  //

+  PeiServices = GetPeiServicesTablePointer ();

+

+  //

+  // Locate SEC Platform Information PPI

+  //

+  Status = PeiServicesLocatePpi (

+             &gEfiSecPlatformInformationPpiGuid,

+             0,

+             NULL,

+             (VOID **)&SecPlatformPpi

+             );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Retrieve PAL call address from platform information reported by the PPI

+  //

+  RecordSize = sizeof (SecPlatformInfoRecord);

+  SecPlatformPpi->PlatformInformation (

+                    PeiServices,

+                    &RecordSize,

+                    &SecPlatformInfoRecord

+                    );

+  PalCallAddress = SecPlatformInfoRecord.ItaniumHealthFlags.PalCallAddress;

+

+  ReturnVal = AsmPalCall (PalCallAddress, Index, Arg2, Arg3, Arg4);

+

+  return ReturnVal;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.inf
new file mode 100644
index 0000000..6b49f6e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.inf
@@ -0,0 +1,51 @@
+## @file

+# Instance of PAL Library using a PPI for PAL entrypoint.

+#

+# Instance of PAL Library that uses a PPI to retrieve the PAL

+# Entry Point and layers on top of AsmPalCall() in the Base Library

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiPalLib

+  MODULE_UNI_FILE                = PeiPalLib.uni

+  FILE_GUID                      = B53DC524-6B98-4584-940B-8F1363DEF09E

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PalLib|PEIM SEC PEI_CORE

+

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  PeiPalLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  PeiServicesLib

+  PeiServicesTablePointerLib

+

+

+[Ppis]

+  gEfiSecPlatformInformationPpiGuid             ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.uni
new file mode 100644
index 0000000..5997b31
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPalLib/PeiPalLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
new file mode 100644
index 0000000..536e1d0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
@@ -0,0 +1,1194 @@
+/** @file

+Implementation of PcdLib class library for PEI phase.

+

+Copyright (c) 2006 - 2014, 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 <PiPei.h>

+

+#include <Ppi/Pcd.h>

+#include <Ppi/PiPcd.h>

+#include <Ppi/PcdInfo.h>

+#include <Ppi/PiPcdInfo.h>

+

+#include <Library/PeiServicesLib.h>

+#include <Library/PcdLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+

+/**

+  Retrieve the PCD_PPI pointer.

+

+  This function is to locate PCD_PPI PPI via PeiService. 

+  If fail to locate PCD_PPI, then ASSERT_EFI_ERROR().

+  

+  @retval PCD_PPI * The pointer to the PCD_PPI.

+

+**/

+PCD_PPI  *

+GetPcdPpiPointer (

+  VOID

+  ) 

+{

+  EFI_STATUS        Status;

+  PCD_PPI           *PcdPpi;

+  

+  Status = PeiServicesLocatePpi (&gPcdPpiGuid, 0, NULL, (VOID **)&PcdPpi);

+  ASSERT_EFI_ERROR (Status);

+

+  return PcdPpi;

+}

+

+/**

+  Retrieve the pointer of EFI_PEI_PCD_PPI defined in PI 1.2 Vol 3.

+

+  This function is to locate EFI_PEI_PCD_PPI PPI via PeiService. 

+  If fail to locate EFI_PEI_PCD_PPI, then ASSERT_EFI_ERROR().

+  

+  @retval EFI_PEI_PCD_PPI * The pointer to the EFI_PEI_PCD_PPI.

+

+**/

+EFI_PEI_PCD_PPI *

+GetPiPcdPpiPointer (

+  VOID

+  )

+{

+  EFI_STATUS        Status;

+  EFI_PEI_PCD_PPI   *PiPcdPpi;

+  

+  Status = PeiServicesLocatePpi (&gEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&PiPcdPpi);

+  ASSERT_EFI_ERROR (Status);

+  

+  return PiPcdPpi;

+}  

+

+/**

+  Retrieve the GET_PCD_INFO_PPI pointer.

+

+  This function is to locate GET_PCD_INFO_PPI PPI via PeiService. 

+  If fail to locate GET_PCD_INFO_PPI, then ASSERT_EFI_ERROR().

+

+  @retval GET_PCD_INFO_PPI * The pointer to the GET_PCD_INFO_PPI.

+

+**/

+GET_PCD_INFO_PPI *

+GetPcdInfoPpiPointer (

+  VOID

+  ) 

+{

+  EFI_STATUS            Status;

+  GET_PCD_INFO_PPI      *PcdInfoPpi;

+  

+  Status = PeiServicesLocatePpi (&gGetPcdInfoPpiGuid, 0, NULL, (VOID **)&PcdInfoPpi);

+  ASSERT_EFI_ERROR (Status);

+

+  return PcdInfoPpi;

+}

+

+/**

+  Retrieve the pointer of EFI_GET_PCD_INFO_PPI defined in PI 1.2.1 Vol 3.

+

+  This function is to locate EFI_GET_PCD_INFO_PPI PPI via PeiService. 

+  If fail to locate EFI_GET_PCD_INFO_PPI, then ASSERT_EFI_ERROR().

+

+  @retval EFI_GET_PCD_INFO_PPI * The pointer to the EFI_GET_PCD_INFO_PPI.

+

+**/

+EFI_GET_PCD_INFO_PPI *

+GetPiPcdInfoPpiPointer (

+  VOID

+  )

+{

+  EFI_STATUS            Status;

+  EFI_GET_PCD_INFO_PPI  *PiPcdInfoPpi;

+  

+  Status = PeiServicesLocatePpi (&gEfiGetPcdInfoPpiGuid, 0, NULL, (VOID **)&PiPcdInfoPpi);

+  ASSERT_EFI_ERROR (Status);

+  

+  return PiPcdInfoPpi;

+}  

+

+/**

+  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.

+  If SkuId >= PCD_MAX_SKU_ID, then ASSERT(). 

+

+  @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 just be set.

+

+**/

+UINTN

+EFIAPI

+LibPcdSetSku (

+  IN UINTN   SkuId

+  )

+{

+

+  ASSERT (SkuId < PCD_MAX_SKU_ID);

+

+  GetPiPcdPpiPointer()->SetSku (SkuId);

+  

+  return 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

+  )

+{

+  return (GetPcdPpiPointer ())->Get8 (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

+  )

+{

+  return (GetPcdPpiPointer ())->Get16 (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

+  )

+{

+  return (GetPcdPpiPointer ())->Get32 (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

+  )

+{

+  return (GetPcdPpiPointer ())->Get64 (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

+  )

+{

+  return (GetPcdPpiPointer ())->GetPtr (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

+  )

+{

+  return (GetPcdPpiPointer ())->GetBool (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

+  )

+{

+  return (GetPcdPpiPointer ())->GetSize (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         The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return (GetPiPcdPpiPointer ())->Get8 (Guid, 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         The 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

+  )

+{

+

+  ASSERT (Guid != NULL);

+

+  return (GetPiPcdPpiPointer ())->Get16 (Guid, TokenNumber);

+}

+

+

+

+/**

+  Returns the 32-bit value for the token specified by TokenNumber and Guid.

+  If Guid is NULL, then ASSERT(). 

+

+  @param[in]  Guid         The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return (GetPiPcdPpiPointer ())->Get32 (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+  return (GetPiPcdPpiPointer ())->Get64 (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+

+  return (GetPiPcdPpiPointer ())->GetPtr (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+  return (GetPiPcdPpiPointer ())->GetBool (Guid, 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          The 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

+  )

+{

+  ASSERT (Guid != NULL);

+  return (GetPiPcdPpiPointer ())->GetSize (Guid, TokenNumber);

+}

+

+

+

+/**

+  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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = (GetPcdPpiPointer ())->Set8 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return 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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = (GetPcdPpiPointer ())->Set16 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+  

+  return 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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = (GetPcdPpiPointer ())->Set32 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = (GetPcdPpiPointer ())->Set64 (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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,

+  or ASSERT() if the set operation was not corretly 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 been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetPtr (

+  IN        UINTN             TokenNumber,

+  IN OUT    UINTN             *SizeOfBuffer,

+  IN CONST  VOID              *Buffer

+  )

+{

+  EFI_STATUS Status;

+  UINTN      InputSizeOfBuffer;

+

+  ASSERT (SizeOfBuffer != NULL);

+

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+

+  InputSizeOfBuffer = *SizeOfBuffer;

+  Status = (GetPcdPpiPointer ())->SetPtr (TokenNumber, SizeOfBuffer, (VOID *) Buffer);

+  if (EFI_ERROR (Status) && (*SizeOfBuffer < InputSizeOfBuffer)) {

+    return NULL;

+  }

+  ASSERT_EFI_ERROR (Status);

+

+  return (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.

+

+  If the set operation was not correctly performed, then ASSERT().

+

+  @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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = (GetPcdPpiPointer ())->SetBool (TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT8

+EFIAPI

+LibPcdSetEx8 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT8             Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = (GetPiPcdPpiPointer ())->Set8 (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT16

+EFIAPI

+LibPcdSetEx16 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT16            Value

+  )

+{

+  EFI_STATUS Status;

+  ASSERT (Guid != NULL);

+  Status = (GetPiPcdPpiPointer ())->Set16 (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT32

+EFIAPI

+LibPcdSetEx32 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT32            Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+

+  Status = (GetPiPcdPpiPointer ())->Set32 (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+UINT64

+EFIAPI

+LibPcdSetEx64 (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN UINT64            Value

+  )

+{

+  EFI_STATUS Status;

+  ASSERT (Guid != NULL);

+

+  Status = (GetPiPcdPpiPointer ())->Set64 (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return 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, or ASSERT() if the set operation was not corretly 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              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, out] SizeOfBuffer  The size, in bytes, of Buffer.

+  @param[in]  Buffer            A pointer to the buffer to set.

+

+  @return Return the pinter to the buffer been set.

+

+**/

+VOID *

+EFIAPI

+LibPcdSetExPtr (

+  IN      CONST GUID        *Guid,

+  IN      UINTN             TokenNumber,

+  IN OUT  UINTN             *SizeOfBuffer,

+  IN      VOID              *Buffer

+  )

+{

+  EFI_STATUS      Status;

+  UINTN           InputSizeOfBuffer;

+

+

+  ASSERT (SizeOfBuffer != NULL);

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+  ASSERT (Guid != NULL);

+

+  InputSizeOfBuffer = *SizeOfBuffer;

+  Status = (GetPiPcdPpiPointer ())->SetPtr (Guid, TokenNumber, SizeOfBuffer, Buffer);

+  if (EFI_ERROR (Status) && (*SizeOfBuffer < InputSizeOfBuffer)) {

+    return NULL;

+  }

+  ASSERT_EFI_ERROR (Status);

+

+  return 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().

+  If the set operation was not correctly performed, 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 Return the value that was set.

+

+**/

+BOOLEAN

+EFIAPI

+LibPcdSetExBool (

+  IN CONST GUID        *Guid,

+  IN UINTN             TokenNumber,

+  IN BOOLEAN           Value

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (Guid != NULL);

+  Status = (GetPiPcdPpiPointer ())->SetBool (Guid, TokenNumber, Value);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Value;

+}

+

+

+

+/**

+  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                  The 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

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (NotificationFunction != NULL);

+

+  Status = (GetPiPcdPpiPointer ())->CallbackOnSet (Guid, TokenNumber, (EFI_PEI_PCD_PPI_CALLBACK) NotificationFunction);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  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

+  )

+{

+  EFI_STATUS Status;

+

+  ASSERT (NotificationFunction != NULL);

+

+  Status = (GetPiPcdPpiPointer ())->CancelCallback (Guid, TokenNumber, (EFI_PEI_PCD_PPI_CALLBACK) NotificationFunction);

+

+  ASSERT_EFI_ERROR (Status);

+

+  return;

+}

+

+

+

+/**

+  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        The 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

+  )

+{

+  EFI_STATUS    Status;

+

+  Status = (GetPiPcdPpiPointer ())->GetNextToken (Guid, &TokenNumber);

+  ASSERT (!EFI_ERROR (Status) || TokenNumber == 0);

+

+  return 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  The pointer to the a PCD token space GUID

+

+  @return The next valid token namespace.

+

+**/

+GUID *

+EFIAPI

+LibPcdGetNextTokenSpace (

+  IN CONST GUID  *TokenSpaceGuid

+  )

+{

+  (GetPiPcdPpiPointer ())->GetNextTokenSpace (&TokenSpaceGuid);

+

+  return (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[in] 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 been set.

+

+**/

+VOID *

+EFIAPI

+LibPatchPcdSetPtr (

+  IN        VOID        *PatchVariable,

+  IN        UINTN       MaximumDatumSize,

+  IN OUT    UINTN       *SizeOfBuffer,

+  IN CONST  VOID        *Buffer

+  )

+{

+  ASSERT (PatchVariable != NULL);

+  ASSERT (SizeOfBuffer  != NULL);

+  

+  if (*SizeOfBuffer > 0) {

+    ASSERT (Buffer != NULL);

+  }

+

+  if ((*SizeOfBuffer > MaximumDatumSize) ||

+      (*SizeOfBuffer == MAX_ADDRESS)) {

+    *SizeOfBuffer = MaximumDatumSize;

+    return NULL;

+  }

+    

+  CopyMem (PatchVariable, Buffer, *SizeOfBuffer);

+  

+  return (VOID *) Buffer;

+}

+

+/**

+  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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPcdInfoPpiPointer()->GetInfo (TokenNumber, (EFI_PCD_INFO *) PcdInfo);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  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

+  )

+{

+  EFI_STATUS Status;

+

+  Status = GetPiPcdInfoPpiPointer()->GetInfo (Guid, TokenNumber, (EFI_PCD_INFO *) PcdInfo);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Retrieve the currently set SKU Id.

+

+  If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().

+

+  @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

+  )

+{

+  UINTN SkuId;

+

+  SkuId = GetPiPcdInfoPpiPointer()->GetSku ();

+  ASSERT (SkuId < PCD_MAX_SKU_ID);

+

+  return SkuId;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
new file mode 100644
index 0000000..75786c1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
@@ -0,0 +1,66 @@
+## @file

+# Instance of PCD Library using PCD PPI.

+#

+# There are two PCD PPIs as follows:

+#   1) PCD_PPI 

+#      It is EDKII implementation which support Dynamic/DynamicEx Pcds.

+#   2) EFI_PEI_PCD_PPI

+#      It is defined by PI specification 1.2, Vol 3 which only support dynamicEx 

+#      type Pcd.

+# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI.

+# This library instance uses the PCD_PPI to handle dynamic PCD request and use

+# EFI_PEI_PCD_PPI to handle dynamicEx type PCD.

+#

+# This library instance assume the PCD_PPI and EFI_PEI_PCD_PPI are both installed early.

+#

+# PCD Library that uses the PCD PPI to access Dynamic and DynamicEx PCD entries

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiPcdLib

+  MODULE_UNI_FILE                = PeiPcdLib.uni

+  FILE_GUID                      = 9dbf6f25-0da2-4a1d-8e12-e78de6ab4d0e

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PcdLib|PEIM PEI_CORE SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiPcdLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  PeiServicesLib

+  DebugLib

+

+

+[Ppis]

+  gPcdPpiGuid                                   ## SOMETIMES_CONSUMES

+  gEfiPeiPcdPpiGuid                             ## CONSUMES

+  gGetPcdInfoPpiGuid                            ## SOMETIMES_CONSUMES

+  gEfiGetPcdInfoPpiGuid                         ## SOMETIMES_CONSUMES

+

+[Depex.common.PEIM]

+  gEfiPeiPcdPpiGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.uni
new file mode 100644
index 0000000..3512c36
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPcdLib/PeiPcdLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c
new file mode 100644
index 0000000..689a229
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PciLib.c
@@ -0,0 +1,1422 @@
+/** @file

+  PCI Library using PCI CFG2 PPI.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiPei.h>

+

+#include <Ppi/PciCfg2.h>

+

+#include <Library/PciLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeiServicesLib.h>

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \

+  ASSERT (((A) & (~0xfffffff | (M))) == 0)

+

+/**

+  Translate PCI Lib address into format of PCI CFG2 PPI.

+

+  @param  A  The address that encodes the PCI Bus, Device, Function and

+             Register.

+

+**/

+#define PCI_TO_PCICFG2_ADDRESS(A) \

+  ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+PeiPciLibPciCfg2ReadWorker (

+  IN    UINTN                       Address,

+  IN    EFI_PEI_PCI_CFG_PPI_WIDTH   Width

+  )

+{

+  EFI_STATUS                   Status;

+  UINT32                       Data;

+  CONST EFI_PEI_PCI_CFG2_PPI   *PciCfg2Ppi;

+  UINT64                       PciCfg2Address;

+

+  Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (PciCfg2Ppi != NULL);

+

+  PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);

+  PciCfg2Ppi->Read (

+                GetPeiServicesTablePointer (),

+                PciCfg2Ppi,

+                Width,

+                PciCfg2Address,

+                &Data

+                );

+

+  return Data;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+PeiPciLibPciCfg2WriteWorker (

+  IN    UINTN                       Address,

+  IN    EFI_PEI_PCI_CFG_PPI_WIDTH   Width,

+  IN    UINT32                      Data

+  )

+{

+  EFI_STATUS                      Status;

+  CONST EFI_PEI_PCI_CFG2_PPI      *PciCfg2Ppi;

+  UINT64                          PciCfg2Address;

+

+  Status = PeiServicesLocatePpi (&gEfiPciCfg2PpiGuid, 0, NULL, (VOID **) &PciCfg2Ppi);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (PciCfg2Ppi != NULL);

+

+  PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);

+  PciCfg2Ppi->Write (

+                GetPeiServicesTablePointer (),

+                PciCfg2Ppi,

+                Width,

+                PciCfg2Address,

+                &Data

+                );

+

+  return Data;

+}

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration registers 

+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint8);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint8, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8) (PciRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (Address, (UINT8) (PciRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8) ((PciRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint16);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint16, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16) (PciRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (Address, (UINT16) (PciRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16) ((PciRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return PeiPciLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint32);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return PeiPciLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint32, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 (Buffer, PciRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 (Buffer, PciRead32 (StartAddress));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 (Buffer, PciRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciWrite32 (StartAddress, ReadUnaligned32 (Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PeiPciLibPciCfg2.inf b/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PeiPciLibPciCfg2.inf
new file mode 100644
index 0000000..2a61685
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PeiPciLibPciCfg2.inf
@@ -0,0 +1,56 @@
+## @file

+# PCI Library that layers on top of the PCI CFG2 PPI.

+#

+# This library produces the APIs from the PCI Library and implements

+#  these APIs by calling into the EFI_PEI_PCI CFG2 PPI. One or more EFI_PEI_PCI CFG2

+#  PPIs are typically produced by a chipset specific PEIM. This library only uses

+#  the first PPI found, so this library instance should only be used platforms

+#  with a single PCI segment.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiPciLibPciCfg2

+  MODULE_UNI_FILE                = PeiPciLibPciCfg2.uni

+  FILE_GUID                      = FA3AD693-D58A-4619-960B-8EE85C914870

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciLib|PEIM SEC PEI_CORE

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PciLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  PeiServicesTablePointerLib

+  BaseLib

+  DebugLib

+  PeiServicesLib

+

+[Ppis]

+  gEfiPciCfg2PpiGuid                            ## CONSUMES

+

+[Depex.common.PEIM]

+  gEfiPciCfg2PpiGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PeiPciLibPciCfg2.uni b/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PeiPciLibPciCfg2.uni
new file mode 100644
index 0000000..ef65ff3
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPciLibPciCfg2/PeiPciLibPciCfg2.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c
new file mode 100644
index 0000000..93f63df
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PciSegmentLib.c
@@ -0,0 +1,1415 @@
+/** @file

+  PCI Segment Library implementation using PCI CFG2 PPI.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiPei.h>

+

+#include <Ppi/PciCfg2.h>

+

+#include <Library/PciSegmentLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeiServicesLib.h>

+

+/**

+  Assert the validity of a PCI Segment address.

+  A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \

+  ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)

+

+/**

+  Translate PCI Lib address into format of PCI CFG2 PPI.

+

+  @param  A  The address that encodes the PCI Bus, Device, Function and

+             Register.

+

+**/

+#define PCI_TO_PCICFG2_ADDRESS(A) \

+  ((((UINT32)(A) << 4) & 0xff000000) | (((UINT32)(A) >> 4) & 0x00000700) | (((UINT32)(A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))

+

+/**

+  Gets PCI CFG2 PPI.

+

+  This internal function retrieves PCI CFG2 PPI from PPI database.

+

+  @param  Address       The address that encodes the PCI Segment, Bus, Device, 

+                        Function and Register.

+

+  @return The pointer to PCI CFG2 PPI.

+

+**/

+EFI_PEI_PCI_CFG2_PPI *

+InternalGetPciCfg2Ppi (

+  IN  UINT64                Address

+  )

+{

+  EFI_STATUS                 Status;

+  UINTN                      Instance;

+  EFI_PEI_PCI_CFG2_PPI       *PciCfg2Ppi;

+  UINT64                     SegmentNumber;

+

+  Instance      = 0;

+  PciCfg2Ppi    = NULL;

+  SegmentNumber = BitFieldRead64 (Address, 32, 63);

+

+  //

+  // Loop through all instances of the PPI and match segment number

+  //

+  do {

+    Status = PeiServicesLocatePpi(

+               &gEfiPciCfg2PpiGuid,

+               Instance,

+               NULL,

+               (VOID**) &PciCfg2Ppi

+               );

+    ASSERT_EFI_ERROR (Status);

+    Instance++;

+  } while (PciCfg2Ppi->Segment != SegmentNumber);

+

+  return PciCfg2Ppi;

+}

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EFI_PEI_PCI_CFG2_PPI.Read() service.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+PeiPciSegmentLibPciCfg2ReadWorker (

+  IN  UINT64                      Address,

+  IN  EFI_PEI_PCI_CFG_PPI_WIDTH   Width

+  )

+{

+  UINT32                       Data;

+  CONST EFI_PEI_PCI_CFG2_PPI   *PciCfg2Ppi;

+  UINT64                       PciCfg2Address;

+

+  PciCfg2Ppi = InternalGetPciCfg2Ppi (Address);

+  PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);

+  PciCfg2Ppi->Read (

+                GetPeiServicesTablePointer (),

+                PciCfg2Ppi,

+                Width,

+                PciCfg2Address,

+                &Data

+                );

+

+  return Data;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EFI_PEI_PCI_CFG2_PPI.Write() service.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+PeiPciSegmentLibPciCfg2WriteWorker (

+  IN  UINT64                      Address,

+  IN  EFI_PEI_PCI_CFG_PPI_WIDTH   Width,

+  IN  UINT32                      Data

+  )

+{

+  CONST EFI_PEI_PCI_CFG2_PPI   *PciCfg2Ppi;

+  UINT64                       PciCfg2Address;

+

+  PciCfg2Ppi = InternalGetPciCfg2Ppi (Address);

+  PciCfg2Address = PCI_TO_PCICFG2_ADDRESS (Address);

+  PciCfg2Ppi->Write (

+                GetPeiServicesTablePointer (),

+                PciCfg2Ppi,

+                Width,

+                PciCfg2Address,

+                &Data

+                );

+

+  return Data;

+}

+

+/**

+  Register a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciSegmentRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, 

+                    and Register.

+

+  @return The 8-bit PCI configuration register specified by Address.

+

+**/

+UINT8

+EFIAPI

+PciSegmentRead8 (

+  IN UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+

+  return (UINT8) PeiPciSegmentLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint8);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentWrite8 (

+  IN UINT64                    Address,

+  IN UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+

+  return (UINT8) PeiPciSegmentLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint8, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentOr8 (

+  IN UINT64                    Address,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAnd8 (

+  IN UINT64                    Address,

+  IN UINT8                     AndData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,

+  followed a  bitwise OR with another 8-bit value.

+  

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the 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 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData    The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAndThenOr8 (

+  IN UINT64                    Address,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldRead8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldWrite8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     Value

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldOr8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAnd8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAndThenOr8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 16-bit PCI configuration register specified by Address.

+

+**/

+UINT16

+EFIAPI

+PciSegmentRead16 (

+  IN UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);

+

+  return (UINT16) PeiPciSegmentLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint16);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+PciSegmentWrite16 (

+  IN UINT64                    Address,

+  IN UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);

+

+  return (UINT16) PeiPciSegmentLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint16, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentOr16 (

+  IN UINT64                    Address,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAnd16 (

+  IN UINT64                    Address,

+  IN UINT16                    AndData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,

+  followed a  bitwise OR with another 16-bit value.

+  

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the 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 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAndThenOr16 (

+  IN UINT64                    Address,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldRead16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldWrite16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    Value

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address. 

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldOr16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,

+  and writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in OrData are stripped.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAnd16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAndThenOr16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, 

+                    and Register.

+

+  @return The 32-bit PCI configuration register specified by Address.

+

+**/

+UINT32

+EFIAPI

+PciSegmentRead32 (

+  IN UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);

+

+  return PeiPciSegmentLibPciCfg2ReadWorker (Address, EfiPeiPciCfgWidthUint32);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address     The address that encodes the PCI Segment, Bus, Device, 

+                      Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT32

+EFIAPI

+PciSegmentWrite32 (

+  IN UINT64                    Address,

+  IN UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);

+

+  return PeiPciSegmentLibPciCfg2WriteWorker (Address, EfiPeiPciCfgWidthUint32, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentOr32 (

+  IN UINT64                    Address,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, 

+                    and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAnd32 (

+  IN UINT64                    Address,

+  IN UINT32                    AndData

+  )

+{

+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,

+  followed a  bitwise OR with another 32-bit value.

+  

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the 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 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function,

+                    and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAndThenOr32 (

+  IN UINT64                    Address,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldRead32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldWrite32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    Value

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldOr32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  

+  Reads the 32-bit PCI configuration register specified by Address, performs a bitwise

+  AND between the read result and the value specified by AndData, and writes the result

+  to the 32-bit PCI configuration register specified by Address. The value written to

+  the PCI configuration register is returned.  This function must guarantee that all PCI

+  read and write operations are serialized.  Extra left bits in AndData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAnd32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAndThenOr32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If any reserved bits in StartAddress are set, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, 

+                        Device, Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciSegmentReadBuffer (

+  IN  UINT64                   StartAddress,

+  IN  UINTN                    Size,

+  OUT VOID                     *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If any reserved bits in StartAddress are set, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, 

+                        Device, Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return The parameter of Size.

+

+**/

+UINTN

+EFIAPI

+PciSegmentWriteBuffer (

+  IN UINT64                    StartAddress,

+  IN UINTN                     Size,

+  IN VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PeiPciSegmentLibPciCfg2.inf b/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PeiPciSegmentLibPciCfg2.inf
new file mode 100644
index 0000000..3458bc6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PeiPciSegmentLibPciCfg2.inf
@@ -0,0 +1,53 @@
+## @file

+# PCI Segment Library that layers on top of the PCI CFG2 PPI.

+#

+# This library produces the APIs from the PCI Segment Library and

+#  implements these APIs by calling into the EFI_PEI_PCI CFG2 PPI. One or more

+#  EFI_PEI_PCI CFG2 PPIs are typically produced by a chipset specific PEIM.

+#  This library instance should only be used platforms with multiple PCI segments.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiPciSegmentLibPciCfg2

+  MODULE_UNI_FILE                = PeiPciSegmentLibPciCfg2.uni

+  FILE_GUID                      = 254901AD-7DB7-45f8-93C8-93D579398D9F

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciSegmentLib|PEIM SEC PEI_CORE

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PciSegmentLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PeiServicesTablePointerLib

+  BaseLib

+  DebugLib

+  PeiServicesLib

+

+[Ppis]

+  gEfiPciCfg2PpiGuid                            ##  CONSUMES

+

+[Depex.common.PEIM]

+  gEfiPciCfg2PpiGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PeiPciSegmentLibPciCfg2.uni b/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PeiPciSegmentLibPciCfg2.uni
new file mode 100644
index 0000000..2889724
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiPciSegmentLibPciCfg2/PeiPciSegmentLibPciCfg2.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.c
new file mode 100644
index 0000000..55ae63b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.c
@@ -0,0 +1,58 @@
+/** @file

+  Resource Publication Library that uses PEI Core Services to publish system memory.

+

+  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.             

+

+**/

+

+

+

+#include <PiPei.h>

+

+

+#include <Library/ResourcePublicationLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/DebugLib.h>

+

+

+/**

+  Declares the presence of permanent system memory in the platform.

+

+  Declares that the system memory buffer specified by MemoryBegin and MemoryLength

+  as permanent memory that may be used for general purpose use by software.

+  The amount of memory available to software may be less than MemoryLength

+  if published memory has alignment restrictions. 

+  If MemoryLength is 0, then ASSERT().

+  If MemoryLength is greater than (MAX_ADDRESS - MemoryBegin + 1), then ASSERT(). 

+

+  @param  MemoryBegin               The start address of the memory being declared.

+  @param  MemoryLength              The number of bytes of memory being declared.

+

+  @retval  RETURN_SUCCESS           The memory buffer was published.

+  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to publish the memory buffer

+

+**/

+RETURN_STATUS

+EFIAPI

+PublishSystemMemory (

+  IN PHYSICAL_ADDRESS       MemoryBegin,

+  IN UINT64                 MemoryLength

+  )

+{

+  EFI_STATUS        Status;

+

+  ASSERT (MemoryLength > 0);

+  ASSERT (MemoryLength <= (MAX_ADDRESS - MemoryBegin + 1));

+

+  Status      = PeiServicesInstallPeiMemory (MemoryBegin, MemoryLength);

+     

+  return (RETURN_STATUS) Status;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
new file mode 100644
index 0000000..b09f48b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
@@ -0,0 +1,42 @@
+## @file

+# Instance of Resource Publication Library using PEI Services.

+#

+# Resource Publication Library that uses PEI Services to publish system memory.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiResourcePublicationLib

+  MODULE_UNI_FILE                = PeiResourcePublicationLib.uni

+  FILE_GUID                      = e8d6390d-e190-4957-9ab6-d47d51b01336

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = ResourcePublicationLib|PEIM SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiResourcePublicationLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  PeiServicesLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.uni
new file mode 100644
index 0000000..e07337c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.c
new file mode 100644
index 0000000..3428add
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.c
@@ -0,0 +1,753 @@
+/** @file

+  Implementation for PEI Services Library.

+

+  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.

+

+**/

+

+

+#include <PiPei.h>

+

+#include <Ppi/FirmwareVolumeInfo.h>

+#include <Ppi/FirmwareVolumeInfo2.h>

+#include <Guid/FirmwareFileSystem2.h>

+

+#include <Library/PeiServicesLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/BaseMemoryLib.h>

+

+/**

+  This service enables a given PEIM to register an interface into the PEI Foundation.

+

+  @param  PpiList               A pointer to the list of interfaces that the caller shall install.

+

+  @retval EFI_SUCCESS           The interface was successfully installed.

+  @retval EFI_INVALID_PARAMETER The PpiList pointer is NULL.

+  @retval EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have the

+                                EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field.

+  @retval EFI_OUT_OF_RESOURCES  There is no additional space in the PPI database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesInstallPpi (

+  IN CONST EFI_PEI_PPI_DESCRIPTOR     *PpiList

+  )

+{

+  CONST EFI_PEI_SERVICES  **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->InstallPpi (PeiServices, PpiList);

+}

+

+/**

+  This service enables PEIMs to replace an entry in the PPI database with an alternate entry.

+

+  @param  OldPpi                The pointer to the old PEI PPI Descriptors.

+  @param  NewPpi                The pointer to the new PEI PPI Descriptors.

+

+  @retval EFI_SUCCESS           The interface was successfully installed.

+  @retval EFI_INVALID_PARAMETER The OldPpi or NewPpi is NULL.

+  @retval EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have the

+                                EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field.

+  @retval EFI_OUT_OF_RESOURCES  There is no additional space in the PPI database.

+  @retval EFI_NOT_FOUND         The PPI for which the reinstallation was requested has not been

+                                installed.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesReInstallPpi (

+  IN CONST EFI_PEI_PPI_DESCRIPTOR     *OldPpi,

+  IN CONST EFI_PEI_PPI_DESCRIPTOR     *NewPpi

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->ReInstallPpi (PeiServices, OldPpi, NewPpi);

+}

+

+/**

+  This service enables PEIMs to discover a given instance of an interface.

+

+  @param  Guid                  A pointer to the GUID whose corresponding interface needs to be

+                                found.

+  @param  Instance              The N-th instance of the interface that is required.

+  @param  PpiDescriptor         A pointer to instance of the EFI_PEI_PPI_DESCRIPTOR.

+  @param  Ppi                   A pointer to the instance of the interface.

+

+  @retval EFI_SUCCESS           The interface was successfully returned.

+  @retval EFI_NOT_FOUND         The PPI descriptor is not found in the database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesLocatePpi (

+  IN CONST EFI_GUID                   *Guid,

+  IN UINTN                      Instance,

+  IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,

+  IN OUT VOID                   **Ppi

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->LocatePpi (PeiServices, Guid, Instance, PpiDescriptor, Ppi);

+}

+

+/**

+  This service enables PEIMs to register a given service to be invoked when another service is

+  installed or reinstalled.

+

+  @param  NotifyList            A pointer to the list of notification interfaces 

+                                that the caller shall install.

+

+  @retval EFI_SUCCESS           The interface was successfully installed.

+  @retval EFI_INVALID_PARAMETER The NotifyList pointer is NULL.

+  @retval EFI_INVALID_PARAMETER Any of the PEI notify descriptors in the list do

+                                 not have the EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES

+                                 bit set in the Flags field.

+  @retval EFI_OUT_OF_RESOURCES  There is no additional space in the PPI database.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesNotifyPpi (

+  IN CONST EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->NotifyPpi (PeiServices, NotifyList);

+}

+

+/**

+  This service enables PEIMs to ascertain the present value of the boot mode.

+

+  @param  BootMode              A pointer to contain the value of the boot mode.

+

+  @retval EFI_SUCCESS           The boot mode was returned successfully.

+  @retval EFI_INVALID_PARAMETER BootMode is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesGetBootMode (

+  OUT EFI_BOOT_MODE          *BootMode

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->GetBootMode (PeiServices, BootMode);

+}

+

+/**

+  This service enables PEIMs to update the boot mode variable.

+

+  @param  BootMode              The value of the boot mode to set.

+

+  @retval EFI_SUCCESS           The value was successfully updated

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesSetBootMode (

+  IN EFI_BOOT_MODE              BootMode

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->SetBootMode (PeiServices, BootMode);

+}

+

+/**

+  This service enables a PEIM to ascertain the address of the list of HOBs in memory.

+

+  @param  HobList               A pointer to the list of HOBs that the PEI Foundation 

+                                will initialize.

+  

+  @retval EFI_SUCCESS           The list was successfully returned.

+  @retval EFI_NOT_AVAILABLE_YET The HOB list is not yet published.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesGetHobList (

+  OUT VOID                      **HobList

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->GetHobList (PeiServices, HobList);

+}

+

+/**

+  This service enables PEIMs to create various types of HOBs.

+

+  @param  Type                  The type of HOB to be installed.

+  @param  Length                The length of the HOB to be added.

+  @param  Hob                   The address of a pointer that will contain the 

+                                HOB header.

+

+  @retval EFI_SUCCESS           The HOB was successfully created.

+  @retval EFI_OUT_OF_RESOURCES  There is no additional space for HOB creation.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesCreateHob (

+  IN UINT16                     Type,

+  IN UINT16                     Length,

+  OUT VOID                      **Hob

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->CreateHob (PeiServices, Type, Length, Hob);

+}

+

+/**

+  This service enables PEIMs to discover additional firmware volumes.

+

+  @param  Instance              This instance of the firmware volume to find.  The 

+                                value 0 is the Boot Firmware Volume (BFV).

+  @param  VolumeHandle          Handle of the firmware volume header of the volume

+                                to return.

+

+  @retval EFI_SUCCESS           The volume was found.

+  @retval EFI_NOT_FOUND         The volume was not found.

+  @retval EFI_INVALID_PARAMETER FwVolHeader is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsFindNextVolume (

+  IN UINTN                          Instance,

+  IN OUT EFI_PEI_FV_HANDLE          *VolumeHandle

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FfsFindNextVolume (PeiServices, Instance, VolumeHandle);

+}

+

+/**

+  This service enables PEIMs to discover additional firmware files.

+

+  @param  SearchType            A filter to find files only of this type.

+  @param  VolumeHandle          The pointer to the firmware volume header of the 

+                                volume to search. This parameter must point to a 

+                                valid FFS volume. 

+  @param  FileHandle            Handle of the current file from which to begin searching.

+

+  @retval EFI_SUCCESS           The file was found.

+  @retval EFI_NOT_FOUND         The file was not found.

+  @retval EFI_NOT_FOUND         The header checksum was not zero.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsFindNextFile (

+  IN EFI_FV_FILETYPE            SearchType,

+  IN EFI_PEI_FV_HANDLE          VolumeHandle,

+  IN OUT EFI_PEI_FILE_HANDLE    *FileHandle

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FfsFindNextFile (PeiServices, SearchType, VolumeHandle, FileHandle);

+}

+

+/**

+  This service enables PEIMs to discover sections of a given type within a valid FFS file.

+

+  @param  SectionType           The value of the section type to find.

+  @param  FileHandle            A pointer to the file header that contains the set 

+                                of sections to be searched.

+  @param  SectionData           A pointer to the discovered section, if successful.

+

+  @retval EFI_SUCCESS           The section was found.

+  @retval EFI_NOT_FOUND         The section was not found.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsFindSectionData (

+  IN EFI_SECTION_TYPE           SectionType,

+  IN EFI_PEI_FILE_HANDLE        FileHandle,

+  OUT VOID                      **SectionData

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FfsFindSectionData (PeiServices, SectionType, FileHandle, SectionData);

+}

+

+/**

+  This service enables PEIMs to discover sections of a given instance and type within a valid FFS file.

+

+  @param  SectionType           The value of the section type to find.

+  @param  SectionInstance       Section instance to find.

+  @param  FileHandle            A pointer to the file header that contains the set 

+                                of sections to be searched.

+  @param  SectionData           A pointer to the discovered section, if successful.

+  @param  AuthenticationStatus  A pointer to the authentication status for this section.

+

+  @retval EFI_SUCCESS           The section was found.

+  @retval EFI_NOT_FOUND         The section was not found.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsFindSectionData3 (

+  IN EFI_SECTION_TYPE           SectionType,

+  IN UINTN                      SectionInstance,

+  IN EFI_PEI_FILE_HANDLE        FileHandle,

+  OUT VOID                      **SectionData,

+  OUT UINT32                    *AuthenticationStatus

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->FindSectionData3 (PeiServices, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus);

+}

+

+/**

+  This service enables PEIMs to register the permanent memory configuration

+  that has been initialized with the PEI Foundation.

+

+  @param  MemoryBegin           The value of a region of installed memory.

+  @param  MemoryLength          The corresponding length of a region of installed memory.

+

+  @retval EFI_SUCCESS           The region was successfully installed in a HOB.

+  @retval EFI_INVALID_PARAMETER MemoryBegin and MemoryLength are illegal for this system.

+  @retval EFI_OUT_OF_RESOURCES  There is no additional space for HOB creation.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesInstallPeiMemory (

+  IN EFI_PHYSICAL_ADDRESS       MemoryBegin,

+  IN UINT64                     MemoryLength

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->InstallPeiMemory (PeiServices, MemoryBegin, MemoryLength);

+}

+

+/**

+  This service enables PEIMs to allocate memory after the permanent memory has been

+   installed by a PEIM.

+

+  @param  MemoryType            Type of memory to allocate.

+  @param  Pages                 The number of pages to allocate.

+  @param  Memory                Pointer of memory allocated.

+

+  @retval EFI_SUCCESS           The memory range was successfully allocated.

+  @retval EFI_INVALID_PARAMETER Type is not equal to AllocateAnyPages.

+  @retval EFI_NOT_AVAILABLE_YET Called with permanent memory not available.

+  @retval EFI_OUT_OF_RESOURCES  The pages could not be allocated.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesAllocatePages (

+  IN EFI_MEMORY_TYPE            MemoryType,

+  IN UINTN                      Pages,

+  OUT EFI_PHYSICAL_ADDRESS      *Memory

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->AllocatePages (PeiServices, MemoryType, Pages, Memory);

+}

+

+/**

+  This service allocates memory from the Hand-Off Block (HOB) heap.

+

+  @param  Size                  The number of bytes to allocate from the pool.

+  @param  Buffer                If the call succeeds, a pointer to a pointer to 

+                                the allocate buffer; otherwise, undefined.

+

+  @retval EFI_SUCCESS           The allocation was successful

+  @retval EFI_OUT_OF_RESOURCES  There is not enough heap to allocate the requested size.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesAllocatePool (

+  IN UINTN                      Size,

+  OUT VOID                      **Buffer

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->AllocatePool (PeiServices, Size, Buffer);

+}

+

+/**

+  Resets the entire platform.

+

+  @retval EFI_SUCCESS           The function completed successfully.

+  @retval EFI_NOT_AVAILABLE_YET The service has not been installed yet.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesResetSystem (

+  VOID

+  )

+{

+  CONST EFI_PEI_SERVICES **PeiServices;

+

+  PeiServices = GetPeiServicesTablePointer ();

+  return (*PeiServices)->ResetSystem (PeiServices);

+}

+

+/**

+  This service is a wrapper for the PEI Service RegisterForShadow(), except the 

+  pointer to the PEI Services Table has been removed.  See the Platform 

+  Initialization Pre-EFI Initialization Core Interface Specification for details. 

+

+  @param FileHandle             PEIM's file handle. Must be the currently

+                                executing PEIM.

+  

+  @retval EFI_SUCCESS           The PEIM was successfully registered for

+                                shadowing.

+

+  @retval EFI_ALREADY_STARTED   The PEIM was previously

+                                registered for shadowing.

+

+  @retval EFI_NOT_FOUND         The FileHandle does not refer to a

+                                valid file handle.

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesRegisterForShadow (

+  IN  EFI_PEI_FILE_HANDLE FileHandle

+  )

+{

+  return (*GetPeiServicesTablePointer())->RegisterForShadow (FileHandle);

+}

+

+/**

+  This service is a wrapper for the PEI Service FfsGetFileInfo(), except the pointer to the PEI Services 

+  Table has been removed.  See the Platform Initialization Pre-EFI Initialization Core Interface 

+  Specification for details. 

+

+  @param FileHandle              The handle of the file.

+

+  @param FileInfo                 Upon exit, points to the file's

+                                  information.

+

+  @retval EFI_SUCCESS             File information returned.

+  

+  @retval EFI_INVALID_PARAMETER   If FileHandle does not

+                                  represent a valid file.

+  

+  @retval EFI_INVALID_PARAMETER   FileInfo is NULL.

+  

+**/

+EFI_STATUS

+EFIAPI 

+PeiServicesFfsGetFileInfo (

+  IN CONST  EFI_PEI_FILE_HANDLE   FileHandle,

+  OUT EFI_FV_FILE_INFO            *FileInfo

+  )

+{

+  return (*GetPeiServicesTablePointer())->FfsGetFileInfo (FileHandle, FileInfo);

+}

+

+/**

+  This service is a wrapper for the PEI Service FfsGetFileInfo2(), except the pointer to the PEI Services

+  Table has been removed. See the Platform Initialization Pre-EFI Initialization Core Interface

+  Specification for details.

+

+  @param FileHandle               The handle of the file.

+  @param FileInfo                 Upon exit, points to the file's

+                                  information.

+

+  @retval EFI_SUCCESS             File information returned.

+  @retval EFI_INVALID_PARAMETER   If FileHandle does not

+                                  represent a valid file.

+  @retval EFI_INVALID_PARAMETER   FileInfo is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsGetFileInfo2 (

+  IN CONST  EFI_PEI_FILE_HANDLE   FileHandle,

+  OUT EFI_FV_FILE_INFO2           *FileInfo

+  )

+{

+  return (*GetPeiServicesTablePointer())->FfsGetFileInfo2 (FileHandle, FileInfo);

+}

+

+/**

+  This service is a wrapper for the PEI Service FfsFindByName(), except the pointer to the PEI Services 

+  Table has been removed.  See the Platform Initialization Pre-EFI Initialization Core Interface 

+  Specification for details. 

+

+  @param FileName                 A pointer to the name of the file to

+                                  find within the firmware volume.

+

+  @param VolumeHandle             The firmware volume to search FileHandle

+                                  Upon exit, points to the found file's

+                                  handle or NULL if it could not be found.

+  @param FileHandle               The pointer to found file handle 

+

+  @retval EFI_SUCCESS             File was found.

+

+  @retval EFI_NOT_FOUND           File was not found.

+

+  @retval EFI_INVALID_PARAMETER   VolumeHandle or FileHandle or

+                                  FileName was NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsFindFileByName (

+  IN CONST  EFI_GUID            *FileName,

+  IN CONST  EFI_PEI_FV_HANDLE   VolumeHandle,

+  OUT       EFI_PEI_FILE_HANDLE *FileHandle

+  )

+{

+  return (*GetPeiServicesTablePointer())->FfsFindFileByName (FileName, VolumeHandle, FileHandle);

+}

+

+

+/**

+  This service is a wrapper for the PEI Service FfsGetVolumeInfo(), except the pointer to the PEI Services 

+  Table has been removed.  See the Platform Initialization Pre-EFI Initialization Core Interface 

+  Specification for details. 

+

+  @param VolumeHandle             Handle of the volume.

+

+  @param VolumeInfo               Upon exit, points to the volume's

+                                  information.

+

+  @retval EFI_SUCCESS             File information returned.

+  

+  @retval EFI_INVALID_PARAMETER   If FileHandle does not

+                                  represent a valid file.

+  

+  @retval EFI_INVALID_PARAMETER   If FileInfo is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesFfsGetVolumeInfo (

+  IN  EFI_PEI_FV_HANDLE       VolumeHandle,

+  OUT EFI_FV_INFO             *VolumeInfo

+  )

+{

+  return (*GetPeiServicesTablePointer())->FfsGetVolumeInfo (VolumeHandle, VolumeInfo);

+}

+

+/**

+  Install a EFI_PEI_FIRMWARE_VOLUME_INFO(2)_PPI instance so the PEI Core will be notified about a new firmware volume.

+

+  This function allocates, initializes, and installs a new EFI_PEI_FIRMWARE_VOLUME_INFO(2)_PPI using

+  the parameters passed in to initialize the fields of the EFI_PEI_FIRMWARE_VOLUME_INFO(2)_PPI instance.

+  If the resources can not be allocated for EFI_PEI_FIRMWARE_VOLUME_INFO(2)_PPI, then ASSERT().

+  If the EFI_PEI_FIRMWARE_VOLUME_INFO(2)_PPI can not be installed, then ASSERT().

+

+  @param  InstallFvInfoPpi     Install FvInfo Ppi if it is TRUE. Otherwise, install FvInfo2 Ppi.

+  @param  FvFormat             Unique identifier of the format of the memory-mapped

+                               firmware volume.  This parameter is optional and

+                               may be NULL.  If NULL is specified, the

+                               EFI_FIRMWARE_FILE_SYSTEM2_GUID format is assumed.

+  @param  FvInfo               Points to a buffer which allows the

+                               EFI_PEI_FIRMWARE_VOLUME_PPI to process the volume.

+                               The format of this buffer is specific to the FvFormat.

+                               For memory-mapped firmware volumes, this typically

+                               points to the first byte of the firmware volume.

+  @param  FvInfoSize           The size, in bytes, of FvInfo. For memory-mapped

+                               firmware volumes, this is typically the size of

+                               the firmware volume.

+  @param  ParentFvName         If the new firmware volume originated from a file

+                               in a different firmware volume, then this parameter

+                               specifies the GUID name of the originating firmware

+                               volume. Otherwise, this parameter must be NULL.

+  @param  ParentFileName       If the new firmware volume originated from a file

+                               in a different firmware volume, then this parameter

+                               specifies the GUID file name of the originating

+                               firmware file. Otherwise, this parameter must be NULL.

+  @param  AuthenticationStatus Authentication Status, it will be ignored if InstallFvInfoPpi is TRUE.

+**/

+VOID

+EFIAPI

+InternalPeiServicesInstallFvInfoPpi (

+  IN       BOOLEAN                 InstallFvInfoPpi,

+  IN CONST EFI_GUID                *FvFormat, OPTIONAL

+  IN CONST VOID                    *FvInfo,

+  IN       UINT32                  FvInfoSize,

+  IN CONST EFI_GUID                *ParentFvName, OPTIONAL

+  IN CONST EFI_GUID                *ParentFileName, OPTIONAL

+  IN       UINT32                  AuthenticationStatus

+  )

+{

+  EFI_STATUS                       Status;   

+  EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;

+  EFI_PEI_PPI_DESCRIPTOR           *FvInfoPpiDescriptor;

+  EFI_GUID                         *ParentFvNameValue;

+  EFI_GUID                         *ParentFileNameValue;

+  EFI_GUID                         *PpiGuid;

+

+  ParentFvNameValue   = NULL;

+  ParentFileNameValue = NULL;

+  if (InstallFvInfoPpi) {

+    //

+    // To install FvInfo Ppi.

+    //

+    FvInfoPpi = AllocateZeroPool (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI));

+    ASSERT (FvInfoPpi != NULL);

+    PpiGuid = &gEfiPeiFirmwareVolumeInfoPpiGuid;

+  } else {

+    //

+    // To install FvInfo2 Ppi.

+    //

+    FvInfoPpi = AllocateZeroPool (sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI));

+    ASSERT (FvInfoPpi != NULL);

+    ((EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *) FvInfoPpi)->AuthenticationStatus = AuthenticationStatus;

+    PpiGuid = &gEfiPeiFirmwareVolumeInfo2PpiGuid;

+  }

+

+  if (FvFormat != NULL) {

+    CopyGuid (&FvInfoPpi->FvFormat, FvFormat);

+  } else {

+    CopyGuid (&FvInfoPpi->FvFormat, &gEfiFirmwareFileSystem2Guid);

+  }

+  FvInfoPpi->FvInfo = (VOID *) FvInfo;

+  FvInfoPpi->FvInfoSize = FvInfoSize;

+  if (ParentFvName != NULL) {

+    ParentFvNameValue = AllocateCopyPool (sizeof (EFI_GUID), ParentFvName);

+    ASSERT (ParentFvNameValue != NULL);

+    FvInfoPpi->ParentFvName = ParentFvNameValue;

+  }

+  if (ParentFileName != NULL) {

+    ParentFileNameValue = AllocateCopyPool (sizeof (EFI_GUID), ParentFileName);

+    ASSERT (ParentFileNameValue != NULL);

+    FvInfoPpi->ParentFileName = ParentFileNameValue;

+  }

+

+  FvInfoPpiDescriptor = AllocatePool (sizeof (EFI_PEI_PPI_DESCRIPTOR));

+  ASSERT (FvInfoPpiDescriptor != NULL);

+

+  FvInfoPpiDescriptor->Guid  = PpiGuid;

+  FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;

+  FvInfoPpiDescriptor->Ppi   = (VOID *) FvInfoPpi;

+  Status = PeiServicesInstallPpi (FvInfoPpiDescriptor);

+  ASSERT_EFI_ERROR (Status);

+

+}

+

+/**

+  Install a EFI_PEI_FIRMWARE_VOLUME_INFO_PPI instance so the PEI Core will be notified about a new firmware volume.

+

+  This function allocates, initializes, and installs a new EFI_PEI_FIRMWARE_VOLUME_INFO_PPI using

+  the parameters passed in to initialize the fields of the EFI_PEI_FIRMWARE_VOLUME_INFO_PPI instance.

+  If the resources can not be allocated for EFI_PEI_FIRMWARE_VOLUME_INFO_PPI, then ASSERT().

+  If the EFI_PEI_FIRMWARE_VOLUME_INFO_PPI can not be installed, then ASSERT().

+

+  @param  FvFormat             Unique identifier of the format of the memory-mapped

+                               firmware volume.  This parameter is optional and

+                               may be NULL.  If NULL is specified, the

+                               EFI_FIRMWARE_FILE_SYSTEM2_GUID format is assumed.

+  @param  FvInfo               Points to a buffer which allows the

+                               EFI_PEI_FIRMWARE_VOLUME_PPI to process the volume.

+                               The format of this buffer is specific to the FvFormat.

+                               For memory-mapped firmware volumes, this typically

+                               points to the first byte of the firmware volume.

+  @param  FvInfoSize           The size, in bytes, of FvInfo. For memory-mapped

+                               firmware volumes, this is typically the size of

+                               the firmware volume.

+  @param  ParentFvName         If the new firmware volume originated from a file

+                               in a different firmware volume, then this parameter

+                               specifies the GUID name of the originating firmware

+                               volume. Otherwise, this parameter must be NULL.

+  @param  ParentFileName       If the new firmware volume originated from a file

+                               in a different firmware volume, then this parameter

+                               specifies the GUID file name of the originating

+                               firmware file. Otherwise, this parameter must be NULL.

+**/

+VOID

+EFIAPI

+PeiServicesInstallFvInfoPpi (

+  IN CONST EFI_GUID                *FvFormat, OPTIONAL

+  IN CONST VOID                    *FvInfo,

+  IN       UINT32                  FvInfoSize,

+  IN CONST EFI_GUID                *ParentFvName, OPTIONAL

+  IN CONST EFI_GUID                *ParentFileName OPTIONAL

+  )

+{

+  InternalPeiServicesInstallFvInfoPpi (TRUE, FvFormat, FvInfo, FvInfoSize, ParentFvName, ParentFileName, 0);

+}

+

+/**

+  Install a EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI instance so the PEI Core will be notified about a new firmware volume.

+

+  This function allocates, initializes, and installs a new EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI using

+  the parameters passed in to initialize the fields of the EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI instance.

+  If the resources can not be allocated for EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI, then ASSERT().

+  If the EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI can not be installed, then ASSERT().

+

+  @param  FvFormat             Unique identifier of the format of the memory-mapped

+                               firmware volume.  This parameter is optional and

+                               may be NULL.  If NULL is specified, the

+                               EFI_FIRMWARE_FILE_SYSTEM2_GUID format is assumed.

+  @param  FvInfo               Points to a buffer which allows the

+                               EFI_PEI_FIRMWARE_VOLUME_PPI to process the volume.

+                               The format of this buffer is specific to the FvFormat.

+                               For memory-mapped firmware volumes, this typically

+                               points to the first byte of the firmware volume.

+  @param  FvInfoSize           The size, in bytes, of FvInfo. For memory-mapped

+                               firmware volumes, this is typically the size of

+                               the firmware volume.

+  @param  ParentFvName         If the new firmware volume originated from a file

+                               in a different firmware volume, then this parameter

+                               specifies the GUID name of the originating firmware

+                               volume. Otherwise, this parameter must be NULL.

+  @param  ParentFileName       If the new firmware volume originated from a file

+                               in a different firmware volume, then this parameter

+                               specifies the GUID file name of the originating

+                               firmware file. Otherwise, this parameter must be NULL.

+  @param  AuthenticationStatus Authentication Status

+**/

+VOID

+EFIAPI

+PeiServicesInstallFvInfo2Ppi (

+  IN CONST EFI_GUID                *FvFormat, OPTIONAL

+  IN CONST VOID                    *FvInfo,

+  IN       UINT32                  FvInfoSize,

+  IN CONST EFI_GUID                *ParentFvName, OPTIONAL

+  IN CONST EFI_GUID                *ParentFileName, OPTIONAL

+  IN       UINT32                  AuthenticationStatus

+  )

+{

+  InternalPeiServicesInstallFvInfoPpi (FALSE, FvFormat, FvInfo, FvInfoSize, ParentFvName, ParentFileName, AuthenticationStatus);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
new file mode 100644
index 0000000..ed99266
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
@@ -0,0 +1,48 @@
+## @file

+# PEI Services Library implementation.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiServicesLib

+  MODULE_UNI_FILE                = PeiServicesLib.uni

+  FILE_GUID                      = a804239b-4155-446f-acc8-f0825d74908c

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeiServicesLib|SEC PEIM PEI_CORE 

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiServicesLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  PeiServicesTablePointerLib

+  MemoryAllocationLib

+  DebugLib

+

+[Guids]

+  gEfiFirmwareFileSystem2Guid        ## SOMETIMES_PRODUCES ## GUID # FV File System Guid.

+

+[Ppis]

+  gEfiPeiFirmwareVolumeInfoPpiGuid   ## SOMETIMES_PRODUCES

+  gEfiPeiFirmwareVolumeInfo2PpiGuid  ## SOMETIMES_PRODUCES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.uni
new file mode 100644
index 0000000..5e32c85
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesLib/PeiServicesLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
new file mode 100644
index 0000000..efcaac9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c
@@ -0,0 +1,116 @@
+/** @file

+  PEI Services Table Pointer Library.

+  

+  This library is used for PEIM which does executed from flash device directly but

+  executed in memory.

+

+  Copyright (c) 2006 - 2014, 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 <PiPei.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/DebugLib.h>

+

+CONST EFI_PEI_SERVICES  **gPeiServices;

+

+/**

+  Caches a pointer PEI Services Table. 

+ 

+  Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer 

+  in a CPU specific manner as specified in the CPU binding section of the Platform Initialization 

+  Pre-EFI Initialization Core Interface Specification. 

+  

+  If PeiServicesTablePointer is NULL, then ASSERT().

+  

+  @param    PeiServicesTablePointer   The address of PeiServices pointer.

+**/

+VOID

+EFIAPI

+SetPeiServicesTablePointer (

+  IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer

+  )

+{

+  ASSERT (PeiServicesTablePointer != NULL);

+  gPeiServices = PeiServicesTablePointer;

+}

+

+/**

+  Retrieves the cached value of the PEI Services Table pointer.

+

+  Returns the cached value of the PEI Services Table pointer in a CPU specific manner 

+  as specified in the CPU binding section of the Platform Initialization Pre-EFI 

+  Initialization Core Interface Specification.

+  

+  If the cached PEI Services Table pointer is NULL, then ASSERT().

+

+  @return  The pointer to PeiServices.

+

+**/

+CONST EFI_PEI_SERVICES **

+EFIAPI

+GetPeiServicesTablePointer (

+  VOID

+  )

+{

+  ASSERT (gPeiServices != NULL);

+  return gPeiServices;

+}

+

+

+/**

+  The constructor function caches the pointer to PEI services.

+  

+  The constructor function caches the pointer to PEI services.

+  It will always return EFI_SUCCESS.

+

+  @param  FileHandle   The handle of FFS header the loaded driver.

+  @param  PeiServices  The pointer to the PEI services.

+

+  @retval EFI_SUCCESS  The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PeiServicesTablePointerLibConstructor (

+  IN EFI_PEI_FILE_HANDLE        FileHandle,

+  IN CONST EFI_PEI_SERVICES     **PeiServices

+  )

+{

+  gPeiServices = PeiServices;

+  return EFI_SUCCESS;

+}

+

+/**

+  Perform CPU specific actions required to migrate the PEI Services Table 

+  pointer from temporary RAM to permanent RAM.

+

+  For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes 

+  immediately preceding the Interrupt Descriptor Table (IDT) in memory.

+  For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes 

+  immediately preceding the Interrupt Descriptor Table (IDT) in memory.

+  For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in

+  a dedicated CPU register.  This means that there is no memory storage 

+  associated with storing the PEI Services Table pointer, so no additional 

+  migration actions are required for Itanium or ARM CPUs.

+

+**/

+VOID

+EFIAPI

+MigratePeiServicesTablePointer (

+  VOID

+  )

+{

+  //

+  //  PEI Services Table pointer is cached in the global variable. No additional 

+  //  migration actions are required.

+  //

+  return;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
new file mode 100644
index 0000000..5925f13
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
@@ -0,0 +1,44 @@
+## @file

+# Instance of PEI Services Table Pointer Library using global variable for the table pointer.

+#

+# PEI Services Table Pointer Library implementation that retrieves a pointer to the

+#  PEI Services Table from a global variable. Not available to modules that execute from

+#  read-only memory.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiServicesTablePointerLib

+  MODULE_UNI_FILE                = PeiServicesTablePointerLib.uni

+  FILE_GUID                      = 1c747f6b-0a58-49ae-8ea3-0327a4fa10e3

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeiServicesTablePointerLib|PEIM PEI_CORE SEC

+

+  CONSTRUCTOR                    = PeiServicesTablePointerLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeiServicesTablePointer.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.uni b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.uni
new file mode 100644
index 0000000..28357ec
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c
new file mode 100644
index 0000000..dd0a78d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c
@@ -0,0 +1,131 @@
+/** @file

+  PEI Services Table Pointer Library for IA-32 and x64.

+

+  According to PI specification, the peiservice pointer is stored prior at IDT

+  table in IA32 and x64 architecture.

+  

+  Copyright (c) 2006 - 2014, 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 <PiPei.h>

+

+#include <Library/BaseLib.h>

+#include <Library/PeiServicesTablePointerLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseMemoryLib.h>

+

+/**

+  Retrieves the cached value of the PEI Services Table pointer.

+

+  Returns the cached value of the PEI Services Table pointer in a CPU specific manner 

+  as specified in the CPU binding section of the Platform Initialization Pre-EFI 

+  Initialization Core Interface Specification.

+  

+  If the cached PEI Services Table pointer is NULL, then ASSERT().

+

+  @return  The pointer to PeiServices.

+

+**/

+CONST EFI_PEI_SERVICES **

+EFIAPI

+GetPeiServicesTablePointer (

+  VOID

+  )

+{

+  CONST EFI_PEI_SERVICES  **PeiServices;

+  IA32_DESCRIPTOR   Idtr;

+  

+  AsmReadIdtr (&Idtr);

+  PeiServices = (CONST EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.Base - sizeof (UINTN)));

+  ASSERT (PeiServices != NULL);

+  return PeiServices;

+}

+

+/**

+  Caches a pointer PEI Services Table. 

+ 

+  Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer 

+  in a CPU specific manner as specified in the CPU binding section of the Platform Initialization 

+  Pre-EFI Initialization Core Interface Specification. 

+  The function set the pointer of PEI services immediately preceding the IDT table

+  according to PI specification.

+  

+  If PeiServicesTablePointer is NULL, then ASSERT().

+  

+  @param    PeiServicesTablePointer   The address of PeiServices pointer.

+**/

+VOID

+EFIAPI

+SetPeiServicesTablePointer (

+  IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer

+  )

+{

+  IA32_DESCRIPTOR        Idtr;

+  

+  ASSERT (PeiServicesTablePointer != NULL);

+  AsmReadIdtr (&Idtr);

+  (*(UINTN*)(Idtr.Base - sizeof (UINTN))) = (UINTN)PeiServicesTablePointer;

+}

+

+/**

+  Perform CPU specific actions required to migrate the PEI Services Table 

+  pointer from temporary RAM to permanent RAM.

+

+  For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes 

+  immediately preceding the Interrupt Descriptor Table (IDT) in memory.

+  For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes 

+  immediately preceding the Interrupt Descriptor Table (IDT) in memory.

+  For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in

+  a dedicated CPU register.  This means that there is no memory storage 

+  associated with storing the PEI Services Table pointer, so no additional 

+  migration actions are required for Itanium or ARM CPUs.

+

+  If The cached PEI Services Table pointer is NULL, then ASSERT().

+  If the permanent memory is allocated failed, then ASSERT().

+**/

+VOID

+EFIAPI

+MigratePeiServicesTablePointer (

+  VOID

+  )

+{

+  EFI_STATUS             Status;

+  IA32_DESCRIPTOR        Idtr;

+  EFI_PHYSICAL_ADDRESS   IdtBase;

+  CONST EFI_PEI_SERVICES  **PeiServices;

+

+  //

+  // Get PEI Services Table pointer

+  //

+  AsmReadIdtr (&Idtr);

+  PeiServices = (CONST EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.Base - sizeof (UINTN)));

+  ASSERT (PeiServices != NULL);

+  //

+  // Allocate the permanent memory.

+  //

+  Status = (*PeiServices)->AllocatePages (

+                            PeiServices, 

+                            EfiBootServicesCode,

+                            EFI_SIZE_TO_PAGES(Idtr.Limit + 1 + sizeof (UINTN)),

+                            &IdtBase

+                            );

+  ASSERT_EFI_ERROR (Status);

+  //

+  // Idt table needs to be migrated into memory.

+  //

+  CopyMem ((VOID *) (UINTN) IdtBase, (VOID *) (Idtr.Base - sizeof (UINTN)), Idtr.Limit + 1 + sizeof (UINTN));

+  Idtr.Base = (UINTN) IdtBase + sizeof (UINTN);

+  AsmWriteIdtr (&Idtr);

+  

+  return;

+}

+

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
new file mode 100644
index 0000000..d14af86
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
@@ -0,0 +1,43 @@
+## @file

+# Instance of PEI Services Table Pointer Library using IDT for the table pointer.

+#

+# PEI Services Table Pointer Library implementation that retrieves a pointer to the PEI

+# Services Table from the IDT on IA-32 and x64.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiServicesTablePointerLibIdt

+  MODULE_UNI_FILE                = PeiServicesTablePointerLibIdt.uni

+  FILE_GUID                      = DED3F743-CE2C-4ba6-92A2-FFCE2A6D72D9

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeiServicesTablePointerLib|PEIM PEI_CORE SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[Sources]

+  PeiServicesTablePointer.c

+

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+  BaseMemoryLib

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.uni b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.uni
new file mode 100644
index 0000000..966f8fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c
new file mode 100644
index 0000000..66cf7bc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c
@@ -0,0 +1,91 @@
+/** @file

+  PEI Services Table Pointer Library implementation for IPF that uses Kernel

+  Register 7 to store the pointer.

+

+  Copyright (c) 2006 - 2014, 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 <PiPei.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Retrieves the cached value of the PEI Services Table pointer.

+

+  Returns the cached value of the PEI Services Table pointer in a CPU specific manner 

+  as specified in the CPU binding section of the Platform Initialization Pre-EFI 

+  Initialization Core Interface Specification.

+  

+  If the cached PEI Services Table pointer is NULL, then ASSERT().

+

+  @return  The pointer to PeiServices.

+

+**/

+CONST EFI_PEI_SERVICES **

+EFIAPI

+GetPeiServicesTablePointer (

+  VOID

+  )

+{

+  CONST EFI_PEI_SERVICES  **PeiServices;

+

+  PeiServices = (CONST EFI_PEI_SERVICES **)(UINTN)AsmReadKr7 ();

+  ASSERT (PeiServices != NULL);

+  return PeiServices;

+}

+

+

+/**

+  Caches a pointer PEI Services Table. 

+ 

+  Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer 

+  in a CPU specific manner as specified in the CPU binding section of the Platform Initialization 

+  Pre-EFI Initialization Core Interface Specification. 

+  The function set the pointer of PEI services in KR7 register 

+  according to PI specification.

+  

+  If PeiServicesTablePointer is NULL, then ASSERT().

+  

+  @param    PeiServicesTablePointer   The address of PeiServices pointer.

+**/

+VOID

+EFIAPI

+SetPeiServicesTablePointer (

+  IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer

+  )

+{

+  ASSERT (PeiServicesTablePointer != NULL);

+  AsmWriteKr7 ((UINT64)(UINTN)PeiServicesTablePointer);

+}

+  

+/**

+  Perform CPU specific actions required to migrate the PEI Services Table 

+  pointer from temporary RAM to permanent RAM.

+

+  For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes 

+  immediately preceding the Interrupt Descriptor Table (IDT) in memory.

+  For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes 

+  immediately preceding the Interrupt Descriptor Table (IDT) in memory.

+  For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in

+  a dedicated CPU register.  This means that there is no memory storage 

+  associated with storing the PEI Services Table pointer, so no additional 

+  migration actions are required for Itanium or ARM CPUs.

+

+**/

+VOID

+EFIAPI

+MigratePeiServicesTablePointer (

+  VOID

+  )

+{

+  return;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.inf b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.inf
new file mode 100644
index 0000000..ae38fc0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.inf
@@ -0,0 +1,42 @@
+## @file

+# Instance of PEI Services Table Pointer Library using KR7 for the table pointer.

+#

+# PEI Services Table Pointer Library implementation that retrieves a pointer to the PEI

+# Services Table from KR7 on IPF.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiServicesTablePointerLibKr7

+  MODULE_UNI_FILE                = PeiServicesTablePointerLibKr7.uni

+  FILE_GUID                      = E0E7D776-E7EB-4e5f-9AA8-54CF3AA64A43

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeiServicesTablePointerLib|SEC PEIM PEI_CORE

+

+

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources.Ipf]

+  PeiServicesTablePointer.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.uni b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.uni
new file mode 100644
index 0000000..5517f3c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointerLibKr7.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/InternalSmbusLib.h b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/InternalSmbusLib.h
new file mode 100644
index 0000000..00f8078
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/InternalSmbusLib.h
@@ -0,0 +1,80 @@
+/** @file

+Internal header file for Smbus library.

+

+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 __INTERNAL_SMBUS_LIB_H_

+#define __INTERNAL_SMBUS_LIB_H_

+

+

+#include <PiPei.h>

+

+#include <Ppi/Smbus2.h>

+

+#include <Library/SmbusLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PeiServicesLib.h>

+#include <Library/BaseMemoryLib.h>

+

+//

+// Declaration for internal functions

+//

+

+/**

+  Gets Smbus PPIs.

+

+  This internal function retrieves Smbus PPI from PPI database.

+

+  @param  VOID

+

+  @return The pointer to Smbus PPI.

+

+**/

+EFI_PEI_SMBUS2_PPI *

+InternalGetSmbusPpi (

+  VOID

+  );

+

+/**

+  Executes an SMBus operation to an SMBus controller.

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol 

+                          instance that it will use to execute the SMBus transactions.

+  @param  SmBusAddress    The address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will 

+                          do. The maximum number of bytes can be revision specific 

+                          and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave 

+                          device. Not all operations require this argument. The 

+                          length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation.

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLib.c
new file mode 100644
index 0000000..5821e9b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLib.c
@@ -0,0 +1,95 @@
+/** @file

+Implementation of SmBusLib class library for PEI phase.

+

+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.

+

+**/

+

+#include "InternalSmbusLib.h"

+

+/**

+  Gets Smbus PPIs.

+

+  This internal function retrieves Smbus PPI from PPI database.

+

+  @param  VOID

+

+  @return The pointer to Smbus PPI.

+

+**/

+EFI_PEI_SMBUS2_PPI *

+InternalGetSmbusPpi (

+  VOID

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PEI_SMBUS2_PPI     *SmbusPpi;

+

+  Status = PeiServicesLocatePpi (&gEfiPeiSmbus2PpiGuid, 0, NULL, (VOID **) &SmbusPpi);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (SmbusPpi != NULL);

+

+  return SmbusPpi;

+}

+

+/**

+  Executes an SMBus operation to an SMBus controller.

+

+  This function provides a standard way to execute Smbus script

+  as defined in the SmBus Specification. The data can either be of

+  the Length byte, word, or a block of data.

+

+  @param  SmbusOperation  Signifies which particular SMBus hardware protocol instance 

+                          that it will use to execute the SMBus transactions.

+  @param  SmBusAddress    The address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Length          Signifies the number of bytes that this operation will 

+                          do. The maximum number of bytes can be revision specific 

+                          and operation specific.

+  @param  Buffer          Contains the value of data to execute to the SMBus slave 

+                          device. Not all operations require this argument. The 

+                          length of this buffer is identified by Length.

+  @param  Status          Return status for the executed command.

+                          This is an optional parameter and may be NULL.

+

+  @return The actual number of bytes that are executed for this operation.

+

+**/

+UINTN

+InternalSmBusExec (

+  IN     EFI_SMBUS_OPERATION        SmbusOperation,

+  IN     UINTN                      SmBusAddress,

+  IN     UINTN                      Length,

+  IN OUT VOID                       *Buffer,

+     OUT RETURN_STATUS              *Status        OPTIONAL

+  )

+{

+  EFI_PEI_SMBUS2_PPI        *SmbusPpi;

+  RETURN_STATUS             ReturnStatus;

+  EFI_SMBUS_DEVICE_ADDRESS  SmbusDeviceAddress;

+

+  SmbusPpi    = InternalGetSmbusPpi ();

+  SmbusDeviceAddress.SmbusDeviceAddress = SMBUS_LIB_SLAVE_ADDRESS (SmBusAddress);

+

+  ReturnStatus = SmbusPpi->Execute (

+                             SmbusPpi,

+                             SmbusDeviceAddress,

+                             SMBUS_LIB_COMMAND (SmBusAddress),

+                             SmbusOperation,

+                             SMBUS_LIB_PEC (SmBusAddress),

+                             &Length,

+                             Buffer

+                             );

+  if (Status != NULL) {

+    *Status = ReturnStatus;

+  }

+

+  return Length;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLibSmbus2Ppi.inf b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLibSmbus2Ppi.inf
new file mode 100644
index 0000000..cef8e03
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLibSmbus2Ppi.inf
@@ -0,0 +1,50 @@
+## @file

+# SMBUS library that layers on top of the SMBUS2 PPI.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeiSmbusLibSmbus2Ppi

+  MODULE_UNI_FILE                = PeiSmbusLibSmbus2Ppi.uni

+  FILE_GUID                      = 2A1E1C92-AABA-4d62-AC40-F3A4C3387356

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmbusLib|PEIM SEC

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  SmbusLib.c

+  PeiSmbusLib.c

+  InternalSmbusLib.h

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  PeiServicesLib

+  DebugLib

+

+[Ppis]

+  gEfiPeiSmbus2PpiGuid                           ## CONSUMES

+

+[Depex.common.PEIM]

+  gEfiPeiSmbus2PpiGuid 

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLibSmbus2Ppi.uni b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLibSmbus2Ppi.uni
new file mode 100644
index 0000000..6fac3d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/PeiSmbusLibSmbus2Ppi.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/SmbusLib.c b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/SmbusLib.c
new file mode 100644
index 0000000..42e9513
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeiSmbusLibSmbus2Ppi/SmbusLib.c
@@ -0,0 +1,584 @@
+/** @file

+Implementation of SmBusLib class library for PEI phase.

+

+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.

+

+

+**/

+

+#include "InternalSmbusLib.h"

+

+/**

+  Executes an SMBUS quick read command.

+

+  Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS:  The SMBUS command was executed.

+                        RETURN_TIMEOUT:  A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR: The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle

+                        (host initiated), or bus errors (collisions).

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+**/

+VOID

+EFIAPI

+SmBusQuickRead (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickRead, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS quick write command.

+

+  Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If PEC is set in SmBusAddress, then ASSERT().

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle (host initiated), or bus 

+                        errors (collisions).

+                        RETURN_UNSUPPORTED::  The SMBus operation is not supported.

+

+**/

+VOID

+EFIAPI

+SmBusQuickWrite (

+  IN  UINTN                     SmBusAddress,

+  OUT RETURN_STATUS             *Status       OPTIONAL

+  )

+{

+  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusQuickWrite, SmBusAddress, 0, NULL, Status);

+}

+

+/**

+  Executes an SMBUS receive byte command.

+

+  Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address field of SmBusAddress is required.

+  The byte received from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated),

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The byte received from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReceiveByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)  == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte, Status);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS send byte command.

+

+  Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.

+  The byte specified by Value is sent.

+  Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Command in SmBusAddress is not zero, then ASSERT().

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 8-bit value to send.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  Device 

+                        errors are a result of a transaction collision, illegal 

+                        command field, unclaimed cycle (host initiated), or bus 

+                        errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusSendByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Byte   = Value;

+  InternalSmBusExec (EfiSmbusSendByte, SmBusAddress, 1, &Byte, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data byte command.

+

+  Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 8-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress    The address that encodes the SMBUS Slave Address,

+                          SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated),

+                       or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT8

+EFIAPI

+SmBusReadDataByte (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, 1, &Byte, Status);

+

+  return Byte;

+}

+

+/**

+  Executes an SMBUS write data byte command.

+

+  Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.

+  The 8-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 8-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated),

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT8

+EFIAPI

+SmBusWriteDataByte (

+  IN  UINTN          SmBusAddress,

+  IN  UINT8          Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT8   Byte;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Byte = Value;

+  InternalSmBusExec (EfiSmbusWriteByte, SmBusAddress, 1, &Byte, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read data word command.

+

+  Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value read from the SMBUS is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+  

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated),

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The byte read from the SMBUS.

+

+**/

+UINT16

+EFIAPI

+SmBusReadDataWord (

+  IN  UINTN          SmBusAddress,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);

+

+  return Word;

+}

+

+/**

+  Executes an SMBUS write data word command.

+

+  Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Value is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 16-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated),

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+SmBusWriteDataWord (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINT16  Word;

+

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Word = Value;

+  InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS process call command.

+

+  Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.

+  The 16-bit value specified by Value is written.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  The 16-bit value returned by the process call command is returned.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Value         The 16-bit value to write.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated),

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The 16-bit value returned by the process call command.

+

+**/

+UINT16

+EFIAPI

+SmBusProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  UINT16         Value,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);

+

+  return Value;

+}

+

+/**

+  Executes an SMBUS read block command.

+

+  Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.

+  Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.

+  Bytes are read from the SMBUS and stored in Buffer.

+  The number of bytes read is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is not zero, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer        The pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_SUCCESS: The SMBUS command was executed.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The number of bytes read.

+

+**/

+UINTN

+EFIAPI

+SmBusReadBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS write block command.

+

+  Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from Buffer.

+  The number of bytes written is returned, and will never return a value larger than 32-bytes.

+  If Status is not NULL, then the status of the executed command is returned in Status.  

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If Buffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        MBUS Command, SMBUS Data Length, and PEC.

+  @param  Buffer        The pointer to the buffer to store the bytes read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR:  The checksum is not correct (PEC is incorrect)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusWriteBlock (

+  IN  UINTN          SmBusAddress,

+  OUT VOID           *Buffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN  Length;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Length = SMBUS_LIB_LENGTH (SmBusAddress);

+  return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);

+}

+

+/**

+  Executes an SMBUS block process call command.

+

+  Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.

+  The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.

+  Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.

+  If Status is not NULL, then the status of the executed command is returned in Status.

+  It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.

+  SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.

+  If Length in SmBusAddress is zero or greater than 32, then ASSERT().

+  If WriteBuffer is NULL, then ASSERT().

+  If ReadBuffer is NULL, then ASSERT().

+  If any reserved bits of SmBusAddress are set, then ASSERT().

+

+  @param  SmBusAddress  The address that encodes the SMBUS Slave Address,

+                        SMBUS Command, SMBUS Data Length, and PEC.

+  @param  WriteBuffer   The pointer to the buffer of bytes to write to the SMBUS.

+  @param  ReadBuffer    The pointer to the buffer of bytes to read from the SMBUS.

+  @param  Status        Return status for the executed command.

+                        This is an optional parameter and may be NULL.

+                        RETURN_TIMEOUT: A timeout occurred while executing the 

+                        SMBUS command.

+                        RETURN_DEVICE_ERROR:  The request was not completed because 

+                        a failure reflected in the Host Status Register bit.  

+                        Device errors are a result of a transaction collision, 

+                        illegal command field, unclaimed cycle (host initiated), 

+                        or bus errors (collisions).

+                        RETURN_CRC_ERROR  The checksum is not correct. (PEC is incorrect.)

+                        RETURN_UNSUPPORTED:  The SMBus operation is not supported.

+

+  @return The number of bytes written.

+

+**/

+UINTN

+EFIAPI

+SmBusBlockProcessCall (

+  IN  UINTN          SmBusAddress,

+  IN  VOID           *WriteBuffer,

+  OUT VOID           *ReadBuffer,

+  OUT RETURN_STATUS  *Status        OPTIONAL

+  )

+{

+  UINTN   Length;

+

+  ASSERT (WriteBuffer != NULL);

+  ASSERT (ReadBuffer  != NULL);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);

+  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);

+  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);

+

+  Length = SMBUS_LIB_LENGTH (SmBusAddress);

+  //

+  // Assuming that ReadBuffer is large enough to save another memory copy.

+  //

+  ReadBuffer = CopyMem (ReadBuffer, WriteBuffer, Length);

+  return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, ReadBuffer, Status);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c b/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c
new file mode 100644
index 0000000..83a1bd8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.c
@@ -0,0 +1,81 @@
+/** @file

+  Entry point to a PEIM.

+

+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.

+

+**/

+

+

+#include <PiPei.h>

+

+

+#include <Library/PeimEntryPoint.h>

+#include <Library/DebugLib.h>

+

+/**

+  The entry point of PE/COFF Image for a PEIM.

+

+  This function is the entry point for a PEIM.  This function must call ProcessLibraryConstructorList() 

+  and ProcessModuleEntryPointList().  The return value from ProcessModuleEntryPointList() is returned.

+  If _gPeimRevision is not zero and PeiServices->Hdr.Revision is less than _gPeimRevison, then ASSERT().

+

+  @param  FileHandle  Handle of the file being invoked. 

+  @param  PeiServices Describes the list of possible PEI Services.

+

+  @retval  EFI_SUCCESS   The PEIM executed normally.

+  @retval  !EFI_SUCCESS  The PEIM failed to execute normally.

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_PEI_FILE_HANDLE       FileHandle,

+  IN CONST EFI_PEI_SERVICES    **PeiServices

+  )

+{

+  if (_gPeimRevision != 0) {

+    //

+    // Make sure that the PEI spec revision of the platform is >= PEI spec revision of the driver

+    //

+    ASSERT ((*PeiServices)->Hdr.Revision >= _gPeimRevision);

+  }

+

+  //

+  // Call constructor for all libraries

+  //

+  ProcessLibraryConstructorList (FileHandle, PeiServices);

+

+  //

+  // Call the driver entry point

+  //

+  return ProcessModuleEntryPointList (FileHandle, PeiServices);

+}

+

+

+/**

+  Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().

+  

+  This function is required to call _ModuleEntryPoint() passing in FileHandle and PeiServices.

+

+  @param  FileHandle  Handle of the file being invoked. 

+  @param  PeiServices Describes the list of possible PEI Services.

+

+  @retval EFI_SUCCESS  The PEIM executed normally.

+  @retval !EFI_SUCCESS The PEIM failed to execute normally.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_PEI_FILE_HANDLE       FileHandle,

+  IN CONST EFI_PEI_SERVICES    **PeiServices

+  )

+{

+  return _ModuleEntryPoint (FileHandle, PeiServices);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf b/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
new file mode 100644
index 0000000..a2db9e0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -0,0 +1,39 @@
+## @file

+# Module entry point library for PEIM.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = PeimEntryPoint

+  MODULE_UNI_FILE                = PeimEntryPoint.uni

+  FILE_GUID                      = fa177ff7-1fc7-458d-a358-d9d62ae61cec

+  MODULE_TYPE                    = PEIM

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PeimEntryPoint|PEIM 

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is for build only)

+#

+

+[Sources]

+  PeimEntryPoint.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.uni b/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.uni
new file mode 100644
index 0000000..258108b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/PeimEntryPoint/PeimEntryPoint.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/IpfTimerLib.c b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/IpfTimerLib.c
new file mode 100644
index 0000000..714b99e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/IpfTimerLib.c
@@ -0,0 +1,216 @@
+/** @file

+  Timer Library functions built upon ITC on IPF.

+

+  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

+  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 <Base.h>

+#include <Library/TimerLib.h>

+#include <Library/BaseLib.h>

+#include <Library/PalLib.h>

+

+

+/**

+  Performs a delay measured as number of ticks.

+

+  An internal function to perform a delay measured as number of ticks. It's

+  invoked by MicroSecondDelay() and NanoSecondDelay().

+

+  @param  Delay The number of ticks to delay.

+

+**/

+VOID

+EFIAPI

+InternalIpfDelay (

+  IN      INT64                     Delay

+  )

+{

+  INT64                             Ticks;

+

+  //

+  // The target timer count is calculated here

+  //

+  Ticks = (INT64)AsmReadItc () + Delay;

+

+  //

+  // Wait until time out

+  // Delay > 2^63 could not be handled by this function

+  // Timer wrap-arounds are handled correctly by this function

+  //

+  while (Ticks - (INT64)AsmReadItc() >= 0);

+}

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return The value of MicroSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  InternalIpfDelay (

+    GetPerformanceCounterProperties (NULL, NULL) *

+    MicroSeconds /

+    1000000

+    );

+  return MicroSeconds;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return The value of NanoSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  InternalIpfDelay (

+    GetPerformanceCounterProperties (NULL, NULL) *

+    NanoSeconds /

+    1000000000

+    );

+  return NanoSeconds;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  The counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  return AsmReadItc ();

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  OUT      UINT64                    *StartValue,  OPTIONAL

+  OUT      UINT64                    *EndValue     OPTIONAL

+  )

+{

+  PAL_CALL_RETURN                   PalRet;

+  UINT64                            BaseFrequence;

+

+  if (StartValue != NULL) {

+    *StartValue = 0;

+  }

+

+  if (EndValue != NULL) {

+    *EndValue = (UINT64)(-1);

+  }

+

+  PalRet = PalCall (PAL_FREQ_BASE, 0, 0, 0);

+  if (PalRet.Status != 0) {

+    return 1000000;

+  }

+  BaseFrequence = PalRet.r9;

+

+  PalRet = PalCall (PAL_FREQ_RATIOS, 0, 0, 0);

+  if (PalRet.Status != 0) {

+    return 1000000;

+  }

+

+  return BaseFrequence * (PalRet.r11 >> 32) / (UINT32)PalRet.r11;

+}

+

+/**

+  Converts elapsed ticks of performance counter to time in nanoseconds.

+

+  This function converts the elapsed ticks of running performance counter to

+  time value in unit of nanoseconds.

+

+  @param  Ticks     The number of elapsed ticks of running performance counter.

+

+  @return The elapsed time in nanoseconds.

+

+**/

+UINT64

+EFIAPI

+GetTimeInNanoSecond (

+  IN      UINT64                     Ticks

+  )

+{

+  UINT64  Frequency;

+  UINT64  NanoSeconds;

+  UINT64  Remainder;

+  INTN    Shift;

+

+  Frequency = GetPerformanceCounterProperties (NULL, NULL);

+

+  //

+  //          Ticks

+  // Time = --------- x 1,000,000,000

+  //        Frequency

+  //

+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);

+

+  //

+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.

+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,

+  // i.e. highest bit set in Remainder should <= 33.

+  //

+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);

+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);

+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);

+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);

+

+  return NanoSeconds;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
new file mode 100644
index 0000000..a00ebb0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
@@ -0,0 +1,67 @@
+## @file

+# Instance of Timer Library only using CPU resources.

+#

+# Timer Library that only uses CPU resources to provide calibrated delays

+#  on IA-32, x64, and IPF.

+# Note: A driver of type DXE_RUNTIME_DRIVER and DXE_SMM_DRIVER can use this TimerLib 

+#  in their initialization without any issues. They only have to be careful in 

+#  the implementation of runtime services and SMI handlers.  

+#  Because CPU Local APIC and ITC could be programmed by OS, it cannot be

+#  used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM

+#  drivers and runtime drivers.

+#

+# Note that for IA-32 and x64, this library only supports xAPIC mode. If x2APIC

+# support is desired, the SecPeiDxeTimerLibUefiCpu library can be used.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SecPeiDxeTimerLibCpu

+  MODULE_UNI_FILE                = SecPeiDxeTimerLibCpu.uni

+  FILE_GUID                      = b5a05743-9b71-489b-a0ed-a0eb3950d23b

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = TimerLib

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF

+#

+

+[Sources.Ia32, Sources.X64]

+  X86TimerLib.c

+

+[Sources.IPF]

+  IpfTimerLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+

+[LibraryClasses.IA32, LibraryClasses.X64]

+  PcdLib

+  IoLib

+  DebugLib

+

+[LibraryClasses.IPF]

+  PalLib

+

+

+[Pcd.IA32, Pcd.X64]

+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.uni b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.uni
new file mode 100644
index 0000000..1e80508
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/X86TimerLib.c b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/X86TimerLib.c
new file mode 100644
index 0000000..7b2bc54
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/X86TimerLib.c
@@ -0,0 +1,340 @@
+/** @file

+  Timer Library functions built upon local APIC on IA32/x64.

+

+  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.

+

+**/

+

+#include <Base.h>

+#include <Library/TimerLib.h>

+#include <Library/BaseLib.h>

+#include <Library/IoLib.h>

+#include <Library/PcdLib.h>

+#include <Library/DebugLib.h>

+

+#define APIC_LVTERR     0x370

+#define APIC_TMICT      0x380

+#define APIC_TMCCT      0x390

+#define APIC_TDCR       0x3e0

+

+//

+// The following array is used in calculating the frequency of local APIC

+// timer. Refer to IA-32 developers' manual for more details.

+//

+GLOBAL_REMOVE_IF_UNREFERENCED

+CONST UINT8                           mTimerLibLocalApicDivisor[] = {

+  0x02, 0x04, 0x08, 0x10,

+  0x02, 0x04, 0x08, 0x10,

+  0x20, 0x40, 0x80, 0x01,

+  0x20, 0x40, 0x80, 0x01

+};

+

+/**

+  Internal function to retrieve the base address of local APIC.

+

+  @return The base address of local APIC

+

+**/

+UINTN

+EFIAPI

+InternalX86GetApicBase (

+  VOID

+  )

+{

+  return (UINTN)AsmMsrBitFieldRead64 (27, 12, 35) << 12;

+}

+

+/**

+  Internal function to return the frequency of the local APIC timer.

+

+  @param  ApicBase  The base address of memory mapped registers of local APIC.

+

+  @return The frequency of the timer in Hz.

+

+**/

+UINT32

+EFIAPI

+InternalX86GetTimerFrequency (

+  IN      UINTN                     ApicBase

+  )

+{

+  return

+    PcdGet32(PcdFSBClock) /

+    mTimerLibLocalApicDivisor[MmioBitFieldRead32 (ApicBase + APIC_TDCR, 0, 3)];

+}

+

+/**

+  Internal function to read the current tick counter of local APIC.

+

+  @param  ApicBase  The base address of memory mapped registers of local APIC.

+

+  @return The tick counter read.

+

+**/

+INT32

+EFIAPI

+InternalX86GetTimerTick (

+  IN      UINTN                     ApicBase

+  )

+{

+  return MmioRead32 (ApicBase + APIC_TMCCT);

+}

+

+/**

+  Internal function to read the initial timer count of local APIC.

+

+  @param  ApicBase  The base address of memory mapped registers of local APIC.

+

+  @return The initial timer count read.

+

+**/

+UINT32

+InternalX86GetInitTimerCount (

+  IN      UINTN                     ApicBase

+  )

+{

+  return MmioRead32 (ApicBase + APIC_TMICT);

+}

+

+/**

+  Stalls the CPU for at least the given number of ticks.

+

+  Stalls the CPU for at least the given number of ticks. It's invoked by

+  MicroSecondDelay() and NanoSecondDelay().

+

+  @param  ApicBase  The base address of memory mapped registers of local APIC.

+  @param  Delay     A period of time to delay in ticks.

+

+**/

+VOID

+EFIAPI

+InternalX86Delay (

+  IN      UINTN                     ApicBase,

+  IN      UINT32                    Delay

+  )

+{

+  INT32                             Ticks;

+  UINT32                            Times;

+  UINT32                            InitCount;

+  UINT32                            StartTick;

+

+  //

+  // In case Delay is too larger, separate it into several small delay slot.

+  // Devided Delay by half value of Init Count is to avoid Delay close to

+  // the Init Count, timeout maybe missing if the time consuming between 2

+  // GetApicTimerCurrentCount() invoking is larger than the time gap between

+  // Delay and the Init Count.

+  //

+  InitCount = InternalX86GetInitTimerCount (ApicBase);

+  Times     = Delay / (InitCount / 2);

+  Delay     = Delay % (InitCount / 2);

+

+  //

+  // Get Start Tick and do delay

+  //

+  StartTick  = InternalX86GetTimerTick (ApicBase);

+  do {

+    //

+    // Wait until time out by Delay value

+    //

+    do {

+      CpuPause ();

+      //

+      // Get Ticks from Start to Current.

+      //

+      Ticks = StartTick - InternalX86GetTimerTick (ApicBase);

+      //

+      // Ticks < 0 means Timer wrap-arounds happens.

+      //

+      if (Ticks < 0) {

+        Ticks += InitCount;

+      }

+    } while ((UINT32)Ticks < Delay);

+

+    //

+    // Update StartTick and Delay for next delay slot

+    //

+    StartTick -= (StartTick > Delay) ?  Delay : (Delay - InitCount);

+    Delay      = InitCount / 2;

+  } while (Times-- > 0);

+}

+

+/**

+  Stalls the CPU for at least the given number of microseconds.

+

+  Stalls the CPU for the number of microseconds specified by MicroSeconds.

+

+  @param  MicroSeconds  The minimum number of microseconds to delay.

+

+  @return The value of MicroSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+MicroSecondDelay (

+  IN      UINTN                     MicroSeconds

+  )

+{

+  UINTN                             ApicBase;

+

+  ApicBase = InternalX86GetApicBase ();

+  InternalX86Delay (

+    ApicBase,

+    (UINT32)DivU64x32 (

+              MultU64x64 (

+                InternalX86GetTimerFrequency (ApicBase),

+                MicroSeconds

+                ),

+              1000000u

+              )

+    );

+  return MicroSeconds;

+}

+

+/**

+  Stalls the CPU for at least the given number of nanoseconds.

+

+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.

+

+  @param  NanoSeconds The minimum number of nanoseconds to delay.

+

+  @return The value of NanoSeconds inputted.

+

+**/

+UINTN

+EFIAPI

+NanoSecondDelay (

+  IN      UINTN                     NanoSeconds

+  )

+{

+  UINTN                             ApicBase;

+

+  ApicBase = InternalX86GetApicBase ();

+  InternalX86Delay (

+    ApicBase,

+    (UINT32)DivU64x32 (

+              MultU64x64 (

+                InternalX86GetTimerFrequency (ApicBase),

+                NanoSeconds

+                ),

+              1000000000u

+              )

+    );

+  return NanoSeconds;

+}

+

+/**

+  Retrieves the current value of a 64-bit free running performance counter.

+

+  The counter can either count up by 1 or count down by 1. If the physical

+  performance counter counts by a larger increment, then the counter values

+  must be translated. The properties of the counter can be retrieved from

+  GetPerformanceCounterProperties().

+

+  @return The current value of the free running performance counter.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounter (

+  VOID

+  )

+{

+  return (UINT64)(UINT32)InternalX86GetTimerTick (InternalX86GetApicBase ());

+}

+

+/**

+  Retrieves the 64-bit frequency in Hz and the range of performance counter

+  values.

+

+  If StartValue is not NULL, then the value that the performance counter starts

+  with immediately after is it rolls over is returned in StartValue. If

+  EndValue is not NULL, then the value that the performance counter end with

+  immediately before it rolls over is returned in EndValue. The 64-bit

+  frequency of the performance counter in Hz is always returned. If StartValue

+  is less than EndValue, then the performance counter counts up. If StartValue

+  is greater than EndValue, then the performance counter counts down. For

+  example, a 64-bit free running counter that counts up would have a StartValue

+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter

+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.

+

+  @param  StartValue  The value the performance counter starts with when it

+                      rolls over.

+  @param  EndValue    The value that the performance counter ends with before

+                      it rolls over.

+

+  @return The frequency in Hz.

+

+**/

+UINT64

+EFIAPI

+GetPerformanceCounterProperties (

+  OUT      UINT64                    *StartValue,  OPTIONAL

+  OUT      UINT64                    *EndValue     OPTIONAL

+  )

+{

+  UINTN                             ApicBase;

+

+  ApicBase = InternalX86GetApicBase ();

+

+  if (StartValue != NULL) {

+    *StartValue = (UINT64)InternalX86GetInitTimerCount (ApicBase);

+  }

+

+  if (EndValue != NULL) {

+    *EndValue = 0;

+  }

+

+  return (UINT64) InternalX86GetTimerFrequency (ApicBase);

+}

+

+/**

+  Converts elapsed ticks of performance counter to time in nanoseconds.

+

+  This function converts the elapsed ticks of running performance counter to

+  time value in unit of nanoseconds.

+

+  @param  Ticks     The number of elapsed ticks of running performance counter.

+

+  @return The elapsed time in nanoseconds.

+

+**/

+UINT64

+EFIAPI

+GetTimeInNanoSecond (

+  IN      UINT64                     Ticks

+  )

+{

+  UINT64  Frequency;

+  UINT64  NanoSeconds;

+  UINT64  Remainder;

+  INTN    Shift;

+

+  Frequency = GetPerformanceCounterProperties (NULL, NULL);

+

+  //

+  //          Ticks

+  // Time = --------- x 1,000,000,000

+  //        Frequency

+  //

+  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);

+

+  //

+  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.

+  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,

+  // i.e. highest bit set in Remainder should <= 33.

+  //

+  Shift = MAX (0, HighBitSet64 (Remainder) - 33);

+  Remainder = RShiftU64 (Remainder, (UINTN) Shift);

+  Frequency = RShiftU64 (Frequency, (UINTN) Shift);

+  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);

+

+  return NanoSeconds;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c
new file mode 100644
index 0000000..31be13c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoHighLevel.c
@@ -0,0 +1,2312 @@
+/** @file

+  High-level Io/Mmio functions.

+

+  All assertions for bit field operations are handled bit field functions in the

+  Base Library.

+

+  Copyright (c) 2009 - 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.

+

+  The following IoLib instances share the same version of this file:

+

+    BaseIoLibIntrinsic

+    DxeIoLibCpuIo

+    PeiIoLibCpuIo

+    SmmIoLibCpuIo

+**/

+

+#include "SmmCpuIoLibInternal.h"

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) | OrData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAnd8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (Port, (UINT8) (IoRead8 (Port) & AndData));

+}

+

+/**

+  Reads an 8-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 8-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (Port, (UINT8) ((IoRead8 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in an 8-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldRead8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (IoRead8 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldWrite8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldWrite8 (IoRead8 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 8-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldOr8 (IoRead8 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 8-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAnd8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAnd8 (IoRead8 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit I/O port specified by Port, 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 8-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 8-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoBitFieldAndThenOr8 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return IoWrite8 (

+           Port,

+           BitFieldAndThenOr8 (IoRead8 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) | OrData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAnd16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (Port, (UINT16) (IoRead16 (Port) & AndData));

+}

+

+/**

+  Reads a 16-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 16-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (Port, (UINT16) ((IoRead16 (Port) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 16-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit I/O port 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  Port      The I/O port to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldRead16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (IoRead16 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldWrite16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldWrite16 (IoRead16 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 16-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldOr16 (IoRead16 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 16-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAnd16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAnd16 (IoRead16 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit I/O port specified by Port, 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 16-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 16-bit I/O port 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  Port      The I/O port to write.

+  @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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoBitFieldAndThenOr16 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return IoWrite16 (

+           Port,

+           BitFieldAndThenOr16 (IoRead16 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) | OrData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAnd32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (Port, IoRead32 (Port) & AndData);

+}

+

+/**

+  Reads a 32-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 32-bit I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (Port, (IoRead32 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 32-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 value read.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldRead32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (IoRead32 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldWrite32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldWrite32 (IoRead32 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 32-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldOr32 (IoRead32 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 32-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAnd32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAnd32 (IoRead32 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit I/O port specified by Port, 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 32-bit I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 32-bit I/O port 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoBitFieldAndThenOr32 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return IoWrite32 (

+           Port,

+           BitFieldAndThenOr32 (IoRead32 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise OR, and writes the

+  result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  OrData  The value to OR with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) | OrData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND, and writes the result back

+  to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAnd64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (Port, IoRead64 (Port) & AndData);

+}

+

+/**

+  Reads a 64-bit I/O port, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the 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 I/O port specified by Port. The value

+  written to the I/O port is returned. This function must guarantee that all

+  I/O read and write operations are serialized.

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port    The I/O port to write.

+  @param  AndData The value to AND with the read value from the I/O port.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (Port, (IoRead64 (Port) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of an I/O register.

+

+  Reads the bit field in a 64-bit I/O register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit I/O port 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  Port      The I/O port 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.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldRead64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (IoRead64 (Port), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to an I/O register.

+

+  Writes Value to the bit field of the I/O register. The bit field is specified

+  by the StartBit and the EndBit. All other bits in the destination I/O

+  register are preserved. The value written to the I/O port is returned. Extra

+  left bits in Value are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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     The new value of the bit field.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldWrite64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldWrite64 (IoRead64 (Port), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise OR, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise OR

+  between the read result and the value specified by OrData, and writes the

+  result to the 64-bit I/O port specified by Port. The value written to the I/O

+  port is returned. This function must guarantee that all I/O read and write

+  operations are serialized. Extra left bits in OrData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldOr64 (IoRead64 (Port), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND, and writes the

+  result back to the bit field in the 64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, performs a bitwise AND between

+  the read result and the value specified by AndData, and writes the result to

+  the 64-bit I/O port specified by Port. The value written to the I/O port is

+  returned. This function must guarantee that all I/O read and write operations

+  are serialized. Extra left bits in AndData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAnd64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAnd64 (IoRead64 (Port), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  64-bit port.

+

+  Reads the 64-bit I/O port specified by Port, 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 I/O port specified by Port. The

+  value written to the I/O port is returned. This function must guarantee that

+  all I/O read and write operations are serialized. Extra left bits in both

+  AndData and OrData are stripped.

+

+  If 64-bit I/O port 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  Port      The I/O port 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 I/O port.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoBitFieldAndThenOr64 (

+  IN      UINTN                     Port,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return IoWrite64 (

+           Port,

+           BitFieldAndThenOr64 (IoRead64 (Port), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) | OrData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) (MmioRead8 (Address) & AndData));

+}

+

+/**

+  Reads an 8-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 8-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (Address, (UINT8) ((MmioRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in an 8-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (MmioRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 8-bit register is returned.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldWrite8 (MmioRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 8-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldOr8 (MmioRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 8-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAnd8 (MmioRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address, 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 8-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 8-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return MmioWrite8 (

+           Address,

+           BitFieldAndThenOr8 (MmioRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) | OrData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) (MmioRead16 (Address) & AndData));

+}

+

+/**

+  Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 16-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (Address, (UINT16) ((MmioRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 16-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to read.

+  @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 value read.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (MmioRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 16-bit register is returned.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldWrite16 (MmioRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 16-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldOr16 (MmioRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 16-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAnd16 (MmioRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address, 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 16-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 16-bit MMIO register 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  Address   The MMIO register to write.

+  @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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return MmioWrite16 (

+           Address,

+           BitFieldAndThenOr16 (MmioRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) | OrData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (Address, MmioRead32 (Address) & AndData);

+}

+

+/**

+  Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 32-bit MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (Address, (MmioRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 32-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 value read.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (MmioRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 32-bit register is returned.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldWrite32 (MmioRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 32-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldOr32 (MmioRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 32-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAnd32 (MmioRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address, 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 32-bit MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 32-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return MmioWrite32 (

+           Address,

+           BitFieldAndThenOr32 (MmioRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise OR, and writes the

+  result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  OrData  The value to OR with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) | OrData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result

+  back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAnd64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (Address, MmioRead64 (Address) & AndData);

+}

+

+/**

+  Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise

+  inclusive OR, and writes the result back to the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the 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 MMIO register specified by

+  Address. The value written to the MMIO register is returned. This function

+  must guarantee that all MMIO read and write operations are serialized.

+

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+

+  @param  Address The MMIO register to write.

+  @param  AndData The value to AND with the read value from the MMIO register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (Address, (MmioRead64 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a MMIO register.

+

+  Reads the bit field in a 64-bit MMIO register. The bit field is specified by

+  the StartBit and the EndBit. The value of the bit field is returned.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldRead64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead64 (MmioRead64 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a MMIO register.

+

+  Writes Value to the bit field of the MMIO register. The bit field is

+  specified by the StartBit and the EndBit. All other bits in the destination

+  MMIO register are preserved. The new value of the 64-bit register is returned.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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     The new value of the bit field.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldWrite64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    Value

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldWrite64 (MmioRead64 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise OR, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise

+  inclusive OR between the read result and the value specified by OrData, and

+  writes the result to the 64-bit MMIO register specified by Address. The value

+  written to the MMIO register is returned. This function must guarantee that

+  all MMIO read and write operations are serialized. Extra left bits in OrData

+  are stripped.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldOr64 (MmioRead64 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND, and

+  writes the result back to the bit field in the 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, performs a bitwise AND

+  between the read result and the value specified by AndData, and writes the

+  result to the 64-bit MMIO register specified by Address. The value written to

+  the MMIO register is returned. This function must guarantee that all MMIO

+  read and write operations are serialized. Extra left bits in AndData are

+  stripped.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAnd64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAnd64 (MmioRead64 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 64-bit MMIO register, performs a bitwise AND followed

+  by a bitwise OR, and writes the result back to the bit field in the

+  64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address, 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 MMIO register

+  specified by Address. The value written to the MMIO register is returned.

+  This function must guarantee that all MMIO read and write operations are

+  serialized. Extra left bits in both AndData and OrData are stripped.

+

+  If 64-bit MMIO register 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  Address   The MMIO register 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 read value from the MMIO register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioBitFieldAndThenOr64 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT64                    AndData,

+  IN      UINT64                    OrData

+  )

+{

+  return MmioWrite64 (

+           Address,

+           BitFieldAndThenOr64 (MmioRead64 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoLib.c b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoLib.c
new file mode 100644
index 0000000..1e55791
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoLib.c
@@ -0,0 +1,587 @@
+/** @file

+  I/O Library.

+  The implementation of I/O operation for this library instance 

+  are based on EFI_CPU_IO_PROTOCOL.

+  

+  Copyright (c) 2009 - 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.

+

+**/

+

+#include "SmmCpuIoLibInternal.h"

+

+/**

+  Reads registers in the EFI CPU I/O space.

+

+  Reads the I/O port specified by Port with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI CPU I/O space.

+

+**/

+UINT64

+EFIAPI

+IoReadWorker (

+  IN      UINTN                     Port,

+  IN      EFI_SMM_IO_WIDTH          Width

+  )

+{

+  EFI_STATUS                        Status;

+  UINT64                            Data;

+

+  Status = gSmst->SmmIo.Io.Read (&gSmst->SmmIo, Width, Port, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Writes registers in the EFI CPU I/O space.

+

+  Writes the I/O port specified by Port with registers width and value specified by Width

+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+

+  @return The paramter of Data.

+

+**/

+UINT64

+EFIAPI

+IoWriteWorker (

+  IN      UINTN                     Port,

+  IN      EFI_SMM_IO_WIDTH          Width,

+  IN      UINT64                    Data

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gSmst->SmmIo.Io.Write (&gSmst->SmmIo, Width, Port, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Reads memory-mapped registers in the EFI system memory space.

+

+  Reads the MMIO registers specified by Address with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioReadWorker (

+  IN      UINTN                     Address,

+  IN      EFI_SMM_IO_WIDTH          Width

+  )

+{

+  EFI_STATUS                        Status;

+  UINT64                            Data;

+

+  Status = gSmst->SmmIo.Mem.Read (&gSmst->SmmIo, Width, Address, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Writes memory-mapped registers in the EFI system memory space.

+

+  Writes the MMIO registers specified by Address with registers width and value specified by Width

+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+  

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioWriteWorker (

+  IN      UINTN                     Address,

+  IN      EFI_SMM_IO_WIDTH          Width,

+  IN      UINT64                    Data

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gSmst->SmmIo.Mem.Write (&gSmst->SmmIo, Width, Address, 1, &Data);

+  ASSERT_EFI_ERROR (Status);

+

+  return Data;

+}

+

+/**

+  Reads an 8-bit I/O port.

+

+  Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+IoRead8 (

+  IN      UINTN                     Port

+  )

+{

+  return (UINT8)IoReadWorker (Port, SMM_IO_UINT8);

+}

+

+/**

+  Writes an 8-bit I/O port.

+

+  Writes the 8-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If 8-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT8

+EFIAPI

+IoWrite8 (

+  IN      UINTN                     Port,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)IoWriteWorker (Port, SMM_IO_UINT8, Value);

+}

+

+/**

+  Reads a 16-bit I/O port.

+

+  Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+IoRead16 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoReadWorker (Port, SMM_IO_UINT16);

+}

+

+/**

+  Writes a 16-bit I/O port.

+

+  Writes the 16-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If Port is not aligned on a 16-bit boundary, then ASSERT().

+

+  If 16-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT16

+EFIAPI

+IoWrite16 (

+  IN      UINTN                     Port,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Port & 1) == 0);

+  return (UINT16)IoWriteWorker (Port, SMM_IO_UINT16, Value);

+}

+

+/**

+  Reads a 32-bit I/O port.

+

+  Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+ 

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+IoRead32 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoReadWorker (Port, SMM_IO_UINT32);

+}

+

+/**

+  Writes a 32-bit I/O port.

+

+  Writes the 32-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If Port is not aligned on a 32-bit boundary, then ASSERT().

+

+  If 32-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT32

+EFIAPI

+IoWrite32 (

+  IN      UINTN                     Port,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Port & 3) == 0);

+  return (UINT32)IoWriteWorker (Port, SMM_IO_UINT32, Value);

+}

+

+/**

+  Reads a 64-bit I/O port.

+

+  Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned.

+  This function must guarantee that all I/O read and write operations are

+  serialized.

+

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+IoRead64 (

+  IN      UINTN                     Port

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoReadWorker (Port, SMM_IO_UINT64);

+}

+

+/**

+  Writes a 64-bit I/O port.

+

+  Writes the 64-bit I/O port specified by Port with the value specified by Value

+  and returns Value. This function must guarantee that all I/O read and write

+  operations are serialized.

+

+  If Port is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If 64-bit I/O port operations are not supported, then ASSERT().

+

+  @param  Port  The I/O port to write.

+  @param  Value The value to write to the I/O port.

+

+  @return The value written the I/O port.

+

+**/

+UINT64

+EFIAPI

+IoWrite64 (

+  IN      UINTN                     Port,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Port is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Port & 7) == 0);

+  return IoWriteWorker (Port, SMM_IO_UINT64, Value);

+}

+

+/**

+  Reads an 8-bit MMIO register.

+

+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT8

+EFIAPI

+MmioRead8 (

+  IN      UINTN                     Address

+  )

+{

+  return (UINT8)MmioReadWorker (Address, SMM_IO_UINT8);

+}

+

+/**

+  Writes an 8-bit MMIO register.

+

+  Writes the 8-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If 8-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT8

+EFIAPI

+MmioWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  return (UINT8)MmioWriteWorker (Address, SMM_IO_UINT8, Value);

+}

+

+/**

+  Reads a 16-bit MMIO register.

+

+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT16

+EFIAPI

+MmioRead16 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioReadWorker (Address, SMM_IO_UINT16);

+}

+

+/**

+  Writes a 16-bit MMIO register.

+

+  Writes the 16-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  If 16-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT16

+EFIAPI

+MmioWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 16-bit boundary.

+  //

+  ASSERT ((Address & 1) == 0);

+  return (UINT16)MmioWriteWorker (Address, SMM_IO_UINT16, Value);

+}

+

+/**

+  Reads a 32-bit MMIO register.

+

+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+  

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT32

+EFIAPI

+MmioRead32 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioReadWorker (Address, SMM_IO_UINT32);

+}

+

+/**

+  Writes a 32-bit MMIO register.

+

+  Writes the 32-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+ 

+  If 32-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT32

+EFIAPI

+MmioWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 32-bit boundary.

+  //

+  ASSERT ((Address & 3) == 0);

+  return (UINT32)MmioWriteWorker (Address, SMM_IO_UINT32, Value);

+}

+

+/**

+  Reads a 64-bit MMIO register.

+

+  Reads the 64-bit MMIO register specified by Address. The 64-bit read value is

+  returned. This function must guarantee that all MMIO read and write

+  operations are serialized.

+

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to read.

+

+  @return The value read.

+

+**/

+UINT64

+EFIAPI

+MmioRead64 (

+  IN      UINTN                     Address

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioReadWorker (Address, SMM_IO_UINT64);

+}

+

+/**

+  Writes a 64-bit MMIO register.

+

+  Writes the 64-bit MMIO register specified by Address with the value specified

+  by Value and returns Value. This function must guarantee that all MMIO read

+  and write operations are serialized.

+

+  If Address is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If 64-bit MMIO register operations are not supported, then ASSERT().

+

+  @param  Address The MMIO register to write.

+  @param  Value   The value to write to the MMIO register.

+

+**/

+UINT64

+EFIAPI

+MmioWrite64 (

+  IN      UINTN                     Address,

+  IN      UINT64                    Value

+  )

+{

+  //

+  // Make sure Address is aligned on a 64-bit boundary.

+  //

+  ASSERT ((Address & 7) == 0);

+  return (UINT64)MmioWriteWorker (Address, SMM_IO_UINT64, Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoLibMmioBuffer.c b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoLibMmioBuffer.c
new file mode 100644
index 0000000..8682d51
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/IoLibMmioBuffer.c
@@ -0,0 +1,417 @@
+/** @file

+  I/O Library MMIO Buffer Functions.

+

+  Copyright (c) 2009 - 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.

+

+**/

+

+#include "SmmCpuIoLibInternal.h"

+

+/**

+  Copy data from MMIO region to system memory by using 8-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 8-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioReadBuffer8 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT8       *Buffer

+  )

+{

+  UINT8   *ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ReturnBuffer = Buffer;

+

+  while (Length-- > 0) {

+    *(Buffer++) = MmioRead8 (StartAddress++);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 16-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 16-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+  

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioReadBuffer16 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT16      *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = Buffer;

+

+  while (Length > 0) {

+    *(Buffer++) = MmioRead16 (StartAddress);

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 32-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 32-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioReadBuffer32 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT32      *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = Buffer;

+

+  while (Length > 0) {

+    *(Buffer++) = MmioRead32 (StartAddress);

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from MMIO region to system memory by using 64-bit access.

+

+  Copy data from MMIO region specified by starting address StartAddress

+  to system memory specified by Buffer by using 64-bit access. The total

+  number of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+ 

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied from.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer receiving the data read.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioReadBuffer64 (

+  IN  UINTN       StartAddress,

+  IN  UINTN       Length,

+  OUT UINT64      *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = Buffer;

+

+  while (Length > 0) {

+    *(Buffer++) = MmioRead64 (StartAddress);

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 8-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 8-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the 

+                          data to write.

+

+  @return Buffer

+

+**/

+UINT8 *

+EFIAPI

+MmioWriteBuffer8 (

+  IN  UINTN         StartAddress,

+  IN  UINTN         Length,

+  IN  CONST UINT8   *Buffer

+  )

+{

+  VOID* ReturnBuffer;

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ReturnBuffer = (UINT8 *) Buffer;

+

+  while (Length-- > 0) {

+     MmioWrite8 (StartAddress++, *(Buffer++));

+  }

+

+  return ReturnBuffer;

+

+}

+

+/**

+  Copy data from system memory to MMIO region by using 16-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 16-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 16-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the 

+                          data to write.

+

+  @return Buffer

+

+**/

+UINT16 *

+EFIAPI

+MmioWriteBuffer16 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT16 *Buffer

+  )

+{

+  UINT16    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);

+

+  ReturnBuffer = (UINT16 *) Buffer;

+

+  while (Length > 0) {

+    MmioWrite16 (StartAddress, *(Buffer++));

+

+    StartAddress += sizeof (UINT16);

+    Length -= sizeof (UINT16);

+  }

+

+  return ReturnBuffer;

+}

+

+

+/**

+  Copy data from system memory to MMIO region by using 32-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 32-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 32-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the 

+                          data to write.

+

+  @return Buffer

+

+**/

+UINT32 *

+EFIAPI

+MmioWriteBuffer32 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT32 *Buffer

+  )

+{

+  UINT32    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);

+

+  ReturnBuffer = (UINT32 *) Buffer;

+

+  while (Length > 0) {

+    MmioWrite32 (StartAddress, *(Buffer++));

+

+    StartAddress += sizeof (UINT32);

+    Length -= sizeof (UINT32);

+  }

+

+  return ReturnBuffer;

+}

+

+/**

+  Copy data from system memory to MMIO region by using 64-bit access.

+

+  Copy data from system memory specified by Buffer to MMIO region specified

+  by starting address StartAddress by using 64-bit access. The total number

+  of byte to be copied is specified by Length. Buffer is returned.

+

+  If StartAddress is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().

+  If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().

+

+  If Length is not aligned on a 64-bit boundary, then ASSERT().

+

+  If Buffer is not aligned on a 64-bit boundary, then ASSERT().

+

+  @param  StartAddress    The starting address for the MMIO region to be copied to.

+  @param  Length          The size in bytes of the copy.

+  @param  Buffer          The pointer to a system memory buffer containing the 

+                          data to write.

+

+  @return Buffer

+

+**/

+UINT64 *

+EFIAPI

+MmioWriteBuffer64 (

+  IN  UINTN        StartAddress,

+  IN  UINTN        Length,

+  IN  CONST UINT64 *Buffer

+  )

+{

+  UINT64    *ReturnBuffer;

+

+  ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);

+

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));

+  ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));

+

+  ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);

+  ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);

+

+  ReturnBuffer = (UINT64 *) Buffer;

+

+  while (Length > 0) {

+    MmioWrite64 (StartAddress, *(Buffer++));

+

+    StartAddress += sizeof (UINT64);

+    Length -= sizeof (UINT64);

+  }

+

+  return ReturnBuffer;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmCpuIoLibInternal.h b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmCpuIoLibInternal.h
new file mode 100644
index 0000000..0e94b20
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmCpuIoLibInternal.h
@@ -0,0 +1,118 @@
+/** @file

+  Internal include file of SMM CPU IO Library.

+  It includes all necessary protocol/library class's header file

+  for implementation of IoLib library instance. It is included 

+  all source code of this library instance.

+  

+  Copyright (c) 2009 - 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 _SMM_CPUIO_LIB_INTERNAL_H_

+#define _SMM_CPUIO_LIB_INTERNAL_H_

+

+#include <PiSmm.h>

+#include <Protocol/SmmCpuIo2.h>

+#include <Protocol/SmmPciRootBridgeIo.h>

+#include <Library/IoLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/SmmServicesTableLib.h>

+

+

+/**

+  Reads registers in the EFI CPU I/O space.

+

+  Reads the I/O port specified by Port with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI CPU I/O space.

+

+**/

+UINT64

+EFIAPI

+IoReadWorker (

+  IN      UINTN                     Port,

+  IN      EFI_SMM_IO_WIDTH          Width

+  );

+

+/**

+  Writes registers in the EFI CPU I/O space.

+

+  Writes the I/O port specified by Port with registers width and value specified by Width

+  and Data respectively.  Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all I/O read and write operations are serialized.

+

+  @param  Port          The base address of the I/O operation.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+

+  @return The paramter of Data.

+

+**/

+UINT64

+EFIAPI

+IoWriteWorker (

+  IN      UINTN                     Port,

+  IN      EFI_SMM_IO_WIDTH          Width,

+  IN      UINT64                    Data

+  );

+

+/**

+  Reads memory-mapped registers in the EFI system memory space.

+

+  Reads the MMIO registers specified by Address with registers width specified by Width.

+  The read value is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioReadWorker (

+  IN      UINTN                     Address,

+  IN      EFI_SMM_IO_WIDTH          Width

+  );

+

+/**

+  Writes memory-mapped registers in the EFI system memory space.

+

+  Writes the MMIO registers specified by Address with registers width and value specified by Width

+  and Data respectively. Data is returned. If such operations are not supported, then ASSERT().

+  This function must guarantee that all MMIO read and write operations are serialized.

+

+  @param  Address       The MMIO register to read.

+                        The caller is responsible for aligning the Address if required.

+  @param  Width         The width of the I/O operation.

+  @param  Data          The value to write to the I/O port.

+  

+  @return Data read from registers in the EFI system memory space.

+

+**/

+UINT64

+EFIAPI

+MmioWriteWorker (

+  IN      UINTN                     Address,

+  IN      EFI_SMM_IO_WIDTH          Width,

+  IN      UINT64                    Data

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.inf b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.inf
new file mode 100644
index 0000000..628ed87
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.inf
@@ -0,0 +1,49 @@
+## @file

+# SMM Instance of I/O Library using SMM CPU I/O 2 Protocol.

+#

+# I/O Library SMM implementation that uses SMM CPU I/O 2 Protocol for I/O

+#  and MMIO operations.

+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmIoLibSmmCpuIo2

+  MODULE_UNI_FILE                = SmmIoLibSmmCpuIo2.uni

+  FILE_GUID                      = DEEEA15E-4A77-4513-BA75-71D26FEF78A1

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = IoLib|DXE_SMM_DRIVER SMM_CORE

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  IoLibMmioBuffer.c

+  SmmCpuIoLibInternal.h

+  IoHighLevel.c

+  IoLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  DebugLib

+  SmmServicesTableLib

+

+[Depex.common.DXE_SMM_DRIVER]

+  gEfiSmmCpuIo2ProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.uni b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.uni
new file mode 100644
index 0000000..e97d136
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmIoLibSmmCpuIo2/SmmIoLibSmmCpuIo2.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.c b/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.c
new file mode 100644
index 0000000..60c8adb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.c
@@ -0,0 +1,103 @@
+/** @file

+  NULL instance of SMM Library.

+

+  Copyright (c) 2009 - 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.             

+

+**/

+

+#include <Base.h>

+#include <Library/SmmLib.h>

+

+/**

+  Triggers an SMI at boot time.  

+

+  This function triggers a software SMM interrupt at boot time.

+

+**/

+VOID

+EFIAPI

+TriggerBootServiceSoftwareSmi (

+  VOID

+  )

+{

+  return;

+}

+

+

+/**

+  Triggers an SMI at run time.  

+

+  This function triggers a software SMM interrupt at run time.

+

+**/

+VOID

+EFIAPI

+TriggerRuntimeSoftwareSmi (

+  VOID

+  )

+{

+  return;

+}

+

+

+

+/**

+  Test if a boot time software SMI happened.  

+

+  This function tests if a software SMM interrupt happened. If a software SMM 

+  interrupt happened and it was triggered at boot time, it returns TRUE. Otherwise, 

+  it returns FALSE.

+

+  @retval TRUE   A software SMI triggered at boot time happened.

+  @retval FALSE  No software SMI happened or the software SMI was triggered at run time.

+

+**/

+BOOLEAN

+EFIAPI

+IsBootServiceSoftwareSmi (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+

+/**

+  Test if a run time software SMI happened.  

+

+  This function tests if a software SMM interrupt happened. If a software SMM 

+  interrupt happened and it was triggered at run time, it returns TRUE. Otherwise, 

+  it returns FALSE.

+

+  @retval TRUE   A software SMI triggered at run time happened.

+  @retval FALSE  No software SMI happened or the software SMI was triggered at boot time.

+

+**/

+BOOLEAN

+EFIAPI

+IsRuntimeSoftwareSmi (

+  VOID

+  )

+{

+  return FALSE;

+}

+

+/**

+  Clear APM SMI Status Bit; Set the EOS bit. 

+  

+**/

+VOID

+EFIAPI

+ClearSmi (

+  VOID

+  )

+{

+  return;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.inf b/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.inf
new file mode 100644
index 0000000..597b884
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.inf
@@ -0,0 +1,37 @@
+## @file

+# NULL instance of SMM Library.

+#

+#  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmLibNull

+  MODULE_UNI_FILE                = SmmLibNull.uni

+  FILE_GUID                      = DDADFC93-FBC5-4389-B20F-EC99E4A6AE52

+  MODULE_TYPE                    = BASE

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmmLib

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  SmmLibNull.c

+  

+

+[Packages]

+  MdePkg/MdePkg.dec

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.uni b/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.uni
new file mode 100644
index 0000000..2bfaede
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmLibNull/SmmLibNull.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.c b/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.c
new file mode 100644
index 0000000..21f67d2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.c
@@ -0,0 +1,343 @@
+/** @file

+  Instance of SMM memory check library.

+

+  SMM memory check library library implementation. This library consumes SMM_ACCESS2_PROTOCOL

+  to get SMRAM information. In order to use this library instance, the platform should produce

+  all SMRAM range via SMM_ACCESS2_PROTOCOL, including the range for firmware (like SMM Core

+  and SMM driver) and/or specific dedicated hardware.

+

+  Copyright (c) 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 <PiSmm.h>

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/SmmServicesTableLib.h>

+#include <Library/HobLib.h>

+#include <Protocol/SmmAccess2.h>

+

+EFI_SMRAM_DESCRIPTOR *mSmmMemLibInternalSmramRanges;

+UINTN                mSmmMemLibInternalSmramCount;

+

+//

+// Maximum support address used to check input buffer

+//

+EFI_PHYSICAL_ADDRESS  mSmmMemLibInternalMaximumSupportAddress = 0;

+

+/**

+  Caculate and save the maximum support address.

+

+**/

+VOID

+SmmMemLibInternalCaculateMaximumSupportAddress (

+  VOID

+  )

+{

+  VOID         *Hob;

+  UINT32       RegEax;

+  UINT8        PhysicalAddressBits;

+

+  //

+  // Get physical address bits supported.

+  //

+  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);

+  if (Hob != NULL) {

+    PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;

+  } else {

+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);

+    if (RegEax >= 0x80000008) {

+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);

+      PhysicalAddressBits = (UINT8) RegEax;

+    } else {

+      PhysicalAddressBits = 36;

+    }

+  }

+  //

+  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.

+  //

+  ASSERT (PhysicalAddressBits <= 52);

+  if (PhysicalAddressBits > 48) {

+    PhysicalAddressBits = 48;

+  }

+  

+  //

+  // Save the maximum support address in one global variable  

+  //

+  mSmmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);

+  DEBUG ((EFI_D_INFO, "mSmmMemLibInternalMaximumSupportAddress = 0x%lx\n", mSmmMemLibInternalMaximumSupportAddress));

+}

+

+/**

+  This function check if the buffer is valid per processor architecture and not overlap with SMRAM.

+

+  @param Buffer  The buffer start address to be checked.

+  @param Length  The buffer length to be checked.

+

+  @retval TRUE  This buffer is valid per processor architecture and not overlap with SMRAM.

+  @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM.

+**/

+BOOLEAN

+EFIAPI

+SmmIsBufferOutsideSmmValid (

+  IN EFI_PHYSICAL_ADDRESS  Buffer,

+  IN UINT64                Length

+  )

+{

+  UINTN  Index;

+  

+  //

+  // Check override.

+  // NOTE: (B:0->L:4G) is invalid for IA32, but (B:1->L:4G-1)/(B:4G-1->L:1) is valid.

+  //

+  if ((Length > mSmmMemLibInternalMaximumSupportAddress) ||

+      (Buffer > mSmmMemLibInternalMaximumSupportAddress) ||

+      ((Length != 0) && (Buffer > (mSmmMemLibInternalMaximumSupportAddress - (Length - 1)))) ) {

+    //

+    // Overflow happen

+    //

+    DEBUG ((

+      EFI_D_ERROR,

+      "SmmIsBufferOutsideSmmValid: Overflow: Buffer (0x%lx) - Length (0x%lx), MaximumSupportAddress (0x%lx)\n",

+      Buffer,

+      Length,

+      mSmmMemLibInternalMaximumSupportAddress

+      ));

+    return FALSE;

+  }

+  

+  for (Index = 0; Index < mSmmMemLibInternalSmramCount; Index ++) {

+    if (((Buffer >= mSmmMemLibInternalSmramRanges[Index].CpuStart) && (Buffer < mSmmMemLibInternalSmramRanges[Index].CpuStart + mSmmMemLibInternalSmramRanges[Index].PhysicalSize)) ||

+        ((mSmmMemLibInternalSmramRanges[Index].CpuStart >= Buffer) && (mSmmMemLibInternalSmramRanges[Index].CpuStart < Buffer + Length))) {

+      DEBUG ((

+        EFI_D_ERROR,

+        "SmmIsBufferOutsideSmmValid: Overlap: Buffer (0x%lx) - Length (0x%lx), ",

+        Buffer,

+        Length

+        ));

+      DEBUG ((

+        EFI_D_ERROR,

+        "CpuStart (0x%lx) - PhysicalSize (0x%lx)\n",

+        mSmmMemLibInternalSmramRanges[Index].CpuStart,

+        mSmmMemLibInternalSmramRanges[Index].PhysicalSize

+        ));

+      return FALSE;

+    }

+  }

+

+  return TRUE;

+}

+

+/**

+  Copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).

+

+  This function copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).

+  It checks if source buffer is valid per processor architecture and not overlap with SMRAM.

+  If the check passes, it copies memory and returns EFI_SUCCESS.

+  If the check fails, it return EFI_SECURITY_VIOLATION.

+  The implementation must be reentrant.

+

+  @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.

+

+  @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with SMRAM.

+  @retval EFI_SUCCESS            Memory is copied.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmCopyMemToSmram (

+  OUT VOID       *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {

+    DEBUG ((EFI_D_ERROR, "SmmCopyMemToSmram: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));

+    return EFI_SECURITY_VIOLATION;

+  }

+  CopyMem (DestinationBuffer, SourceBuffer, Length);

+  return EFI_SUCCESS;

+}

+

+/**

+  Copies a source buffer (SMRAM) to a destination buffer (NON-SMRAM).

+

+  This function copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).

+  It checks if destination buffer is valid per processor architecture and not overlap with SMRAM.

+  If the check passes, it copies memory and returns EFI_SUCCESS.

+  If the check fails, it returns EFI_SECURITY_VIOLATION.

+  The implementation must be reentrant.

+  

+  @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.

+

+  @retval EFI_SECURITY_VIOLATION The DesinationBuffer is invalid per processor architecture or overlap with SMRAM.

+  @retval EFI_SUCCESS            Memory is copied.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmCopyMemFromSmram (

+  OUT VOID       *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {

+    DEBUG ((EFI_D_ERROR, "SmmCopyMemFromSmram: Security Violation: Destination (0x%x), Length (0x%x)\n", DestinationBuffer, Length));

+    return EFI_SECURITY_VIOLATION;

+  }

+  CopyMem (DestinationBuffer, SourceBuffer, Length);

+  return EFI_SUCCESS;

+}

+

+/**

+  Copies a source buffer (NON-SMRAM) to a destination buffer (NON-SMRAM).

+

+  This function copies a source buffer (non-SMRAM) to a destination buffer (SMRAM).

+  It checks if source buffer and destination buffer are valid per processor architecture and not overlap with SMRAM.

+  If the check passes, it copies memory and returns EFI_SUCCESS.

+  If the check fails, it returns EFI_SECURITY_VIOLATION.

+  The implementation must be reentrant, and it must handle the case where source buffer overlaps destination buffer.

+  

+  @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.

+

+  @retval EFI_SECURITY_VIOLATION The DesinationBuffer is invalid per processor architecture or overlap with SMRAM.

+  @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with SMRAM.

+  @retval EFI_SUCCESS            Memory is copied.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmCopyMem (

+  OUT VOID       *DestinationBuffer,

+  IN CONST VOID  *SourceBuffer,

+  IN UINTN       Length

+  )

+{

+  if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {

+    DEBUG ((EFI_D_ERROR, "SmmCopyMem: Security Violation: Destination (0x%x), Length (0x%x)\n", DestinationBuffer, Length));

+    return EFI_SECURITY_VIOLATION;

+  }

+  if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {

+    DEBUG ((EFI_D_ERROR, "SmmCopyMem: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));

+    return EFI_SECURITY_VIOLATION;

+  }

+  CopyMem (DestinationBuffer, SourceBuffer, Length);

+  return EFI_SUCCESS;

+}

+

+/**

+  Fills a target buffer (NON-SMRAM) with a byte value.

+

+  This function fills a target buffer (non-SMRAM) with a byte value.

+  It checks if target buffer is valid per processor architecture and not overlap with SMRAM.

+  If the check passes, it fills memory and returns EFI_SUCCESS.

+  If the check fails, it returns EFI_SECURITY_VIOLATION.

+  

+  @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.

+  

+  @retval EFI_SECURITY_VIOLATION The Buffer is invalid per processor architecture or overlap with SMRAM.

+  @retval EFI_SUCCESS            Memory is set.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmSetMem (

+  OUT VOID  *Buffer,

+  IN UINTN  Length,

+  IN UINT8  Value

+  )

+{

+  if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Length)) {

+    DEBUG ((EFI_D_ERROR, "SmmSetMem: Security Violation: Source (0x%x), Length (0x%x)\n", Buffer, Length));

+    return EFI_SECURITY_VIOLATION;

+  }

+  SetMem (Buffer, Length, Value);

+  return EFI_SUCCESS;

+}

+

+/**

+  The constructor function initializes the Smm Mem library

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmMemLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                    Status;

+  EFI_SMM_ACCESS2_PROTOCOL      *SmmAccess;

+  UINTN                         Size;

+  

+  //

+  // Get SMRAM information

+  //

+  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);

+  ASSERT_EFI_ERROR (Status);

+

+  Size = 0;

+  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);

+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

+

+  mSmmMemLibInternalSmramRanges = AllocatePool (Size);

+  ASSERT (mSmmMemLibInternalSmramRanges != NULL);

+

+  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmMemLibInternalSmramRanges);

+  ASSERT_EFI_ERROR (Status);

+

+  mSmmMemLibInternalSmramCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);

+

+  //

+  // Caculate and save maximum support address

+  //

+  SmmMemLibInternalCaculateMaximumSupportAddress ();

+

+  return EFI_SUCCESS;

+}

+

+/**

+  The destructor function frees resource used in the Smm Mem library

+

+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.

+  @param[in]  SystemTable   A pointer to the EFI System Table.

+

+  @retval     EFI_SUCCESS   The deconstructor always returns EFI_SUCCESS.

+**/

+EFI_STATUS

+EFIAPI

+SmmMemLibDestructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  FreePool (mSmmMemLibInternalSmramRanges);

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.inf b/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.inf
new file mode 100644
index 0000000..5531423
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.inf
@@ -0,0 +1,52 @@
+## @file

+#  Instance of SMM memory check library.

+#

+#  SMM memory check library library implementation. This library consumes SMM_ACCESS2_PROTOCOL

+#  to get SMRAM information. In order to use this library instance, the platform should produce

+#  all SMRAM range via SMM_ACCESS2_PROTOCOL, including the range for firmware (like SMM Core

+#  and SMM driver) and/or specific dedicated hardware.

+#  

+#  Copyright (c) 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.

+#  

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmMemLib

+  MODULE_UNI_FILE                = SmmMemLib.uni

+  FILE_GUID                      = 7F23F839-C81C-4B89-8132-69746FCBCE52

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmmMemLib|DXE_SMM_DRIVER SMM_CORE

+  CONSTRUCTOR                    = SmmMemLibConstructor

+  DESTRUCTOR                     = SmmMemLibDestructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  SmmMemLib.c

+  

+[Packages]

+  MdePkg/MdePkg.dec

+  

+[LibraryClasses]

+  SmmServicesTableLib

+  UefiBootServicesTableLib

+  DebugLib

+  BaseMemoryLib

+  HobLib

+  MemoryAllocationLib

+

+[Protocols]

+  gEfiSmmAccess2ProtocolGuid    ## SOMETIMES_CONSUMES

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.uni b/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.uni
new file mode 100644
index 0000000..7fd7869
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmMemLib/SmmMemLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c b/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c
new file mode 100644
index 0000000..49d7a57
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c
@@ -0,0 +1,981 @@
+/** @file

+  Support routines for memory allocation routines based 

+  on SMM Services Table services for SMM phase drivers.

+  

+  The PI System Management Mode Core Interface Specification only allows the use

+  of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory 

+  allocations through the SMM Services Table.  The functions in the Memory 

+  Allocation Library use EfiBootServicesData as the default memory allocation

+  type.  For this SMM specific instance of the Memory Allocation Library, 

+  EfiRuntimeServicesData is used as the default memory type for all allocations.

+  In addition, allocation for the Reserved memory types are not supported and 

+  will always return NULL.

+

+  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.             

+

+**/

+

+#include <PiSmm.h>

+

+#include <Protocol/SmmAccess2.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/SmmServicesTableLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+

+EFI_SMRAM_DESCRIPTOR  *mSmramRanges;

+UINTN                 mSmramRangeCount;

+

+/**

+  The constructor function caches SMRAM ranges that are present in the system.

+    

+  It will ASSERT() if SMM Access2 Protocol doesn't exist.

+  It will ASSERT() if SMRAM ranges can't be got.

+  It will ASSERT() if Resource can't be allocated for cache SMRAM range. 

+  It will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmMemoryAllocationLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                Status;

+  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;

+  UINTN                     Size;

+

+  //

+  // Locate SMM Access2 Protocol

+  //

+  Status = gBS->LocateProtocol (

+                  &gEfiSmmAccess2ProtocolGuid, 

+                  NULL, 

+                  (VOID **)&SmmAccess

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Get SMRAM range information

+  //

+  Size = 0;

+  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);

+  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

+

+  mSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);

+  ASSERT (mSmramRanges != NULL);

+

+  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);

+  ASSERT_EFI_ERROR (Status);

+

+  mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  If SMM driver exits with an error, it must call this routine 

+  to free the allocated resource before the exiting.

+

+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.

+  @param[in]  SystemTable   A pointer to the EFI System Table.

+

+  @retval     EFI_SUCCESS   The deconstructor always returns EFI_SUCCESS.

+**/

+EFI_STATUS

+EFIAPI

+SmmMemoryAllocationLibDestructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  FreePool (mSmramRanges);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Check whether the start address of buffer is within any of the SMRAM ranges.

+

+  @param[in]  Buffer   The pointer to the buffer to be checked.

+

+  @retval     TURE     The buffer is in SMRAM ranges.

+  @retval     FALSE    The buffer is out of SMRAM ranges.

+**/

+BOOLEAN

+EFIAPI

+BufferInSmram (

+  IN VOID *Buffer

+  )

+{

+  UINTN  Index;

+

+  for (Index = 0; Index < mSmramRangeCount; Index ++) {

+    if (((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer >= mSmramRanges[Index].CpuStart) && 

+        ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) {

+      return TRUE;

+    }

+  }

+

+  return FALSE;

+}

+

+/**

+  Allocates one or more 4KB pages of a certain memory type.

+

+  Allocates the number of 4KB pages of a certain memory type 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  MemoryType            The type of memory to allocate.

+  @param  Pages                 The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory; 

+

+  if (Pages == 0) {

+    return NULL;

+  }

+

+  Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+  return (VOID *) (UINTN) Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocatePages (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocatePages (EfiRuntimeServicesData, 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

+  )

+{

+  return NULL;

+}

+

+/**

+  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                The 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

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (Pages != 0);

+  if (BufferInSmram (Buffer)) {

+    //

+    // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.

+    // So, gSmst->SmmFreePages() service is used to free it.

+    //

+    Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  } else {

+    //

+    // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.

+    // So, gBS->FreePages() service is used to free it.

+    //

+    Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  }

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates one or more 4KB pages of a certain memory type at a specified alignment.

+

+  Allocates the number of 4KB pages specified by Pages of a certain memory type 

+  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  MemoryType            The type of memory to allocate.

+  @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 *

+InternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory;

+  UINTN                 AlignedMemory;

+  UINTN                 AlignmentMask;

+  UINTN                 UnalignedPages;

+  UINTN                 RealPages;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+ 

+  if (Pages == 0) {

+    return NULL;

+  }

+  if (Alignment > EFI_PAGE_SIZE) {

+    //

+    // Caculate the total number of pages since alignment is larger than page size.

+    //

+    AlignmentMask  = Alignment - 1;

+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);

+    //

+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.

+    //

+    ASSERT (RealPages > Pages);

+ 

+    Status         = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;

+    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);

+    if (UnalignedPages > 0) {

+      //

+      // Free first unaligned page(s).

+      //

+      Status = gSmst->SmmFreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));

+    UnalignedPages = RealPages - Pages - UnalignedPages;

+    if (UnalignedPages > 0) {

+      //

+      // Free last unaligned page(s).

+      //

+      Status = gSmst->SmmFreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+  } else {

+    //

+    // Do not over-allocate pages in this case.

+    //

+    Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = (UINTN) Memory;

+  }

+  return (VOID *) AlignedMemory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, 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

+  )

+{

+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, 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

+  )

+{

+  return NULL;

+}

+

+/**

+  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                The 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

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (Pages != 0);

+  if (BufferInSmram (Buffer)) {

+    //

+    // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service.

+    // So, gSmst->SmmFreePages() service is used to free it.

+    //

+    Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  } else {

+    //

+    // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.

+    // So, gBS->FreePages() service is used to free it.

+    //

+    Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  }

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates a buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type 

+  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  MemoryType            The type of memory to allocate.

+  @param  AllocationSize        The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            AllocationSize

+  )

+{

+  EFI_STATUS  Status;

+  VOID        *Memory;

+

+  Status = gSmst->SmmAllocatePool (MemoryType, AllocationSize, &Memory);

+  if (EFI_ERROR (Status)) {

+    Memory = NULL;

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocatePool (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocatePool (EfiRuntimeServicesData, 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

+  )

+{

+  return NULL;

+}

+

+/**

+  Allocates and zeros a buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type, 

+  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  PoolType              The type of memory to allocate.

+  @param  AllocationSize        The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize

+  ) 

+{

+  VOID  *Memory;

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateZeroPool (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocateZeroPool (EfiRuntimeServicesData, 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

+  )

+{

+  return NULL;

+}

+

+/**

+  Copies a buffer to an allocated buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type, 

+  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  PoolType              The type of pool to allocate.

+  @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 *

+InternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  ) 

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+} 

+

+/**

+  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

+  )

+{

+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, 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

+  )

+{

+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, 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

+  )

+{

+  return NULL;

+}

+

+/**

+  Reallocates a buffer of a specified memory type.

+

+  Allocates and zeros the number bytes specified by NewSize from memory of the type

+  specified by PoolType.  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  PoolType       The type of pool to allocate.

+  @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 *

+InternalReallocatePool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            OldSize,

+  IN UINTN            NewSize,

+  IN VOID             *OldBuffer  OPTIONAL

+  )

+{

+  VOID  *NewBuffer;

+

+  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);

+  if (NewBuffer != NULL && OldBuffer != NULL) {

+    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));

+    FreePool (OldBuffer);

+  }

+  return NewBuffer;

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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

+  )

+{

+  return NULL;

+}

+

+/**

+  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                The pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreePool (

+  IN VOID   *Buffer

+  )

+{

+  EFI_STATUS    Status;

+

+  if (BufferInSmram (Buffer)) {

+    //

+    // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.

+    // So, gSmst->SmmFreePool() service is used to free it.

+    //

+    Status = gSmst->SmmFreePool (Buffer);

+  } else {

+    //

+    // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.

+    // So, gBS->FreePool() service is used to free it.

+    //

+    Status = gBS->FreePool (Buffer);

+  }

+  ASSERT_EFI_ERROR (Status);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf b/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
new file mode 100644
index 0000000..8210c97
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
@@ -0,0 +1,50 @@
+## @file

+# Instance of Memory Allocation Library using SMM Services Table.

+#

+# Memory Allocation Library that uses services from the SMM Services Table to 

+# allocate and free memory.

+#

+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>

+# This program and the accompanying materials

+# are licensed and made available under the terms and conditions of the BSD License

+# which accompanies this distribution. The full text of the license may be found at

+# http://opensource.org/licenses/bsd-license.php.

+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmMemoryAllocationLib

+  MODULE_UNI_FILE                = SmmMemoryAllocationLib.uni

+  FILE_GUID                      = 4DF30A5D-D5B0-4f85-80ED-6B16CD343C8E

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+  LIBRARY_CLASS                  = MemoryAllocationLib|DXE_SMM_DRIVER 

+  CONSTRUCTOR                    = SmmMemoryAllocationLibConstructor

+  DESTRUCTOR                     = SmmMemoryAllocationLibDestructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  MemoryAllocationLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseMemoryLib

+  SmmServicesTableLib

+  UefiBootServicesTableLib

+

+[Protocols]

+  gEfiSmmAccess2ProtocolGuid    ## CONSUMES  

+

+[Depex]

+  gEfiSmmAccess2ProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.uni b/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.uni
new file mode 100644
index 0000000..0f7d169
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c
new file mode 100644
index 0000000..0b94aeb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/PciLib.c
@@ -0,0 +1,1434 @@
+/** @file

+  PCI Library using SMM PCI Root Bridge I/O Protocol.

+

+  Copyright (c) 2009 - 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.

+

+**/

+#include <PiSmm.h>

+#include <Protocol/SmmPciRootBridgeIo.h>

+#include <Library/PciLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/SmmServicesTableLib.h>

+

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \

+  ASSERT (((A) & (~0xfffffff | (M))) == 0)

+

+/**

+  Translate PCI Lib address into format of PCI Root Bridge I/O Protocol.

+

+  @param  A  The address that encodes the PCI Bus, Device, Function and

+             Register.

+

+**/

+#define PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS(A) \

+  ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))

+

+//

+// Global varible to cache pointer to PCI Root Bridge I/O protocol.

+//

+EFI_SMM_PCI_ROOT_BRIDGE_IO_PROTOCOL      *mSmmPciRootBridgeIo = NULL; 

+

+/**

+  The constructor function caches the pointer to PCI Root Bridge I/O protocol.

+  

+  The constructor function locates PCI Root Bridge I/O protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PciLibConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  

+  Status = gSmst->SmmLocateProtocol (&gEfiSmmPciRootBridgeIoProtocolGuid, NULL, (VOID**) &mSmmPciRootBridgeIo);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mSmmPciRootBridgeIo != NULL);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+SmmPciLibPciRootBridgeIoReadWorker (

+  IN    UINTN                                  Address,

+  IN    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width

+  )

+{

+  UINT32  Data;

+

+  mSmmPciRootBridgeIo->Pci.Read (

+                          mSmmPciRootBridgeIo,

+                          Width,

+                          PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),

+                          1,

+                          &Data

+                          );

+

+  return Data;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+SmmPciLibPciRootBridgeIoWriteWorker (

+  IN    UINTN                                  Address,

+  IN    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN    UINT32                                 Data

+  )

+{

+  mSmmPciRootBridgeIo->Pci.Write (

+                          mSmmPciRootBridgeIo,

+                          Width,

+                          PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),

+                          1,

+                          &Data

+                          );

+  return Data;

+}

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration registers 

+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) SmmPciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) SmmPciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8) (PciRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (Address, (UINT8) (PciRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8) ((PciRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) SmmPciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) SmmPciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16) (PciRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (Address, (UINT16) (PciRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16) ((PciRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return SmmPciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return SmmPciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 (Buffer, PciRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 (Buffer, PciRead32 (StartAddress));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 (Buffer, PciRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciWrite32 (StartAddress, ReadUnaligned32 (Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/SmmPciLibPciRootBridgeIo.inf b/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/SmmPciLibPciRootBridgeIo.inf
new file mode 100644
index 0000000..a74d48f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/SmmPciLibPciRootBridgeIo.inf
@@ -0,0 +1,55 @@
+## @file

+# PCI Library that layers on top of the SMM PCI Root Bridge I/O Protocol.

+#

+# This library produces the APIs from the PCI Library and implements these APIs

+#  by calling into SMM PCI Root Bridge I/O Protocol. SMM PCI Root Bridge I/O Protocol is

+#  typically produced by a chipset specific SMM driver.

+#  This library binds to the first SMM PCI Root Bridge I/O Protocol in the platform. As a result,

+#  it should only be used on platforms that contain a single PCI root bridge.

+#

+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmPciLibPciRootBridgeIo

+  MODULE_UNI_FILE                = SmmPciLibPciRootBridgeIo.uni

+  FILE_GUID                      = F6994CBA-2351-4ebc-A2DA-20BAC2FE2CF3

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciLib|DXE_SMM_DRIVER SMM_CORE

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+  CONSTRUCTOR                    = PciLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  PciLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  SmmServicesTableLib

+  DebugLib

+

+[Protocols]

+  gEfiSmmPciRootBridgeIoProtocolGuid               ## CONSUMES

+  

+[Depex.common.DXE_SMM_DRIVER]

+  gEfiSmmPciRootBridgeIoProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/SmmPciLibPciRootBridgeIo.uni b/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/SmmPciLibPciRootBridgeIo.uni
new file mode 100644
index 0000000..3b0a31c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmPciLibPciRootBridgeIo/SmmPciLibPciRootBridgeIo.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.c b/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.c
new file mode 100644
index 0000000..b6db317
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.c
@@ -0,0 +1,1183 @@
+/** @file

+  SMM Periodic SMI Library.

+

+  Copyright (c) 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

+  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 <PiSmm.h>

+

+#include <Protocol/SmmPeriodicTimerDispatch2.h>

+

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/SynchronizationLib.h>

+#include <Library/DebugLib.h>

+#include <Library/TimerLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/SmmServicesTableLib.h>

+

+#include <Library/SmmPeriodicSmiLib.h>

+

+///

+/// Define the number of periodic SMI handler entries that should be allocated to the list

+/// of free periodic SMI handlers when the list of free periodic SMI handlers is empty.

+///

+#define PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE  0x08

+

+///

+/// Signature for a PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT structure

+///

+#define PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE  SIGNATURE_32 ('P', 'S', 'M', 'I')

+

+///

+/// Structure that contains state information for an enabled periodic SMI handler

+///

+typedef struct {

+  ///

+  /// Signature value that must be set to PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE

+  ///

+  UINT32                                   Signature;

+  ///

+  /// The link entry to be inserted to the list of periodic SMI handlers.

+  ///

+  LIST_ENTRY                               Link;

+  ///

+  /// The dispatch function to called to invoke an enabled periodic SMI handler.

+  ///

+  PERIODIC_SMI_LIBRARY_HANDLER             DispatchFunction;

+  ///

+  /// The context to pass into DispatchFunction

+  ///

+  VOID                                     *Context;

+  ///

+  /// The tick period in 100 ns units that DispatchFunction should be called.

+  ///

+  UINT64                                   TickPeriod;

+  ///

+  /// The Cpu number that is required to execute DispatchFunction.  If Cpu is 

+  /// set to PERIODIC_SMI_LIBRARY_ANY_CPU, then DispatchFunction may be executed 

+  /// on any CPU.

+  ///

+  UINTN                                    Cpu;

+  ///

+  /// The size, in bytes, of the stack allocated for a periodic SMI handler.  

+  /// This value must be a multiple of EFI_PAGE_SIZE.

+  ///

+  UINTN                                    StackSize;

+  ///

+  /// A pointer to the stack allocated using AllocatePages().  This field will

+  /// be NULL if StackSize is 0.

+  ///

+  VOID                                     *Stack;

+  ///

+  /// Spin lock used to wait for an AP to complete the execution of a periodic SMI handler

+  ///

+  SPIN_LOCK                                DispatchLock;

+  ///

+  /// The rate in Hz of the performance counter that is used to measure the 

+  /// amount of time that a periodic SMI handler executes.

+  ///

+  UINT64                                   PerfomanceCounterRate;

+  ///

+  /// The start count value of the performance counter that is used to measure 

+  /// the amount of time that a periodic SMI handler executes.

+  ///

+  UINT64                                   PerfomanceCounterStartValue;

+  ///

+  /// The end count value of the performance counter that is used to measure 

+  /// the amount of time that a periodic SMI handler executes.

+  ///

+  UINT64                                   PerfomanceCounterEndValue;

+  ///

+  /// The context record passed into the Register() function of the SMM Periodic 

+  /// Timer Dispatch Protocol when a periodic SMI handler is enabled.

+  ///

+  EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT  RegisterContext;

+  ///

+  /// The handle returned from the Register() function of the SMM Periodic 

+  /// Timer Dispatch Protocol when a periodic SMI handler is enabled.

+  ///

+  EFI_HANDLE                               DispatchHandle;

+  ///

+  /// The total number of performance counter ticks that the periodic SMI handler

+  /// has been executing in its current invocation.

+  ///

+  UINT64                                   DispatchTotalTime;

+  ///

+  /// The performance counter value that was captured the last time that the 

+  /// periodic SMI handler called PeriodcSmiExecutionTime().  This allows the

+  /// time value returned by PeriodcSmiExecutionTime() to be accurate even when

+  /// the performance counter rolls over.

+  ///

+  UINT64                                   DispatchCheckPointTime;

+  ///

+  /// Buffer used to save the context when control is transfer from this library

+  /// to an enabled periodic SMI handler.  This saved context is used when the 

+  /// periodic SMI handler exits or yields.  

+  ///

+  BASE_LIBRARY_JUMP_BUFFER                 DispatchJumpBuffer;

+  ///

+  /// Flag that is set to TRUE when a periodic SMI handler requests to yield 

+  /// using PeriodicSmiYield().  When this flag IS TRUE, YieldJumpBuffer is 

+  /// valid.  When this flag is FALSE, YieldJumpBuffer is not valid.

+  ///

+  BOOLEAN                                  YieldFlag;

+  ///

+  /// Buffer used to save the context when a periodic SMI handler requests to 

+  /// yield using PeriodicSmiYield().  This context is used to resume the 

+  /// execution of a periodic SMI handler the next time control is transferd

+  /// to the periodic SMI handler that yielded.

+  ///

+  BASE_LIBRARY_JUMP_BUFFER                 YieldJumpBuffer;

+  ///

+  /// The amount of time, in 100 ns units, that have elapsed since the last

+  /// time the periodic SMI handler was invoked.

+  ///

+  UINT64                                   ElapsedTime;

+} PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT;

+

+/**

+ Macro that returns a pointer to a PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT 

+ structure based on a pointer to a RegisterContext field.

+

+**/

+#define PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_REGISTER_CONTEXT(a) \

+  CR (                                                                \

+    a,                                                                \

+    PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT,                             \

+    RegisterContext,                                                  \

+    PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE                    \

+    )

+

+/**

+ Macro that returns a pointer to a PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT 

+ structure based on a pointer to a Link field.

+

+**/

+#define PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK(a)             \

+  CR (                                                                \

+    a,                                                                \

+    PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT,                             \

+    Link,                                                             \

+    PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE                    \

+    )

+

+///

+/// Pointer to the SMM Periodic Timer Disatch Protocol that was located in the constuctor.

+///

+EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL  *gSmmPeriodicTimerDispatch2           = NULL;

+

+///

+/// Pointer to a table of supported periodic SMI tick periods in 100 ns units 

+/// sorted from largest to smallest terminated by a tick period value of 0.

+/// This table is allocated using AllocatePool() in the constructor and filled 

+/// in based on the values returned from the SMM Periodic Timer Dispatch 2 Protocol 

+/// function GetNextShorterInterval().

+///

+UINT64                                     *gSmiTickPeriodTable                  = NULL;

+

+///

+/// Linked list of free periodic SMI handlers that this library can use.

+///

+LIST_ENTRY                                 gFreePeriodicSmiLibraryHandlers       =

+                                           INITIALIZE_LIST_HEAD_VARIABLE (gFreePeriodicSmiLibraryHandlers);

+

+///

+/// Linked list of periodic SMI handlers that this library is currently managing.

+///

+LIST_ENTRY                                 gPeriodicSmiLibraryHandlers           =

+                                           INITIALIZE_LIST_HEAD_VARIABLE (gPeriodicSmiLibraryHandlers);

+

+///

+/// Pointer to the periodic SMI handler that is currently being executed.

+/// Is set to NULL if no periodic SMI handler is currently being executed.

+///

+PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT       *gActivePeriodicSmiLibraryHandler     = NULL;

+

+/**

+  Internal worker function that returns a pointer to the 

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT structure associated with the periodic 

+  SMI handler that is currently being executed.  If a periodic SMI handler is 

+  not currently being executed, the NULL is returned.

+  

+  @retval  NULL   A periodic SMI handler is not currently being executed.

+  @retval  other  Pointer to the PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT

+                  associated with the active periodic SMI handler.

+  

+**/

+PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *

+GetActivePeriodicSmiLibraryHandler (

+  VOID

+  )

+{

+  return gActivePeriodicSmiLibraryHandler;

+}

+

+/**

+  Internal worker function that returns a pointer to the 

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT structure associated with the 

+  DispatchHandle that was returned when the periodic SMI handler was enabled

+  with PeriodicSmiEnable().  If DispatchHandle is NULL, then the active 

+  periodic SMI handler is returned.  If DispatchHandle is NULL and there is

+  no active periodic SMI handler, then NULL is returned.

+  

+  @param[in] DispatchHandle  DispatchHandle that was returned when the periodic 

+                             SMI handler was enabled with PeriodicSmiEnable().  

+                             This is an optional parameter that may be NULL.

+                             If this parameter is NULL, then the active periodic

+                             SMI handler is returned.

+  

+  @retval  NULL   DispatchHandle is NULL and there is no active periodic SMI 

+                  handler.

+  @retval  NULL   DispatchHandle does not match any of the periodic SMI handlers

+                  that have been enabled with PeriodicSmiEnable().

+  @retval  other  Pointer to the PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT

+                  associated with the DispatchHandle.

+  

+**/

+PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *

+LookupPeriodicSmiLibraryHandler (

+  IN EFI_HANDLE                         DispatchHandle    OPTIONAL

+  )

+{

+  LIST_ENTRY                            *Link;

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+

+  //

+  // If DispatchHandle is NULL, then return the active periodic SMI handler

+  //

+  if (DispatchHandle == NULL) {

+    return GetActivePeriodicSmiLibraryHandler ();

+  }

+

+  //

+  // Search the periodic SMI handler entries for a a matching DispatchHandle

+  //

+  for ( Link = GetFirstNode (&gPeriodicSmiLibraryHandlers)

+      ; !IsNull (&gPeriodicSmiLibraryHandlers, Link)

+      ; Link = GetNextNode (&gPeriodicSmiLibraryHandlers, Link)

+      ) {

+    PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (Link);

+

+    if (PeriodicSmiLibraryHandler->DispatchHandle == DispatchHandle) {

+      return PeriodicSmiLibraryHandler;

+    }

+  }

+  

+  //

+  // No entries match DispatchHandle, so return NULL

+  //

+  return NULL;

+}

+

+/**

+  Internal worker function that sets that active periodic SMI handler based on 

+  the Context used when the periodic SMI handler was registered with the 

+  SMM Periodic Timer Dispatch 2 Protocol.  If Context is NULL, then the 

+  state is updated to show that there is not active periodic SMI handler.

+  A pointer to the active PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT structure 

+  is returned.

+  

+  @retval  NULL   Context is NULL.

+  @retval  other  Pointer to the PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT

+                  associated with Context.

+  

+**/

+PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *

+SetActivePeriodicSmiLibraryHandler (

+  IN CONST VOID  *Context  OPTIONAL

+  )

+{

+  if (Context == NULL) {

+    gActivePeriodicSmiLibraryHandler = NULL;

+  } else {

+    gActivePeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_REGISTER_CONTEXT (Context);

+  }

+  return gActivePeriodicSmiLibraryHandler;

+}

+

+/**

+  Internal worker function that moves the specified periodic SMI handler from the

+  list of managed periodic SMI handlers to the list of free periodic SMI handlers.

+

+  @param[in] PeriodicSmiLibraryHandler  Pointer to the periodic SMI handler to be reclaimed.

+**/

+VOID

+ReclaimPeriodicSmiLibraryHandler (

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT     *PeriodicSmiLibraryHandler

+  )

+{

+  ASSERT (PeriodicSmiLibraryHandler->DispatchHandle == NULL);

+  if (PeriodicSmiLibraryHandler->Stack != NULL) {

+    FreePages (

+      PeriodicSmiLibraryHandler->Stack,

+      EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize)

+      );

+    PeriodicSmiLibraryHandler->Stack = NULL;

+  }

+  RemoveEntryList (&PeriodicSmiLibraryHandler->Link);

+  InsertHeadList (&gFreePeriodicSmiLibraryHandlers, &PeriodicSmiLibraryHandler->Link);

+}

+

+/**

+  Add the additional entries to the list of free periodic SMI handlers.

+  The function is assumed to be called only when the list of free periodic SMI

+  handlers is empty.

+

+  @retval TRUE  The additional entries were added.

+  @retval FALSE There was no available resource for the additional entries.

+**/

+BOOLEAN

+EnlargeFreePeriodicSmiLibraryHandlerList (

+  VOID

+  )

+{

+  UINTN                                 Index;

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+

+  //

+  // Add the entries to the list

+  //

+  for (Index = 0; Index < PERIODIC_SMI_LIBRARY_ALLOCATE_SIZE; Index++) {

+    PeriodicSmiLibraryHandler = AllocatePool (sizeof (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT));

+    if (PeriodicSmiLibraryHandler == NULL) {

+      break;

+    }

+    PeriodicSmiLibraryHandler->Signature = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_SIGNATURE;

+    InsertHeadList (&gFreePeriodicSmiLibraryHandlers, &PeriodicSmiLibraryHandler->Link);

+  }

+

+  return (BOOLEAN) (Index > 0);

+}

+

+/**

+  Internal worker function that returns a free entry for a new periodic

+  SMI handler.  If no free entries are available, then additional

+  entries are allocated.

+  

+  @retval  NULL   There are not enough resources available to to allocate a free entry.

+  @retval  other  Pointer to a free PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT structure.

+  

+**/

+PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *

+FindFreePeriodicSmiLibraryHandler (

+  VOID

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  

+  if (IsListEmpty (&gFreePeriodicSmiLibraryHandlers)) {

+    if (!EnlargeFreePeriodicSmiLibraryHandlerList ()) {

+      return NULL;

+    }

+  }

+

+  //

+  // Get one from the list of free periodic SMI handlers.

+  //

+  PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (

+                                GetFirstNode (&gFreePeriodicSmiLibraryHandlers)

+                                );

+  RemoveEntryList (&PeriodicSmiLibraryHandler->Link);

+  InsertTailList (&gPeriodicSmiLibraryHandlers, &PeriodicSmiLibraryHandler->Link);

+

+  return PeriodicSmiLibraryHandler;

+}

+

+/**

+  This function returns a pointer to a table of supported periodic

+  SMI tick periods in 100 ns units sorted from largest to smallest.  

+  The table contains a array of UINT64 values terminated by a tick 

+  period value of 0.  The returned table must be treated as read-only

+  data and must not be freed.

+  

+  @return  A pointer to a table of UINT64 tick period values in 

+           100ns units sorted from largest to smallest terminated 

+           by a tick period of 0.

+  

+**/

+UINT64 *

+EFIAPI

+PeriodicSmiSupportedTickPeriod (

+  VOID

+  )

+{

+  //

+  // Return the table allocated and populated by SmmPeriodicSmiLibConstructor()

+  //

+  return gSmiTickPeriodTable;

+}

+

+/**

+  This function returns the time in 100ns units since the periodic SMI

+  handler function was called.  If the periodic SMI handler was resumed

+  through PeriodicSmiYield(), then the time returned is the time in

+  100ns units since PeriodicSmiYield() returned.

+

+  @return  The actual time in 100ns units that the periodic SMI handler

+           has been executing.  If this function is not called from within

+           an enabled periodic SMI handler, then 0 is returned.

+

+**/

+UINT64

+EFIAPI

+PeriodicSmiExecutionTime (

+  VOID

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  UINT64                                Current;

+  UINT64                                Count;

+

+  //

+  // If there is no active periodic SMI handler, then return 0 

+  //

+  PeriodicSmiLibraryHandler = GetActivePeriodicSmiLibraryHandler ();

+  if (PeriodicSmiLibraryHandler == NULL) {

+    return 0;

+  }

+  

+  //

+  // Get the current performance counter value

+  //

+  Current = GetPerformanceCounter ();

+  

+  //

+  // Count the number of performance counter ticks since the periodic SMI handler 

+  // was dispatched or the last time this function was called. 

+  //

+  if (PeriodicSmiLibraryHandler->PerfomanceCounterEndValue > PeriodicSmiLibraryHandler->PerfomanceCounterStartValue) {

+    //

+    // The performance counter counts up.  Check for roll over condition.

+    //

+    if (Current > PeriodicSmiLibraryHandler->DispatchCheckPointTime) {

+      Count = Current - PeriodicSmiLibraryHandler->DispatchCheckPointTime;

+    } else {

+      Count = (Current - PeriodicSmiLibraryHandler->PerfomanceCounterStartValue) + (PeriodicSmiLibraryHandler->PerfomanceCounterEndValue - PeriodicSmiLibraryHandler->DispatchCheckPointTime);

+    }

+  } else {

+    //

+    // The performance counter counts down.  Check for roll over condition.

+    //

+    if (PeriodicSmiLibraryHandler->DispatchCheckPointTime > Current) {

+      Count = PeriodicSmiLibraryHandler->DispatchCheckPointTime - Current;

+    } else {

+      Count = (PeriodicSmiLibraryHandler->DispatchCheckPointTime - PeriodicSmiLibraryHandler->PerfomanceCounterEndValue) + (PeriodicSmiLibraryHandler->PerfomanceCounterStartValue - Current);

+    }

+  }

+  

+  //

+  // Accumulate the total number of performance counter ticks since the periodic 

+  // SMI handler was dispatched or resumed.

+  //

+  PeriodicSmiLibraryHandler->DispatchTotalTime += Count;

+  

+  //

+  // Update the checkpoint value to the current performance counter value

+  //

+  PeriodicSmiLibraryHandler->DispatchCheckPointTime = Current;

+  

+  //

+  // Convert the total number of performance counter ticks to 100 ns units

+  //

+  return DivU64x64Remainder (

+           MultU64x32 (PeriodicSmiLibraryHandler->DispatchTotalTime, 10000000), 

+           PeriodicSmiLibraryHandler->PerfomanceCounterRate, 

+           NULL

+           );

+}

+

+/**

+  This function returns control back to the SMM Foundation.  When the next 

+  periodic SMI for the currently executing handler is triggered, the periodic

+  SMI handler will restarted from its registered DispatchFunction entry point.

+  If this function is not called from within an enabled periodic SMI handler, 

+  then control is returned to the calling function.

+

+**/

+VOID

+EFIAPI  

+PeriodicSmiExit (

+  VOID

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  

+  //

+  // If there is no active periodic SMI handler, then return 

+  //

+  PeriodicSmiLibraryHandler = GetActivePeriodicSmiLibraryHandler ();

+  if (PeriodicSmiLibraryHandler == NULL) {

+    return;

+  }

+  

+  //

+  // Perform a long jump back to the point when the currently executing dispatch 

+  // function was dispatched.

+  //

+  LongJump (&PeriodicSmiLibraryHandler->DispatchJumpBuffer, 1);

+  

+  //

+  // Must never return

+  //

+  ASSERT (FALSE);

+  CpuDeadLoop();

+}

+

+/**

+  This function yields control back to the SMM Foundation.  When the next 

+  periodic SMI for the currently executing handler is triggered, the periodic

+  SMI handler will be resumed and this function will return.  Use of this 

+  function requires a seperate stack for the periodic SMI handler.  A non zero

+  stack size must be specified in PeriodicSmiEnable() for this function to be 

+  used.  

+  

+  If the stack size passed into PeriodicSmiEnable() was zero, the 0 is returned.

+  

+  If this function is not called from within an enabled periodic SMI handler, 

+  then 0 is returned.

+

+  @return  The actual time in 100ns units elasped since this function was

+           called.  A value of 0 indicates an unknown amount of time.

+

+**/

+UINT64

+EFIAPI  

+PeriodicSmiYield (

+  VOID

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  UINTN                                 SetJumpFlag;

+

+  //

+  // If there is no active periodic SMI handler, then return 

+  //

+  PeriodicSmiLibraryHandler = GetActivePeriodicSmiLibraryHandler ();

+  if (PeriodicSmiLibraryHandler == NULL) {

+    return 0;

+  }

+  

+  //

+  // If PeriodicSmiYield() is called without an allocated stack, then just return 

+  // immediately with an elapsed time of 0.

+  //

+  if (PeriodicSmiLibraryHandler->Stack == NULL) {

+    return 0;

+  }

+  

+  //

+  // Set a flag so the next periodic SMI event will resume at where SetJump() 

+  // is called below.

+  //

+  PeriodicSmiLibraryHandler->YieldFlag = TRUE;

+

+  //

+  // Save context in YieldJumpBuffer

+  //  

+  SetJumpFlag = SetJump (&PeriodicSmiLibraryHandler->YieldJumpBuffer);

+  if (SetJumpFlag == 0) {

+    //

+    // The intial call to SetJump() always returns 0.

+    // If this is the initial call, then exit the current periodic SMI handler

+    //

+    PeriodicSmiExit ();

+  }

+  

+  //

+  // We get here when a LongJump is performed from PeriodicSmiDispatchFunctionOnCpu()

+  // to resume a periodic SMI handler that called PeriodicSmiYield() on the 

+  // previous time this periodic SMI handler was dispatched.

+  //

+  // Clear the flag so the next periodic SMI dispatch will not resume.

+  //

+  PeriodicSmiLibraryHandler->YieldFlag = FALSE;

+

+  //

+  // Return the amount elapsed time that occured while yielded

+  //  

+  return PeriodicSmiLibraryHandler->ElapsedTime;

+}

+

+/**

+  Internal worker function that transfers control to an enabled periodic SMI 

+  handler.  If the enabled periodic SMI handler was allocated its own stack, 

+  then this function is called on that allocated stack through the BaseLin 

+  function SwitchStack().

+

+  @param[in] Context1  Context1 parameter passed into SwitchStack().

+  @param[in] Context2  Context2 parameter passed into SwitchStack().

+

+**/

+VOID

+EFIAPI

+PeriodicSmiDispatchFunctionSwitchStack (

+  IN VOID  *Context1,  OPTIONAL

+  IN VOID  *Context2   OPTIONAL

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+

+  //

+  // Convert Context1 to PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT * 

+  //  

+  PeriodicSmiLibraryHandler = (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT *)Context1;

+

+  //

+  // Dispatch the registered handler passing in the context that was registered

+  // and the amount of time that has elapsed since the previous time this 

+  // periodic SMI handler was dispacthed.

+  //  

+  PeriodicSmiLibraryHandler->DispatchFunction (

+    PeriodicSmiLibraryHandler->Context,

+    PeriodicSmiLibraryHandler->ElapsedTime

+    );

+    

+  //

+  // If this DispatchFunction() returns, then unconditially call PeriodicSmiExit()

+  // to perform a LongJump() back to PeriodicSmiDispatchFunctionOnCpu(). The 

+  // LongJump() will resume exection on the original stack.

+  //  

+  PeriodicSmiExit ();

+}

+

+/**

+  Internal worker function that transfers control to an enabled periodic SMI 

+  handler on the specified logial CPU.  This function determines if the periodic 

+  SMI handler yielded and needs to be resumed.  It also and switches to an 

+  allocated stack if one was allocated in PeriodicSmiEnable().

+

+  @param[in] PeriodicSmiLibraryHandler  A pointer to the context for the periodic

+                                        SMI handler to execute.

+  

+**/

+VOID

+EFIAPI

+PeriodicSmiDispatchFunctionOnCpu (

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler

+  )

+{

+  //

+  // Save context in DispatchJumpBuffer.  The intial call to SetJump() always 

+  // returns 0.  If this is the initial call, then either resume from a prior 

+  // call to PeriodicSmiYield() or call the DispatchFunction registerd in 

+  // PeriodicSmiEnable() using an allocated stack if one was specified.

+  //  

+  if (SetJump (&PeriodicSmiLibraryHandler->DispatchJumpBuffer) != 0) {

+    return;

+  }

+  

+  //

+  // Capture the performance counter value just before the periodic SMI handler 

+  // is resumed so the amount of time the periodic SMI handler executes can be 

+  // calculated.

+  //

+  PeriodicSmiLibraryHandler->DispatchTotalTime      = 0;

+  PeriodicSmiLibraryHandler->DispatchCheckPointTime = GetPerformanceCounter();

+  

+  if (PeriodicSmiLibraryHandler->YieldFlag) {

+    //

+    // Perform a long jump back to the point where the previously dispatched 

+    // function called PeriodicSmiYield(). 

+    //

+    LongJump (&PeriodicSmiLibraryHandler->YieldJumpBuffer, 1);

+  } else if (PeriodicSmiLibraryHandler->Stack == NULL) {

+    //

+    // If Stack is NULL then call DispatchFunction using current stack passing 

+    // in the context that was registered and the amount of time that has 

+    // elapsed since the previous time this periodic SMI handler was dispacthed.

+    //  

+    PeriodicSmiLibraryHandler->DispatchFunction (

+      PeriodicSmiLibraryHandler->Context,

+      PeriodicSmiLibraryHandler->ElapsedTime

+      );

+      

+    //

+    // If this DispatchFunction() returns, then unconditially call PeriodicSmiExit()

+    // to perform a LongJump() back to this function.

+    //  

+    PeriodicSmiExit ();

+  } else {

+    //

+    // If Stack is not NULL then call DispatchFunction switching to the allocated stack

+    //

+    SwitchStack (

+      PeriodicSmiDispatchFunctionSwitchStack,

+      PeriodicSmiLibraryHandler,

+      NULL,

+      (UINT8 *)PeriodicSmiLibraryHandler->Stack + PeriodicSmiLibraryHandler->StackSize

+      );

+  }    

+

+  //

+  // Must never return

+  //

+  ASSERT (FALSE);

+  CpuDeadLoop();

+}

+

+/**

+  Internal worker function that transfers control to an enabled periodic SMI 

+  handler on the specified logial CPU.  This worker function is only called 

+  using the SMM Services Table function SmmStartupThisAp() to execute the 

+  periodic SMI handler on a logical CPU that is different than the one that is 

+  running the SMM Foundation.  When the periodic SMI handler returns, a lock is

+  released to notify the CPU that is running the SMM Foundation that the periodic

+  SMI handler execution has finished its execution.

+

+  @param[in, out] Buffer  A pointer to the context for the periodic SMI handler.

+

+**/

+VOID

+EFIAPI

+PeriodicSmiDispatchFunctionWithLock (

+  IN OUT VOID  *Buffer

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  

+  //

+  // Get context

+  //  

+  PeriodicSmiLibraryHandler = (PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *)Buffer;

+

+  //

+  // Execute dispatch function on the currently excuting logical CPU

+  //  

+  PeriodicSmiDispatchFunctionOnCpu (PeriodicSmiLibraryHandler);

+  

+  //

+  // Release the dispatch spin lock

+  //

+  ReleaseSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);

+}

+

+/**

+  Internal worker function that transfers control to a periodic SMI handler that

+  was enabled using PeriodicSmiEnable().

+

+  @param[in]     DispatchHandle  The unique handle assigned to this handler by 

+                                 SmiHandlerRegister().

+  @param[in]     Context         Points to an optional handler context which was 

+                                 specified when the handler was registered.

+  @param[in, out] CommBuffer     A pointer to a collection of data in memory that

+                                 will be conveyed from a non-SMM environment into 

+                                 an SMM environment.

+  @param[in, out] CommBufferSize The size of the CommBuffer.

+

+  @retval EFI_SUCCESS                         The interrupt was handled and quiesced.

+                                              No other handlers should still be called.

+  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other

+                                              handlers should still be called.

+  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other

+                                              handlers should still be called.

+  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.

+  

+**/

+EFI_STATUS

+EFIAPI

+PeriodicSmiDispatchFunction (

+  IN EFI_HANDLE  DispatchHandle,

+  IN CONST VOID  *Context         OPTIONAL,

+  IN OUT VOID    *CommBuffer      OPTIONAL,

+  IN OUT UINTN   *CommBufferSize  OPTIONAL

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  EFI_SMM_PERIODIC_TIMER_CONTEXT        *TimerContext;

+  EFI_STATUS                            Status;

+  

+  //

+  // Set the active periodic SMI handler

+  //  

+  PeriodicSmiLibraryHandler = SetActivePeriodicSmiLibraryHandler (Context);

+  if (PeriodicSmiLibraryHandler == NULL) {

+    return EFI_NOT_FOUND;

+  }

+  

+  //

+  // Retrieve the elapsed time since the last time this periodic SMI handler was called

+  //

+  PeriodicSmiLibraryHandler->ElapsedTime = 0;

+  if (CommBuffer != NULL) {

+    TimerContext = (EFI_SMM_PERIODIC_TIMER_CONTEXT  *)CommBuffer;

+    PeriodicSmiLibraryHandler->ElapsedTime = TimerContext->ElapsedTime;

+  }

+

+  //

+  // Dispatch the periodic SMI handler

+  //

+  if ((PeriodicSmiLibraryHandler->Cpu == PERIODIC_SMI_LIBRARY_ANY_CPU) ||

+      (PeriodicSmiLibraryHandler->Cpu == gSmst->CurrentlyExecutingCpu)    ) {

+    //

+    // Dispatch on the currently execution CPU if the CPU specified in PeriodicSmiEnable()

+    // was PERIODIC_SMI_LIBARRY_ANY_CPU or the currently executing CPU matches the CPU

+    // that was specified in PeriodicSmiEnable().

+    //

+    PeriodicSmiDispatchFunctionOnCpu (PeriodicSmiLibraryHandler);

+  } else {

+    //

+    // Acquire spin lock for ths periodic SMI handler.  The AP will release the

+    // spin lock when it is done executing the periodic SMI handler.

+    //

+    AcquireSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);

+  

+    //

+    // Execute the periodic SMI handler on the CPU that was specified in 

+    // PeriodicSmiEnable().

+    //

+    Status = gSmst->SmmStartupThisAp (

+                      PeriodicSmiDispatchFunctionWithLock,

+                      PeriodicSmiLibraryHandler->Cpu,

+                      PeriodicSmiLibraryHandler

+                      );

+    if (!EFI_ERROR (Status)) {

+      //

+      // Wait for the AP to release the spin lock.

+      //

+      while (!AcquireSpinLockOrFail (&PeriodicSmiLibraryHandler->DispatchLock)) {

+        CpuPause ();

+      }

+    }

+    

+    //

+    // Release the spin lock for the periodic SMI handler.

+    //

+    ReleaseSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);

+  }

+

+  //

+  // Reclaim the active periodic SMI handler if it was disabled during the current dispatch.

+  //

+  if (PeriodicSmiLibraryHandler->DispatchHandle == NULL) {

+    ReclaimPeriodicSmiLibraryHandler (PeriodicSmiLibraryHandler);

+  }

+  

+  //

+  // Update state to show that there is no active periodic SMI handler

+  //  

+  SetActivePeriodicSmiLibraryHandler (NULL);

+

+  return EFI_SUCCESS;

+}

+  

+/**

+  This function enables a periodic SMI handler.

+  

+  @param[in, out] DispatchHandle   A pointer to the handle associated with the 

+                                   enabled periodic SMI handler.  This is an 

+                                   optional parameter that may be NULL.  If it is 

+                                   NULL, then the handle will not be returned, 

+                                   which means that the periodic SMI handler can 

+                                   never be disabled.

+  @param[in]     DispatchFunction  A pointer to a periodic SMI handler function.

+  @param[in]     Context           Optional content to pass into DispatchFunction.

+  @param[in]     TickPeriod        The requested tick period in 100ns units that 

+                                   control should be givien to the periodic SMI

+                                   handler.  Must be one of the supported values

+                                   returned by PeriodicSmiSupportedPickPeriod().

+  @param[in]     Cpu               Specifies the CPU that is required to execute

+                                   the periodic SMI handler.  If Cpu is 

+                                   PERIODIC_SMI_LIBRARY_ANY_CPU, then the periodic 

+                                   SMI handler will always be executed on the SMST 

+                                   CurrentlyExecutingCpu, which may vary across 

+                                   periodic SMIs.  If Cpu is between 0 and the SMST 

+                                   NumberOfCpus, then the periodic SMI will always

+                                   be executed on the requested CPU.

+  @param[in]     StackSize         The size, in bytes, of the stack to allocate for

+                                   use by the periodic SMI handler.  If 0, then the

+                                   default stack will be used.

+                            

+  @retval EFI_INVALID_PARAMETER  DispatchFunction is NULL.

+  @retval EFI_UNSUPPORTED        TickPeriod is not a supported tick period.  The 

+                                 supported tick periods can be retrieved using 

+                                 PeriodicSmiSupportedTickPeriod().

+  @retval EFI_INVALID_PARAMETER  Cpu is not PERIODIC_SMI_LIBRARY_ANY_CPU or in 

+                                 the range 0 to SMST NumberOfCpus.

+  @retval EFI_OUT_OF_RESOURCES   There are not enough resources to enable the 

+                                 periodic SMI handler.

+  @retval EFI_OUT_OF_RESOURCES   There are not enough resources to allocate the 

+                                 stack speficied by StackSize.

+  @retval EFI_SUCCESS            The periodic SMI handler was enabled.

+  

+**/

+EFI_STATUS 

+EFIAPI

+PeriodicSmiEnable (

+  IN OUT EFI_HANDLE                    *DispatchHandle,    OPTIONAL

+  IN     PERIODIC_SMI_LIBRARY_HANDLER  DispatchFunction,

+  IN     CONST VOID                    *Context,           OPTIONAL

+  IN     UINT64                        TickPeriod,

+  IN     UINTN                         Cpu,

+  IN     UINTN                         StackSize

+  )

+{

+  EFI_STATUS                            Status;

+  UINTN                                 Index;

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+

+  //

+  // Make sure all the input parameters are valid

+  //  

+  if (DispatchFunction == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+  

+  for (Index = 0; gSmiTickPeriodTable[Index] != 0; Index++) {

+    if (gSmiTickPeriodTable[Index] == TickPeriod) {

+      break;

+    }

+  }  

+  if (gSmiTickPeriodTable[Index] == 0) {

+    return EFI_UNSUPPORTED;

+  }

+  

+  if (Cpu != PERIODIC_SMI_LIBRARY_ANY_CPU && Cpu >= gSmst->NumberOfCpus) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Find a free periodic SMI handler entry

+  //  

+  PeriodicSmiLibraryHandler = FindFreePeriodicSmiLibraryHandler();

+  if (PeriodicSmiLibraryHandler == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Initialize a new periodic SMI handler entry

+  //

+  PeriodicSmiLibraryHandler->YieldFlag        = FALSE;

+  PeriodicSmiLibraryHandler->DispatchHandle   = NULL;

+  PeriodicSmiLibraryHandler->DispatchFunction = DispatchFunction;

+  PeriodicSmiLibraryHandler->Context          = (VOID *)Context;

+  PeriodicSmiLibraryHandler->Cpu              = Cpu;

+  PeriodicSmiLibraryHandler->StackSize        = ALIGN_VALUE (StackSize, EFI_PAGE_SIZE);

+  if (PeriodicSmiLibraryHandler->StackSize > 0) {

+    PeriodicSmiLibraryHandler->Stack = AllocatePages (EFI_SIZE_TO_PAGES (PeriodicSmiLibraryHandler->StackSize));

+    if (PeriodicSmiLibraryHandler->Stack == NULL) {

+      return EFI_OUT_OF_RESOURCES;

+    }

+    ZeroMem (PeriodicSmiLibraryHandler->Stack, PeriodicSmiLibraryHandler->StackSize);

+  } else {

+    PeriodicSmiLibraryHandler->Stack = NULL;

+  }

+  InitializeSpinLock (&PeriodicSmiLibraryHandler->DispatchLock);

+  PeriodicSmiLibraryHandler->PerfomanceCounterRate = GetPerformanceCounterProperties (

+                                                       &PeriodicSmiLibraryHandler->PerfomanceCounterStartValue,

+                                                       &PeriodicSmiLibraryHandler->PerfomanceCounterEndValue

+                                                       );

+  PeriodicSmiLibraryHandler->RegisterContext.Period          = TickPeriod;

+  PeriodicSmiLibraryHandler->RegisterContext.SmiTickInterval = TickPeriod;

+  Status = gSmmPeriodicTimerDispatch2->Register (

+                                         gSmmPeriodicTimerDispatch2,

+                                         PeriodicSmiDispatchFunction,

+                                         &PeriodicSmiLibraryHandler->RegisterContext,

+                                         &PeriodicSmiLibraryHandler->DispatchHandle

+                                         );

+  if (EFI_ERROR (Status)) {

+    PeriodicSmiLibraryHandler->DispatchHandle = NULL;

+    ReclaimPeriodicSmiLibraryHandler (PeriodicSmiLibraryHandler);

+    return EFI_OUT_OF_RESOURCES;

+  }

+  

+  //

+  // Return the registered handle if the optional DispatchHandle parameter is not NULL

+  //

+  if (DispatchHandle != NULL) {

+    *DispatchHandle = PeriodicSmiLibraryHandler->DispatchHandle;

+  }

+  return EFI_SUCCESS;                                         

+}

+

+/**

+  This function disables a periodic SMI handler that has been previously

+  enabled with PeriodicSmiEnable().

+  

+  @param[in] DispatchHandle  A handle associated with a previously enabled periodic 

+                             SMI handler.  This is an optional parameter that may

+                             be NULL.  If it is NULL, then the active periodic SMI

+                             handlers is disabled.

+

+  @retval FALSE  DispatchHandle is NULL and there is no active periodic SMI handler.

+  @retval FALSE  The periodic SMI handler specified by DispatchHandle has 

+                 not been enabled with PeriodicSmiEnable().

+  @retval TRUE   The periodic SMI handler specified by DispatchHandle has 

+                 been disabled.  If DispatchHandle is NULL, then the active

+                 periodic SMI handler has been disabled.

+  

+**/

+BOOLEAN 

+EFIAPI

+PeriodicSmiDisable (

+  IN EFI_HANDLE  DispatchHandle    OPTIONAL

+  )

+{

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+  EFI_STATUS                            Status;

+

+  //

+  // Lookup the periodic SMI handler specified by DispatchHandle

+  //

+  PeriodicSmiLibraryHandler = LookupPeriodicSmiLibraryHandler (DispatchHandle);

+  if (PeriodicSmiLibraryHandler == NULL) {

+    return FALSE;

+  }

+  

+  //

+  // Unregister the periodic SMI handler from the SMM Periodic Timer Dispatch 2 Protocol

+  //

+  Status = gSmmPeriodicTimerDispatch2->UnRegister (

+                                         gSmmPeriodicTimerDispatch2,

+                                         PeriodicSmiLibraryHandler->DispatchHandle

+                                         );

+  if (EFI_ERROR (Status)) {

+    return FALSE;

+  }

+

+  //

+  // Mark the entry for the disabled periodic SMI handler as free, and

+  // call ReclaimPeriodicSmiLibraryHandler to move it to the list of free

+  // periodic SMI handlers.

+  //

+  PeriodicSmiLibraryHandler->DispatchHandle = NULL;

+  if (PeriodicSmiLibraryHandler != GetActivePeriodicSmiLibraryHandler ()) {

+    ReclaimPeriodicSmiLibraryHandler (PeriodicSmiLibraryHandler);

+  }

+

+  return TRUE;

+}

+

+/**

+  This constructor function caches the pointer to the SMM Periodic Timer 

+  Dispatch 2 Protocol and collects the list SMI tick rates that the hardware

+  supports.

+

+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.

+  @param[in] SystemTable  A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmPeriodicSmiLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  UINT64      *SmiTickInterval;

+  UINTN       Count;

+

+  //

+  // Locate the SMM Periodic Timer Dispatch 2 Protocol

+  //

+  Status = gSmst->SmmLocateProtocol (

+                    &gEfiSmmPeriodicTimerDispatch2ProtocolGuid,

+                    NULL,

+                    (VOID **)&gSmmPeriodicTimerDispatch2

+                    );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (gSmmPeriodicTimerDispatch2 != NULL);

+

+  //

+  // Count the number of periodic SMI tick intervals that the SMM Periodic Timer 

+  // Dipatch 2 Protocol supports.

+  //

+  SmiTickInterval = NULL;

+  Count = 0;

+  do {

+    Status = gSmmPeriodicTimerDispatch2->GetNextShorterInterval (

+                                           gSmmPeriodicTimerDispatch2,

+                                           &SmiTickInterval

+                                           );

+    Count++;                                           

+  } while (SmiTickInterval != NULL);                                           

+

+  //

+  // Allocate a buffer for the table of supported periodic SMI tick periods.

+  //  

+  gSmiTickPeriodTable = AllocateZeroPool (Count * sizeof (UINT64));

+  ASSERT (gSmiTickPeriodTable != NULL);

+  

+  //

+  // Fill in the table of supported periodic SMI tick periods.

+  //

+  SmiTickInterval = NULL;

+  Count = 0;

+  do {

+    gSmiTickPeriodTable[Count] = 0;

+    Status = gSmmPeriodicTimerDispatch2->GetNextShorterInterval (

+                                           gSmmPeriodicTimerDispatch2,

+                                           &SmiTickInterval

+                                           );

+    if (SmiTickInterval != NULL) {

+      gSmiTickPeriodTable[Count] = *SmiTickInterval;

+    }

+    Count++;

+  } while (SmiTickInterval != NULL);

+

+  //

+  // Allocate buffer for initial set of periodic SMI handlers

+  //

+  EnlargeFreePeriodicSmiLibraryHandlerList ();

+

+  return EFI_SUCCESS;

+}

+

+/**

+  The constructor function caches the pointer to the SMM Periodic Timer Dispatch 2 

+  Protocol and collects the list SMI tick rates that the hardware supports.

+

+  @param[in] ImageHandle  The firmware allocated handle for the EFI image.

+  @param[in] SystemTable  A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmPeriodicSmiLibDestructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  LIST_ENTRY                            *Link;

+  PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT  *PeriodicSmiLibraryHandler;

+

+  //

+  // Free the table of supported periodic SMI tick rates

+  //

+  if (gSmiTickPeriodTable != NULL) {

+    FreePool (gSmiTickPeriodTable);

+  }

+

+  //

+  // Disable all periodic SMI handlers

+  //

+  for (Link = GetFirstNode (&gPeriodicSmiLibraryHandlers); !IsNull (&gPeriodicSmiLibraryHandlers, Link);) {

+    PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (Link);

+    Link = GetNextNode (&gPeriodicSmiLibraryHandlers, Link);

+    PeriodicSmiDisable (PeriodicSmiLibraryHandler->DispatchHandle);

+  }

+

+  //

+  // Free all the periodic SMI handler entries

+  //

+  for (Link = GetFirstNode (&gFreePeriodicSmiLibraryHandlers); !IsNull (&gFreePeriodicSmiLibraryHandlers, Link);) {    

+    PeriodicSmiLibraryHandler = PERIODIC_SMI_LIBRARY_HANDLER_CONTEXT_FROM_LINK (Link);

+    Link = RemoveEntryList (Link);

+    FreePool (PeriodicSmiLibraryHandler);

+  }

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.inf b/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.inf
new file mode 100644
index 0000000..b181764
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.inf
@@ -0,0 +1,52 @@
+## @file

+# SMM Periodic SMI Library.

+#

+# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmPeriodicSmiLib

+  MODULE_UNI_FILE                = SmmPeriodicSmiLib.uni

+  FILE_GUID                      = AED5F3FB-4CFF-4b60-9E43-1541B55C8267

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmmPeriodicSmiLib|DXE_SMM_DRIVER

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+  CONSTRUCTOR                    = SmmPeriodicSmiLibConstructor

+  DESTRUCTOR                     = SmmPeriodicSmiLibDestructor

+  

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  SmmPeriodicSmiLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  BaseLib

+  BaseMemoryLib

+  SynchronizationLib

+  DebugLib

+  TimerLib

+  MemoryAllocationLib

+  SmmServicesTableLib

+  

+[Protocols]

+  gEfiSmmPeriodicTimerDispatch2ProtocolGuid  ## CONSUMES

+  

+[Depex]

+  gEfiSmmPeriodicTimerDispatch2ProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.uni b/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.uni
new file mode 100644
index 0000000..1d1dde1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmPeriodicSmiLib/SmmPeriodicSmiLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c b/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c
new file mode 100644
index 0000000..23a85a0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c
@@ -0,0 +1,97 @@
+/** @file

+  SMM Services Table Library.

+

+  Copyright (c) 2009 - 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.

+

+**/

+

+#include <PiSmm.h>

+#include <Protocol/SmmBase2.h>

+#include <Library/SmmServicesTableLib.h>

+#include <Library/DebugLib.h>

+

+EFI_SMM_SYSTEM_TABLE2   *gSmst             = NULL;

+EFI_SMM_BASE2_PROTOCOL  *mInternalSmmBase2 = NULL;

+

+/**

+  The constructor function caches the pointer of SMM Services Table.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+SmmServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Retrieve SMM Base2 Protocol,  Do not use gBS from UefiBootServicesTableLib on purpose

+  // to prevent inclusion of gBS, gST, and gImageHandle from SMM Drivers unless the 

+  // SMM driver explicity declares that dependency. 

+  //

+  Status = SystemTable->BootServices->LocateProtocol (

+                                        &gEfiSmmBase2ProtocolGuid,

+                                        NULL,

+                                        (VOID **)&mInternalSmmBase2

+                                        );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mInternalSmmBase2 != NULL);

+

+  //

+  // Check to see if we are already in SMM

+  //

+  if (!InSmm ()) {

+    //

+    // We are not in SMM, so SMST is not needed

+    //

+    return EFI_SUCCESS;

+  }

+

+  //

+  // We are in SMM, retrieve the pointer to SMM System Table

+  //

+  mInternalSmmBase2->GetSmstLocation (mInternalSmmBase2, &gSmst);

+  ASSERT (gSmst != NULL);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function allows the caller to determine if the driver is executing in 

+  System Management Mode(SMM).

+

+  This function returns TRUE if the driver is executing in SMM and FALSE if the 

+  driver is not executing in SMM.

+

+  @retval  TRUE  The driver is executing in System Management Mode (SMM).

+  @retval  FALSE The driver is not executing in System Management Mode (SMM). 

+

+**/

+BOOLEAN

+EFIAPI

+InSmm (

+  VOID

+  )

+{

+  BOOLEAN  InSmm;

+

+  //

+  // Check to see if we are already in SMM

+  //

+  mInternalSmmBase2->InSmm (mInternalSmmBase2, &InSmm);

+  return InSmm;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf b/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
new file mode 100644
index 0000000..78f86c0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
@@ -0,0 +1,45 @@
+## @file

+# SMM Services Table Library.

+#

+# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = SmmServicesTableLib

+  MODULE_UNI_FILE                = SmmServicesTableLib.uni

+  FILE_GUID                      = 064B4C5B-C5EF-4eff-85DF-65518EF1314D

+  MODULE_TYPE                    = DXE_SMM_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SmmServicesTableLib|DXE_SMM_DRIVER

+  PI_SPECIFICATION_VERSION       = 0x0001000A

+  CONSTRUCTOR                    = SmmServicesTableLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64

+#

+

+[Sources]

+  SmmServicesTableLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+

+[Protocols]

+  gEfiSmmBase2ProtocolGuid                      ## CONSUMES

+

+[Depex]

+  gEfiSmmBase2ProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.uni b/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.uni
new file mode 100644
index 0000000..4a7bcd4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/ApplicationEntryPoint.c b/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/ApplicationEntryPoint.c
new file mode 100644
index 0000000..dc05b23
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/ApplicationEntryPoint.c
@@ -0,0 +1,121 @@
+/** @file

+  Entry point library instance to a UEFI application.

+

+Copyright (c) 2007 - 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.

+

+**/

+

+#include <Uefi.h>

+#include <Library/UefiApplicationEntryPoint.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+

+/**

+  Entry point to UEFI Application.

+

+  This function is the entry point for a UEFI Application. This function must call

+  ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList().

+  The return value from ProcessModuleEntryPointList() is returned.

+  If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than _gUefiDriverRevison,

+  then return EFI_INCOMPATIBLE_VERSION.

+

+  @param  ImageHandle                The image handle of the UEFI Application.

+  @param  SystemTable                A pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS               The UEFI Application exited normally.

+  @retval  EFI_INCOMPATIBLE_VERSION  _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.

+  @retval  Other                     Return value from ProcessModuleEntryPointList().

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                 Status;

+

+  if (_gUefiDriverRevision != 0) {

+    //

+    // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the application.

+    //

+    if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {

+      return EFI_INCOMPATIBLE_VERSION;

+    }

+  }

+

+  //

+  // Call constructor for all libraries.

+  //

+  ProcessLibraryConstructorList (ImageHandle, SystemTable);

+

+  //

+  // Call the module's entry point

+  //

+  Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);

+

+  //

+  // Process destructor for all libraries.

+  //

+  ProcessLibraryDestructorList (ImageHandle, SystemTable);

+

+  //

+  // Return the return status code from the driver entry point

+  //

+  return Status;

+}

+

+

+/**

+  Invokes the library destructors for all dependent libraries and terminates

+  the UEFI Application. 

+

+  This function calls ProcessLibraryDestructorList() and the EFI Boot Service Exit()

+  with a status specified by Status.

+

+  @param  Status  Status returned by the application that is exiting.

+  

+**/

+VOID

+EFIAPI

+Exit (

+  IN EFI_STATUS  Status

+  )

+

+{

+  ProcessLibraryDestructorList (gImageHandle, gST);

+

+  gBS->Exit (gImageHandle, Status, 0, NULL);

+}

+

+

+/**

+  Required by the EBC compiler and identical in functionality to _ModuleEntryPoint(). 

+

+  @param  ImageHandle  The image handle of the UEFI Application.

+  @param  SystemTable  A pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS               The UEFI Application exited normally.

+  @retval  EFI_INCOMPATIBLE_VERSION  _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.

+  @retval  Other                     Return value from ProcessModuleEntryPointList().

+

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return _ModuleEntryPoint (ImageHandle, SystemTable);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf b/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
new file mode 100644
index 0000000..be92b3d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
@@ -0,0 +1,40 @@
+## @file

+# Module entry point library for UEFI Application.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiApplicationEntryPoint

+  MODULE_UNI_FILE                = UefiApplicationEntryPoint.uni

+  FILE_GUID                      = DADE8301-CB29-4fd5-8148-56FD246C5B88

+  MODULE_TYPE                    = UEFI_APPLICATION

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiApplicationEntryPoint|UEFI_APPLICATION

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  ApplicationEntryPoint.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.uni b/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.uni
new file mode 100644
index 0000000..9efacd1
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c
new file mode 100644
index 0000000..750a268
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.c
@@ -0,0 +1,66 @@
+/** @file

+  This library retrieve the EFI_BOOT_SERVICES pointer from EFI system table in 

+  library's constructor.

+

+  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.

+

+**/

+

+

+#include <Uefi.h>

+

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+

+EFI_HANDLE         gImageHandle = NULL;

+EFI_SYSTEM_TABLE   *gST         = NULL;

+EFI_BOOT_SERVICES  *gBS         = NULL;

+

+/**

+  The constructor function caches the pointer of Boot Services Table.

+    

+  The constructor function caches the pointer of Boot Services Table through System Table.

+  It will ASSERT() if the pointer of System Table is NULL.

+  It will ASSERT() if the pointer of Boot Services Table is NULL.

+  It will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiBootServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  //

+  // Cache the Image Handle

+  //

+  gImageHandle = ImageHandle;

+  ASSERT (gImageHandle != NULL);

+

+  //

+  // Cache pointer to the EFI System Table

+  //

+  gST = SystemTable;

+  ASSERT (gST != NULL);

+

+  //

+  // Cache pointer to the EFI Boot Services Table

+  //

+  gBS = SystemTable->BootServices;

+  ASSERT (gBS != NULL);

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
new file mode 100644
index 0000000..22a2d63
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
@@ -0,0 +1,40 @@
+## @file

+# UEFI Boot Services Table Library implementation.

+# 

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiBootServicesTableLib

+  MODULE_UNI_FILE                = UefiBootServicesTableLib.uni

+  FILE_GUID                      = ff5c7a2c-ab7a-4366-8616-11c6e53247b6

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiBootServicesTableLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+  CONSTRUCTOR                    = UefiBootServicesTableLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  UefiBootServicesTableLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.uni
new file mode 100644
index 0000000..aba2e4e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/DebugLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
new file mode 100644
index 0000000..2ac2204
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
@@ -0,0 +1,277 @@
+/** @file

+  UEFI Debug Library that sends messages to the Console Output Device in the EFI System Table.

+

+  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         

+  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 <Uefi.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/PrintLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugPrintErrorLevelLib.h>

+

+//

+// Define the maximum debug and assert message length that this library supports 

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+/**

+  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      Format string for the debug message to print.

+  @param  ...         A 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,

+  ...

+  )

+{

+  CHAR16   Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver debug mask value and global mask

+  //

+  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {

+    return;

+  }

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH,  Format, Marker);

+  VA_END (Marker);

+

+

+  //

+  // Send the print string to the Console Output device

+  //

+  if ((gST != NULL) && (gST->ConOut != NULL)) {

+    gST->ConOut->OutputString (gST->ConOut, Buffer);

+  }

+}

+

+

+/**

+  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

+  )

+{

+  CHAR16  Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  UnicodeSPrintAsciiFormat (

+    Buffer, 

+    sizeof (Buffer), 

+    "ASSERT %a(%d): %a\n", 

+    FileName, 

+    LineNumber, 

+    Description

+    );

+    

+  //

+  // Send the print string to the Console Output device

+  //

+  if ((gST != NULL) && (gST->ConOut != NULL)) {

+    gST->ConOut->OutputString (gST->ConOut, Buffer);

+  }

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+  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

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

+

+/**

+  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

+  )

+{

+  return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
new file mode 100644
index 0000000..583872f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
@@ -0,0 +1,54 @@
+## @file

+#  Instance of Debug Library using Console Output Device.

+#

+#  Debug Lib that sends messages to the Console Output Device in the EFI System Table.

+#

+#  Copyright (c) 2007 - 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDebugLibConOut

+  MODULE_UNI_FILE                = UefiDebugLibConOut.uni

+  FILE_GUID                      = 5cddfaf3-e9a7-4d16-bdce-1e002df475bb

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+

+[Sources]

+  DebugLib.c

+

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BaseLib

+  PcdLib

+  PrintLib

+  UefiBootServicesTableLib

+  DebugPrintErrorLevelLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue        ## SOMETIMES_CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask            ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel    ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.uni b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.uni
new file mode 100644
index 0000000..c6cf0a4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
new file mode 100644
index 0000000..bbd6d94
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
@@ -0,0 +1,278 @@
+/** @file

+  UEFI Debug Lib that sends messages to the Standard Error Device in the EFI System Table.

+

+  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         

+  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 <Uefi.h>

+

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/PrintLib.h>

+#include <Library/PcdLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugPrintErrorLevelLib.h>

+

+//

+// Define the maximum debug and assert message length that this library supports 

+//

+#define MAX_DEBUG_MESSAGE_LENGTH  0x100

+

+

+/**

+  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,

+  ...

+  )

+{

+  CHAR16   Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+  VA_LIST  Marker;

+

+  //

+  // If Format is NULL, then ASSERT().

+  //

+  ASSERT (Format != NULL);

+

+  //

+  // Check driver debug mask value and global mask

+  //

+  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {

+    return;

+  }

+

+  //

+  // Convert the DEBUG() message to a Unicode String

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH, Format, Marker);

+  VA_END (Marker);

+

+  //

+  // Send the print string to the Standard Error device

+  //

+  if ((gST != NULL) && (gST->StdErr != NULL)) {

+    gST->StdErr->OutputString (gST->StdErr, Buffer);

+  }

+}

+

+

+/**

+  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

+  )

+{

+  CHAR16  Buffer[MAX_DEBUG_MESSAGE_LENGTH];

+

+  //

+  // Generate the ASSERT() message in Unicode format

+  //

+  UnicodeSPrintAsciiFormat (

+    Buffer, 

+    sizeof (Buffer),

+    "ASSERT %a(%d): %a\n", 

+    FileName, 

+    LineNumber, 

+    Description

+    );

+    

+  //

+  // Send the print string to the Standard Error device

+  //

+  if ((gST != NULL) && (gST->StdErr != NULL)) {

+    gST->StdErr->OutputString (gST->StdErr, Buffer);

+  }

+

+  //

+  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings

+  //

+  if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {

+    CpuBreakpoint ();

+  } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {

+    CpuDeadLoop ();

+  }

+}

+

+

+/**

+  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

+  )

+{

+  //

+  // If Buffer is NULL, then ASSERT().

+  //

+  ASSERT (Buffer != NULL);

+

+  //

+  // SetMem() checks for the the ASSERT() condition on Length and returns Buffer

+  //

+  return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));

+}

+

+

+/**

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);

+}

+

+

+/**  

+  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

+  )

+{

+  return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);

+}

+

+/**

+  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

+  )

+{

+  return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
new file mode 100644
index 0000000..196487c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
@@ -0,0 +1,52 @@
+## @file

+#  Instance of Debug Library using the Standard Error Device.

+#

+#  Debug Lib that sends messages to the the Standard Error Device in the EFI System Table.

+#

+#  Copyright (c) 2007 - 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.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDebugLibStdErr

+  MODULE_UNI_FILE                = UefiDebugLibStdErr.uni

+  FILE_GUID                      = b57a1df6-ffdb-4247-a3df-3a562176751a

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DebugLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DebugLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  BaseLib

+  PcdLib

+  PrintLib

+  UefiBootServicesTableLib

+  DebugPrintErrorLevelLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue   ## SOMETIMES_CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask       ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.uni b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.uni
new file mode 100644
index 0000000..ded1748
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
new file mode 100644
index 0000000..6ec0a4c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -0,0 +1,3238 @@
+/** @file

+  DevicePathFromText protocol as defined in the UEFI 2.0 specification.

+

+Copyright (c) 2013 - 2014, 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.

+

+**/

+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.

+

+**/

+CHAR16 *

+GetParamByNodeName (

+  IN CHAR16 *Str,

+  IN 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] = L'\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

+

+**/

+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 = L'\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

+

+**/

+CHAR16 *

+GetNextParamStr (

+  IN OUT CHAR16 **List

+  )

+{

+  //

+  // The separator is comma

+  //

+  return SplitStr (List, L',');

+}

+

+/**

+  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

+

+**/

+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 = L'\0';

+    Str++;

+  } else {

+    *IsInstanceEnd = FALSE;

+    if (!IS_NULL (*Str)) {

+      *Str = L'\0';

+      Str++;

+    }

+  }

+

+  *DevicePath = Str;

+

+  return ReturnStr;

+}

+

+

+/**

+  Return whether the integer string is a hex string.

+

+  @param Str             The integer string

+

+  @retval TRUE   Hex string

+  @retval FALSE  Decimal string

+

+**/

+BOOLEAN

+IsHexStr (

+  IN CHAR16   *Str

+  )

+{

+  //

+  // skip preceeding white space

+  //

+  while ((*Str != 0) && *Str == L' ') {

+    Str ++;

+  }

+  //

+  // skip preceeding zeros

+  //

+  while ((*Str != 0) && *Str == L'0') {

+    Str ++;

+  }

+  

+  return (BOOLEAN) (*Str == L'x' || *Str == L'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

+

+**/

+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

+

+**/

+VOID

+Strtoi64 (

+  IN  CHAR16  *Str,

+  OUT UINT64  *Data

+  )

+{

+  if (IsHexStr (Str)) {

+    *Data = StrHexToUint64 (Str);

+  } else {

+    *Data = StrDecimalToUint64 (Str);

+  }

+}

+

+/**

+  Converts a list of string to a specified buffer.

+

+  @param Buf             The output buffer that contains the string.

+  @param BufferLength    The length of the buffer

+  @param Str             The input string that contains the hex number

+

+  @retval EFI_SUCCESS    The string was successfully converted to the buffer.

+

+**/

+EFI_STATUS

+StrToBuf (

+  OUT UINT8    *Buf,

+  IN  UINTN    BufferLength,

+  IN  CHAR16   *Str

+  )

+{

+  UINTN       Index;

+  UINTN       StrLength;

+  UINT8       Digit;

+  UINT8       Byte;

+

+  Digit = 0;

+

+  //

+  // Two hex char make up one byte

+  //

+  StrLength = BufferLength * sizeof (CHAR16);

+

+  for(Index = 0; Index < StrLength; Index++, Str++) {

+

+    if ((*Str >= L'a') && (*Str <= L'f')) {

+      Digit = (UINT8) (*Str - L'a' + 0x0A);

+    } else if ((*Str >= L'A') && (*Str <= L'F')) {

+      Digit = (UINT8) (*Str - L'A' + 0x0A);

+    } else if ((*Str >= L'0') && (*Str <= L'9')) {

+      Digit = (UINT8) (*Str - L'0');

+    } else {

+      return EFI_INVALID_PARAMETER;

+    }

+

+    //

+    // For odd characters, write the upper nibble for each buffer byte,

+    // and for even characters, the lower nibble.

+    //

+    if ((Index & 1) == 0) {

+      Byte = (UINT8) (Digit << 4);

+    } else {

+      Byte = Buf[Index / 2];

+      Byte &= 0xF0;

+      Byte = (UINT8) (Byte | Digit);

+    }

+

+    Buf[Index / 2] = Byte;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Converts a string to GUID value.

+  Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

+

+  @param Str              The registry format GUID string that contains the GUID value.

+  @param Guid             A pointer to the converted GUID value.

+

+  @retval EFI_SUCCESS     The GUID string was successfully converted to the GUID value.

+  @retval EFI_UNSUPPORTED The input string is not in registry format.

+  @return others          Some error occurred when converting part of GUID value.

+

+**/

+EFI_STATUS

+StrToGuid (

+  IN  CHAR16   *Str,

+  OUT EFI_GUID *Guid

+  )

+{

+  //

+  // Get the first UINT32 data

+  //

+  Guid->Data1 = (UINT32) StrHexToUint64  (Str);

+  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {

+    Str ++;

+  }

+  

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the second UINT16 data

+  //

+  Guid->Data2 = (UINT16) StrHexToUint64  (Str);

+  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {

+    Str ++;

+  }

+

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+  

+  //

+  // Get the third UINT16 data

+  //

+  Guid->Data3 = (UINT16) StrHexToUint64  (Str);

+  while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {

+    Str ++;

+  }

+

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Get the following 8 bytes data

+  //  

+  StrToBuf (&Guid->Data4[0], 2, Str);

+  //

+  // Skip 2 byte hex chars

+  //

+  Str += 2 * 2;

+

+  if (IS_HYPHEN (*Str)) {

+    Str++;

+  } else {

+    return EFI_UNSUPPORTED;

+  }

+  StrToBuf (&Guid->Data4[2], 6, Str);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Converts a string to IPv4 address

+

+  @param Str             A string representation of IPv4 address.

+  @param IPv4Addr        A pointer to the converted IPv4 address.

+

+**/

+VOID

+StrToIPv4Addr (

+  IN OUT CHAR16           **Str,

+  OUT    EFI_IPv4_ADDRESS *IPv4Addr

+  )

+{

+  UINTN  Index;

+

+  for (Index = 0; Index < 4; Index++) {

+    IPv4Addr->Addr[Index] = (UINT8) Strtoi (SplitStr (Str, L'.'));

+  }

+}

+

+/**

+  Converts a string to IPv4 address

+

+  @param Str             A string representation of IPv6 address.

+  @param IPv6Addr        A pointer to the converted IPv6 address.

+

+**/

+VOID

+StrToIPv6Addr (

+  IN OUT CHAR16           **Str,

+  OUT    EFI_IPv6_ADDRESS *IPv6Addr

+  )

+{

+  UINTN  Index;

+  UINT16 Data;

+

+  for (Index = 0; Index < 8; Index++) {

+    Data = (UINT16) StrHexToUintn (SplitStr (Str, L':'));

+    IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);

+    IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);

+  }

+}

+

+/**

+  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

+

+**/

+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.

+**/

+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)

+           );

+

+  if (DataLength != 0) {

+    StrToBuf ((UINT8 *) (Node + 1), DataLength, DataStr);

+  }

+  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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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);

+  StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);

+

+  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.

+

+**/

+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.

+

+**/

+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 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.

+

+**/

+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.

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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, L"Primary") == 0) {

+    Atapi->PrimarySecondary = 0;

+  } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) {

+    Atapi->PrimarySecondary = 1;

+  } else {

+    Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);

+  }

+  if (StrCmp (SlaveMasterStr, L"Master") == 0) {

+    Atapi->SlaveMaster      = 0;

+  } else if (StrCmp (SlaveMasterStr, L"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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+DevPathFromTextInfiniband (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  CHAR16                  *FlagsStr;

+  CHAR16                  *GuidStr;

+  CHAR16                  *SidStr;

+  CHAR16                  *TidStr;

+  CHAR16                  *DidStr;

+  EFI_GUID                PortGid;

+  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, &PortGid);

+  CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));

+  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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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, L"XonXoff") == 0) {

+    UartFlowControl->FlowControlMap = 2;

+  } else if (StrCmp (ValueStr, L"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.

+

+**/

+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, L"NoTopology") == 0) {

+    Info = 0x0;

+

+  } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) {

+

+    Uint16 = (UINT16) Strtoi (DriveBayStr);

+    if (Uint16 == 0) {

+      Info = 0x1;

+    } else {

+      Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));

+    }

+

+    if (StrCmp (SASSATAStr, L"SATA") == 0) {

+      Info |= BIT4;

+    }

+

+    //

+    // Location is an integer between 0 and 1 or else

+    // the keyword Internal (0) or External (1).

+    //

+    if (StrCmp (LocationStr, L"External") == 0) {

+      Uint16 = 1;

+    } else if (StrCmp (LocationStr, L"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, L"Expanded") == 0) {

+      Uint16 = 1;

+    } else if (StrCmp (ConnectStr, L"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.

+

+**/

+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, L"NoTopology") == 0) {

+    Info = 0x0;

+

+  } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) {

+

+    Uint16 = (UINT16) Strtoi (DriveBayStr);

+    if (Uint16 == 0) {

+      Info = 0x1;

+    } else {

+      Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));

+    }

+

+    if (StrCmp (SASSATAStr, L"SATA") == 0) {

+      Info |= BIT4;

+    }

+

+    //

+    // Location is an integer between 0 and 1 or else

+    // the keyword Internal (0) or External (1).

+    //

+    if (StrCmp (LocationStr, L"External") == 0) {

+      Uint16 = 1;

+    } else if (StrCmp (LocationStr, L"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, L"Expanded") == 0) {

+      Uint16 = 1;

+    } else if (StrCmp (ConnectStr, L"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.

+

+**/

+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, L'-'));

+  }

+

+  return (EFI_DEVICE_PATH_PROTOCOL *) Nvme;

+}

+

+/**

+  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.

+

+**/

+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.

+

+**/

+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);

+  StrToBuf (&MACDevPath->MacAddress.Addr[0], Length, AddressStr);

+

+  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 .

+

+**/

+UINTN

+NetworkProtocolFromText (

+  IN CHAR16 *Text

+  )

+{

+  if (StrCmp (Text, L"UDP") == 0) {

+    return RFC_1700_UDP_PROTOCOL;

+  }

+

+  if (StrCmp (Text, L"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.

+

+**/

+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)

+                                                 );

+

+  StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);

+  IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);

+  if (StrCmp (TypeStr, L"Static") == 0) {

+    IPv4->StaticIpAddress = TRUE;

+  } else {

+    IPv4->StaticIpAddress = FALSE;

+  }

+

+  StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);

+  if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {

+    StrToIPv4Addr (&GatewayIPStr,  &IPv4->GatewayIpAddress);

+    StrToIPv4Addr (&SubnetMaskStr, &IPv4->SubnetMask);

+  } 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.

+

+**/

+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)

+                                                 );

+

+  StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);

+  IPv6->Protocol        = (UINT16) NetworkProtocolFromText (ProtocolStr);

+  if (StrCmp (TypeStr, L"Static") == 0) {

+    IPv6->IpAddressOrigin = 0;

+  } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) {

+    IPv6->IpAddressOrigin = 1;

+  } else {

+    IPv6->IpAddressOrigin = 2;

+  }

+

+  StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);

+  if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {

+    StrToIPv6Addr (&GatewayIPStr, &IPv6->GatewayIpAddress);

+    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.

+

+**/

+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, L"DEFAULT") == 0) {

+    Uart->BaudRate = 115200;

+  } else {

+    Strtoi64 (BaudStr, &Uart->BaudRate);

+  }

+  Uart->DataBits  = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));

+  switch (*ParityStr) {

+  case L'D':

+    Uart->Parity = 0;

+    break;

+

+  case L'N':

+    Uart->Parity = 1;

+    break;

+

+  case L'E':

+    Uart->Parity = 2;

+    break;

+

+  case L'O':

+    Uart->Parity = 3;

+    break;

+

+  case L'M':

+    Uart->Parity = 4;

+    break;

+

+  case L'S':

+    Uart->Parity = 5;

+    break;

+

+  default:

+    Uart->Parity = (UINT8) Strtoi (ParityStr);

+    break;

+  }

+

+  if (StrCmp (StopBitsStr, L"D") == 0) {

+    Uart->StopBits = (UINT8) 0;

+  } else if (StrCmp (StopBitsStr, L"1") == 0) {

+    Uart->StopBits = (UINT8) 1;

+  } else if (StrCmp (StopBitsStr, L"1.5") == 0) {

+    Uart->StopBits = (UINT8) 2;

+  } else if (StrCmp (StopBitsStr, L"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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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] == L'\"' &&

+      SerialNumberStr[SerialNumberStrLen - 1] == L'\"'

+    ) {

+    SerialNumberStr[SerialNumberStrLen - 1] = L'\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);

+  StrnCpy ((CHAR16 *) ((UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH)), SerialNumberStr, SerialNumberStrLen);

+

+  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.

+

+**/

+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.

+

+**/

+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, L"CRC32C") == 0) {

+    Options |= 0x0002;

+  }

+

+  if (StrCmp (DataDigestStr, L"CRC32C") == 0) {

+    Options |= 0x0008;

+  }

+

+  if (StrCmp (AuthenticationStr, L"None") == 0) {

+    Options |= 0x0800;

+  }

+

+  if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) {

+    Options |= 0x1000;

+  }

+

+  ISCSIDevPath->LoginOption      = (UINT16) Options;

+

+  ISCSIDevPath->NetworkProtocol  = (UINT16) StrCmp (ProtocolStr, L"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.

+

+**/

+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 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.

+

+**/

+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.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+DevPathFromTextHD (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  CHAR16                *PartitionStr;

+  CHAR16                *TypeStr;

+  CHAR16                *SignatureStr;

+  CHAR16                *StartStr;

+  CHAR16                *SizeStr;

+  UINT32                Signature32;

+  EFI_GUID              SignatureGuid;

+  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, L"MBR") == 0) {

+    Hd->SignatureType = SIGNATURE_TYPE_MBR;

+    Hd->MBRType       = 0x01;

+

+    Signature32       = (UINT32) Strtoi (SignatureStr);

+    CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));

+  } else if (StrCmp (TypeStr, L"GPT") == 0) {

+    Hd->SignatureType = SIGNATURE_TYPE_GUID;

+    Hd->MBRType       = 0x02;

+

+    StrToGuid (SignatureStr, &SignatureGuid);

+    CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));

+  } 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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+DevPathFromTextFilePath (

+  IN CHAR16 *TextDeviceNode

+  )

+{

+  FILEPATH_DEVICE_PATH  *File;

+

+  File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (

+                                    MEDIA_DEVICE_PATH,

+                                    MEDIA_FILEPATH_DP,

+                                    (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)

+                                    );

+

+  StrCpy (File->PathName, TextDeviceNode);

+

+  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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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.

+

+**/

+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 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.

+

+**/

+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.

+

+**/

+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, L"Floppy") == 0) {

+    Bbs->DeviceType = BBS_TYPE_FLOPPY;

+  } else if (StrCmp (TypeStr, L"HD") == 0) {

+    Bbs->DeviceType = BBS_TYPE_HARDDRIVE;

+  } else if (StrCmp (TypeStr, L"CDROM") == 0) {

+    Bbs->DeviceType = BBS_TYPE_CDROM;

+  } else if (StrCmp (TypeStr, L"PCMCIA") == 0) {

+    Bbs->DeviceType = BBS_TYPE_PCMCIA;

+  } else if (StrCmp (TypeStr, L"USB") == 0) {

+    Bbs->DeviceType = BBS_TYPE_USB;

+  } else if (StrCmp (TypeStr, L"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.

+

+**/

+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[] = {

+  {L"Path",                    DevPathFromTextPath                    },

+

+  {L"HardwarePath",            DevPathFromTextHardwarePath            },

+  {L"Pci",                     DevPathFromTextPci                     },

+  {L"PcCard",                  DevPathFromTextPcCard                  },

+  {L"MemoryMapped",            DevPathFromTextMemoryMapped            },

+  {L"VenHw",                   DevPathFromTextVenHw                   },

+  {L"Ctrl",                    DevPathFromTextCtrl                    },

+

+  {L"AcpiPath",                DevPathFromTextAcpiPath                },

+  {L"Acpi",                    DevPathFromTextAcpi                    },

+  {L"PciRoot",                 DevPathFromTextPciRoot                 },

+  {L"PcieRoot",                DevPathFromTextPcieRoot                },

+  {L"Floppy",                  DevPathFromTextFloppy                  },

+  {L"Keyboard",                DevPathFromTextKeyboard                },

+  {L"Serial",                  DevPathFromTextSerial                  },

+  {L"ParallelPort",            DevPathFromTextParallelPort            },

+  {L"AcpiEx",                  DevPathFromTextAcpiEx                  },

+  {L"AcpiExp",                 DevPathFromTextAcpiExp                 },

+  {L"AcpiAdr",                 DevPathFromTextAcpiAdr                 },

+

+  {L"Msg",                     DevPathFromTextMsg                     },

+  {L"Ata",                     DevPathFromTextAta                     },

+  {L"Scsi",                    DevPathFromTextScsi                    },

+  {L"Fibre",                   DevPathFromTextFibre                   },

+  {L"FibreEx",                 DevPathFromTextFibreEx                 },

+  {L"I1394",                   DevPathFromText1394                    },

+  {L"USB",                     DevPathFromTextUsb                     },

+  {L"I2O",                     DevPathFromTextI2O                     },

+  {L"Infiniband",              DevPathFromTextInfiniband              },

+  {L"VenMsg",                  DevPathFromTextVenMsg                  },

+  {L"VenPcAnsi",               DevPathFromTextVenPcAnsi               },

+  {L"VenVt100",                DevPathFromTextVenVt100                },

+  {L"VenVt100Plus",            DevPathFromTextVenVt100Plus            },

+  {L"VenUtf8",                 DevPathFromTextVenUtf8                 },

+  {L"UartFlowCtrl",            DevPathFromTextUartFlowCtrl            },

+  {L"SAS",                     DevPathFromTextSAS                     },

+  {L"SasEx",                   DevPathFromTextSasEx                   },

+  {L"NVMe",                    DevPathFromTextNVMe                    },

+  {L"DebugPort",               DevPathFromTextDebugPort               },

+  {L"MAC",                     DevPathFromTextMAC                     },

+  {L"IPv4",                    DevPathFromTextIPv4                    },

+  {L"IPv6",                    DevPathFromTextIPv6                    },

+  {L"Uart",                    DevPathFromTextUart                    },

+  {L"UsbClass",                DevPathFromTextUsbClass                },

+  {L"UsbAudio",                DevPathFromTextUsbAudio                },

+  {L"UsbCDCControl",           DevPathFromTextUsbCDCControl           },

+  {L"UsbHID",                  DevPathFromTextUsbHID                  },

+  {L"UsbImage",                DevPathFromTextUsbImage                },

+  {L"UsbPrinter",              DevPathFromTextUsbPrinter              },

+  {L"UsbMassStorage",          DevPathFromTextUsbMassStorage          },

+  {L"UsbHub",                  DevPathFromTextUsbHub                  },

+  {L"UsbCDCData",              DevPathFromTextUsbCDCData              },

+  {L"UsbSmartCard",            DevPathFromTextUsbSmartCard            },

+  {L"UsbVideo",                DevPathFromTextUsbVideo                },

+  {L"UsbDiagnostic",           DevPathFromTextUsbDiagnostic           },

+  {L"UsbWireless",             DevPathFromTextUsbWireless             },

+  {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },

+  {L"UsbIrdaBridge",           DevPathFromTextUsbIrdaBridge           },

+  {L"UsbTestAndMeasurement",   DevPathFromTextUsbTestAndMeasurement   },

+  {L"UsbWwid",                 DevPathFromTextUsbWwid                 },

+  {L"Unit",                    DevPathFromTextUnit                    },

+  {L"iSCSI",                   DevPathFromTextiSCSI                   },

+  {L"Vlan",                    DevPathFromTextVlan                    },

+

+  {L"MediaPath",               DevPathFromTextMediaPath               },

+  {L"HD",                      DevPathFromTextHD                      },

+  {L"CDROM",                   DevPathFromTextCDROM                   },

+  {L"VenMedia",                DevPathFromTextVenMedia                },

+  {L"Media",                   DevPathFromTextMedia                   },

+  {L"Fv",                      DevPathFromTextFv                      },

+  {L"FvFile",                  DevPathFromTextFvFile                  },

+  {L"Offset",                  DevPathFromTextRelativeOffsetRange     },

+

+  {L"BbsPath",                 DevPathFromTextBbsPath                 },

+  {L"BBS",                     DevPathFromTextBBS                     },

+  {L"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.

+

+**/

+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.

+

+**/

+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);

+

+      NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);

+      FreePool (DevicePath);

+      FreePool (DeviceNode);

+      DevicePath = NewDevicePath;

+    }

+  }

+

+  FreePool (DevicePathStr);

+  return DevicePath;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
new file mode 100644
index 0000000..0300019
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
@@ -0,0 +1,2037 @@
+/** @file

+  DevicePathToText protocol as defined in the UEFI 2.0 specification.

+

+Copyright (c) 2013 - 2014, 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.

+

+**/

+CHAR16 *

+EFIAPI

+UefiDevicePathLibCatPrint (

+  IN OUT POOL_PRINT   *Str,

+  IN CHAR16           *Fmt,

+  ...

+  )

+{

+  UINTN   Count;

+  VA_LIST Args;

+

+  VA_START (Args, Fmt);

+  Count = SPrintLength (Fmt, Args);

+

+  if ((Str->Count + (Count + 1)) * sizeof (CHAR16) > Str->Capacity) {

+    Str->Capacity = (Str->Count + (Count + 1) * 2) * sizeof (CHAR16);

+    Str->Str = ReallocatePool (

+                 Str->Count * sizeof (CHAR16),

+                 Str->Capacity,

+                 Str->Str

+                 );

+    ASSERT (Str->Str != NULL);

+  }

+  UnicodeVSPrint (&Str->Str[Str->Count], Str->Capacity - Str->Count * sizeof (CHAR16), 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.

+

+**/

+VOID

+DevPathToTextPci (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  PCI_DEVICE_PATH *Pci;

+

+  Pci = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+VOID

+DevPathToTextPccard (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  PCCARD_DEVICE_PATH  *Pccard;

+

+  Pccard = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+VOID

+DevPathToTextMemMap (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  MEMMAP_DEVICE_PATH  *MemMap;

+

+  MemMap = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"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.

+

+**/

+VOID

+DevPathToTextVendor (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  VENDOR_DEVICE_PATH  *Vendor;

+  CHAR16              *Type;

+  UINTN               Index;

+  UINTN               DataLength;

+  UINT32              FlowControlMap;

+  UINT16              Info;

+

+  Vendor = (VENDOR_DEVICE_PATH *) DevPath;

+  switch (DevicePathType (&Vendor->Header)) {

+  case HARDWARE_DEVICE_PATH:

+    Type = L"Hw";

+    break;

+

+  case MESSAGING_DEVICE_PATH:

+    Type = L"Msg";

+    if (AllowShortcuts) {

+      if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenPcAnsi()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenVt100()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenVt100Plus()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {

+        UefiDevicePathLibCatPrint (Str, L"VenUft8()");

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {

+        FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);

+        switch (FlowControlMap & 0x00000003) {

+        case 0:

+          UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"None");

+          break;

+

+        case 1:

+          UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");

+          break;

+

+        case 2:

+          UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");

+          break;

+

+        default:

+          break;

+        }

+

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {

+        UefiDevicePathLibCatPrint (

+          Str,

+          L"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, L"NoTopology,0,0,0,");

+        } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {

+          UefiDevicePathLibCatPrint (

+            Str,

+            L"%s,%s,%s,",

+            ((Info & BIT4) != 0) ? L"SATA" : L"SAS",

+            ((Info & BIT5) != 0) ? L"External" : L"Internal",

+            ((Info & BIT6) != 0) ? L"Expanded" : L"Direct"

+            );

+          if ((Info & 0x0f) == 1) {

+            UefiDevicePathLibCatPrint (Str, L"0,");

+          } else {

+            //

+            // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256

+            //

+            UefiDevicePathLibCatPrint (Str, L"0x%x,", ((Info >> 8) & 0xff) + 1);

+          }

+        } else {

+          UefiDevicePathLibCatPrint (Str, L"0x%x,0,0,0,", Info);

+        }

+

+        UefiDevicePathLibCatPrint (Str, L"0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);

+        return ;

+      } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {

+        UefiDevicePathLibCatPrint (Str, L"DebugPort()");

+        return ;

+      }

+    }

+    break;

+

+  case MEDIA_DEVICE_PATH:

+    Type = L"Media";

+    break;

+

+  default:

+    Type = L"?";

+    break;

+  }

+

+  DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);

+  UefiDevicePathLibCatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);

+  if (DataLength != 0) {

+    UefiDevicePathLibCatPrint (Str, L",");

+    for (Index = 0; Index < DataLength; Index++) {

+      UefiDevicePathLibCatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);

+    }

+  }

+

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  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.

+

+**/

+VOID

+DevPathToTextController (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  CONTROLLER_DEVICE_PATH  *Controller;

+

+  Controller = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"Ctrl(0x%x)",

+    Controller->ControllerNumber

+    );

+}

+

+/**

+  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.

+

+**/

+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, L"PciRoot(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0a08:

+      UefiDevicePathLibCatPrint (Str, L"PcieRoot(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0604:

+      UefiDevicePathLibCatPrint (Str, L"Floppy(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0301:

+      UefiDevicePathLibCatPrint (Str, L"Keyboard(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0501:

+      UefiDevicePathLibCatPrint (Str, L"Serial(0x%x)", Acpi->UID);

+      break;

+

+    case 0x0401:

+      UefiDevicePathLibCatPrint (Str, L"ParallelPort(0x%x)", Acpi->UID);

+      break;

+

+    default:

+      UefiDevicePathLibCatPrint (Str, L"Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);

+      break;

+    }

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+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;

+  CHAR16                         HIDText[11];

+  CHAR16                         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),

+    L"%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),

+    L"%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,

+      L"AcpiExp(%s,%s,%a)",

+      HIDText,

+      CIDText,

+      UIDStr

+      );

+  } else {

+    if (AllowShortcuts) {

+      //

+      // display only

+      //

+      if (AcpiEx->HID == 0) {

+        UefiDevicePathLibCatPrint (Str, L"AcpiEx(%a,", HIDStr);

+      } else {

+        UefiDevicePathLibCatPrint (Str, L"AcpiEx(%s,", HIDText);

+      }

+

+      if (AcpiEx->UID == 0) {

+        UefiDevicePathLibCatPrint (Str, L"%a,", UIDStr);

+      } else {

+        UefiDevicePathLibCatPrint (Str, L"0x%x,", AcpiEx->UID);

+      }

+

+      if (AcpiEx->CID == 0) {

+        UefiDevicePathLibCatPrint (Str, L"%a)", CIDStr);

+      } else {

+        UefiDevicePathLibCatPrint (Str, L"%s)", CIDText);

+      }

+    } else {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"AcpiEx(%s,%s,0x%x,%a,%a,%a)",

+        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.

+

+**/

+VOID

+DevPathToTextAcpiAdr (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  ACPI_ADR_DEVICE_PATH    *AcpiAdr;

+  UINT16                  Index;

+  UINT16                  Length;

+  UINT16                  AdditionalAdrCount;

+

+  AcpiAdr            = DevPath;

+  Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);

+  AdditionalAdrCount = (UINT16) ((Length - 8) / 4);

+

+  UefiDevicePathLibCatPrint (Str, L"AcpiAdr(0x%x", AcpiAdr->ADR);

+  for (Index = 0; Index < AdditionalAdrCount; Index++) {

+    UefiDevicePathLibCatPrint (Str, L",0x%x", *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  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.

+

+**/

+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, L"Ata(0x%x)", Atapi->Lun);

+  } else {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"Ata(%s,%s,0x%x)",

+      (Atapi->PrimarySecondary == 1) ? L"Secondary" : L"Primary",

+      (Atapi->SlaveMaster == 1) ? L"Slave" : L"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.

+

+**/

+VOID

+DevPathToTextScsi (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  SCSI_DEVICE_PATH  *Scsi;

+

+  Scsi = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+VOID

+DevPathToTextFibre (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  FIBRECHANNEL_DEVICE_PATH  *Fibre;

+

+  Fibre = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+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, L"FibreEx(0x");

+  for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", FibreEx->WWN[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L",0x");

+  for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", FibreEx->Lun[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  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.

+

+**/

+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, L"SasEx(0x");

+

+  for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", SasEx->SasAddress[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L",0x");

+  for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", SasEx->Lun[Index]);

+  }

+  UefiDevicePathLibCatPrint (Str, L",0x%x,", SasEx->RelativeTargetPort);

+

+  if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {

+    UefiDevicePathLibCatPrint (Str, L"NoTopology,0,0,0");

+  } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"%s,%s,%s,",

+      ((SasEx->DeviceTopology & BIT4) != 0) ? L"SATA" : L"SAS",

+      ((SasEx->DeviceTopology & BIT5) != 0) ? L"External" : L"Internal",

+      ((SasEx->DeviceTopology & BIT6) != 0) ? L"Expanded" : L"Direct"

+      );

+    if ((SasEx->DeviceTopology & 0x0f) == 1) {

+      UefiDevicePathLibCatPrint (Str, L"0");

+    } else {

+      //

+      // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256

+      //

+      UefiDevicePathLibCatPrint (Str, L"0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);

+    }

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"0x%x,0,0,0", SasEx->DeviceTopology);

+  }

+

+  UefiDevicePathLibCatPrint (Str, L")");

+  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.

+

+**/

+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,

+    L"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 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.

+

+**/

+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, L"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.

+

+**/

+VOID

+DevPathToTextUsb (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  USB_DEVICE_PATH *Usb;

+

+  Usb = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+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 *) ((UINT8 *) UsbWWId + sizeof (USB_WWID_DEVICE_PATH));

+  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,

+    L"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.

+

+**/

+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, L"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.

+

+**/

+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, L"UsbAudio");

+    break;

+

+  case USB_CLASS_CDCCONTROL:

+    UefiDevicePathLibCatPrint (Str, L"UsbCDCControl");

+    break;

+

+  case USB_CLASS_HID:

+    UefiDevicePathLibCatPrint (Str, L"UsbHID");

+    break;

+

+  case USB_CLASS_IMAGE:

+    UefiDevicePathLibCatPrint (Str, L"UsbImage");

+    break;

+

+  case USB_CLASS_PRINTER:

+    UefiDevicePathLibCatPrint (Str, L"UsbPrinter");

+    break;

+

+  case USB_CLASS_MASS_STORAGE:

+    UefiDevicePathLibCatPrint (Str, L"UsbMassStorage");

+    break;

+

+  case USB_CLASS_HUB:

+    UefiDevicePathLibCatPrint (Str, L"UsbHub");

+    break;

+

+  case USB_CLASS_CDCDATA:

+    UefiDevicePathLibCatPrint (Str, L"UsbCDCData");

+    break;

+

+  case USB_CLASS_SMART_CARD:

+    UefiDevicePathLibCatPrint (Str, L"UsbSmartCard");

+    break;

+

+  case USB_CLASS_VIDEO:

+    UefiDevicePathLibCatPrint (Str, L"UsbVideo");

+    break;

+

+  case USB_CLASS_DIAGNOSTIC:

+    UefiDevicePathLibCatPrint (Str, L"UsbDiagnostic");

+    break;

+

+  case USB_CLASS_WIRELESS:

+    UefiDevicePathLibCatPrint (Str, L"UsbWireless");

+    break;

+

+  default:

+    IsKnownSubClass = FALSE;

+    break;

+  }

+

+  if (IsKnownSubClass) {

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"(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,

+        L"UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",

+        UsbClass->VendorId,

+        UsbClass->ProductId,

+        UsbClass->DeviceProtocol

+        );

+      return;

+    } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"UsbIrdaBridge(0x%x,0x%x,0x%x)",

+        UsbClass->VendorId,

+        UsbClass->ProductId,

+        UsbClass->DeviceProtocol

+        );

+      return;

+    } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {

+      UefiDevicePathLibCatPrint (

+        Str,

+        L"UsbTestAndMeasurement(0x%x,0x%x,0x%x)",

+        UsbClass->VendorId,

+        UsbClass->ProductId,

+        UsbClass->DeviceProtocol

+        );

+      return;

+    }

+  }

+

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"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.

+

+**/

+VOID

+DevPathToTextSata (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  SATA_DEVICE_PATH *Sata;

+

+  Sata = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"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.

+

+**/

+VOID

+DevPathToTextI2O (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  I2O_DEVICE_PATH *I2ODevPath;

+

+  I2ODevPath = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+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, L"MAC(");

+

+  for (Index = 0; Index < HwAddressSize; Index++) {

+    UefiDevicePathLibCatPrint (Str, L"%02x", MacDevPath->MacAddress.Addr[Index]);

+  }

+

+  UefiDevicePathLibCatPrint (Str, L",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.

+

+**/

+VOID

+CatNetworkProtocol (

+  IN OUT POOL_PRINT  *Str,

+  IN UINT16          Protocol

+  )

+{

+  if (Protocol == RFC_1700_TCP_PROTOCOL) {

+    UefiDevicePathLibCatPrint (Str, L"TCP");

+  } else if (Protocol == RFC_1700_UDP_PROTOCOL) {

+    UefiDevicePathLibCatPrint (Str, L"UDP");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"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.

+**/

+VOID

+CatIPv4Address (

+  IN OUT POOL_PRINT   *Str,

+  IN EFI_IPv4_ADDRESS *Address

+  )

+{

+  UefiDevicePathLibCatPrint (Str, L"%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.

+**/

+VOID

+CatIPv6Address (

+  IN OUT POOL_PRINT   *Str,

+  IN EFI_IPv6_ADDRESS *Address

+  )

+{

+  UefiDevicePathLibCatPrint (

+    Str, L"%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.

+

+**/

+VOID

+DevPathToTextIPv4 (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  IPv4_DEVICE_PATH  *IPDevPath;

+

+  IPDevPath = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"IPv4(");

+  CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);

+

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L")");

+    return ;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L",");

+  CatNetworkProtocol (Str, IPDevPath->Protocol);

+

+  UefiDevicePathLibCatPrint (Str, L",%s,", IPDevPath->StaticIpAddress ? L"Static" : L"DHCP");

+  CatIPv4Address (Str, &IPDevPath->LocalIpAddress);

+  if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {

+    UefiDevicePathLibCatPrint (Str, L",");

+    CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);

+    UefiDevicePathLibCatPrint (Str, L",");

+    CatIPv4Address (Str, &IPDevPath->SubnetMask);

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  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.

+

+**/

+VOID

+DevPathToTextIPv6 (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  IPv6_DEVICE_PATH  *IPDevPath;

+

+  IPDevPath = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"IPv6(");

+  CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L")");

+    return ;

+  }

+  

+  UefiDevicePathLibCatPrint (Str, L",");

+  CatNetworkProtocol (Str, IPDevPath->Protocol);

+

+  switch (IPDevPath->IpAddressOrigin) {

+    case 0:

+      UefiDevicePathLibCatPrint (Str, L",Static,");

+      break;

+    case 1:

+      UefiDevicePathLibCatPrint (Str, L",StatelessAutoConfigure,");

+      break;

+    default:

+      UefiDevicePathLibCatPrint (Str, L",StatefulAutoConfigure,");

+      break;

+  }

+

+  CatIPv6Address (Str, &IPDevPath->LocalIpAddress);

+

+  if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {

+    UefiDevicePathLibCatPrint (Str, L",0x%x,", IPDevPath->PrefixLength);

+    CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);

+  }

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+/**

+  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.

+

+**/

+VOID

+DevPathToTextInfiniBand (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  INFINIBAND_DEVICE_PATH  *InfiniBand;

+

+  InfiniBand = DevPath;

+  UefiDevicePathLibCatPrint (

+    Str,

+    L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)",

+    InfiniBand->ResourceFlags,

+    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.

+

+**/

+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, L"Uart(DEFAULT,");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"Uart(%ld,", Uart->BaudRate);

+  }

+

+  if (Uart->DataBits == 0) {

+    UefiDevicePathLibCatPrint (Str, L"DEFAULT,");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"%d,", Uart->DataBits);

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"%c,", Parity);

+

+  switch (Uart->StopBits) {

+  case 0:

+    UefiDevicePathLibCatPrint (Str, L"D)");

+    break;

+

+  case 1:

+    UefiDevicePathLibCatPrint (Str, L"1)");

+    break;

+

+  case 2:

+    UefiDevicePathLibCatPrint (Str, L"1.5)");

+    break;

+

+  case 3:

+    UefiDevicePathLibCatPrint (Str, L"2)");

+    break;

+

+  default:

+    UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+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,

+    L"iSCSI(%a,0x%x,0x%lx,",

+    ISCSIDevPath->TargetName,

+    ISCSIDevPath->TargetPortalGroupTag,

+    ISCSIDevPath->Lun

+    );

+

+  Options = ISCSIDevPath->LoginOption;

+  UefiDevicePathLibCatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");

+  UefiDevicePathLibCatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");

+  if (((Options >> 11) & 0x0001) != 0) {

+    UefiDevicePathLibCatPrint (Str, L"%s,", L"None");

+  } else if (((Options >> 12) & 0x0001) != 0) {

+    UefiDevicePathLibCatPrint (Str, L"%s,", L"CHAP_UNI");

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"%s,", L"CHAP_BI");

+

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"%s)", (ISCSIDevPath->NetworkProtocol == 0) ? L"TCP" : L"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.

+

+**/

+VOID

+DevPathToTextVlan (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  VLAN_DEVICE_PATH  *Vlan;

+

+  Vlan = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"Vlan(%d)", Vlan->VlanId);

+}

+

+/**

+  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.

+

+**/

+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,

+      L"HD(%d,%s,0x%08x,",

+      Hd->PartitionNumber,

+      L"MBR",

+      *((UINT32 *) (&(Hd->Signature[0])))

+      );

+    break;

+

+  case SIGNATURE_TYPE_GUID:

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"HD(%d,%s,%g,",

+      Hd->PartitionNumber,

+      L"GPT",

+      (EFI_GUID *) &(Hd->Signature[0])

+      );

+    break;

+

+  default:

+    UefiDevicePathLibCatPrint (

+      Str,

+      L"HD(%d,%d,0,",

+      Hd->PartitionNumber,

+      Hd->SignatureType

+      );

+    break;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+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, L"CDROM(0x%x)", Cd->BootEntry);

+    return ;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L"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.

+

+**/

+VOID

+DevPathToTextFilePath (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  FILEPATH_DEVICE_PATH  *Fp;

+

+  Fp = DevPath;

+  UefiDevicePathLibCatPrint (Str, L"%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.

+

+**/

+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, L"Media(%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.

+

+**/

+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, L"Fv(%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.

+

+**/

+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, L"FvFile(%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.

+

+**/

+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,

+    L"Offset(0x%lx,0x%lx)",

+    Offset->StartingOffset,

+    Offset->EndingOffset

+    );

+}

+

+/**

+  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.

+

+**/

+VOID

+DevPathToTextBBS (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  BBS_BBS_DEVICE_PATH *Bbs;

+  CHAR16              *Type;

+

+  Bbs = DevPath;

+  switch (Bbs->DeviceType) {

+  case BBS_TYPE_FLOPPY:

+    Type = L"Floppy";

+    break;

+

+  case BBS_TYPE_HARDDRIVE:

+    Type = L"HD";

+    break;

+

+  case BBS_TYPE_CDROM:

+    Type = L"CDROM";

+    break;

+

+  case BBS_TYPE_PCMCIA:

+    Type = L"PCMCIA";

+    break;

+

+  case BBS_TYPE_USB:

+    Type = L"USB";

+    break;

+

+  case BBS_TYPE_EMBEDDED_NETWORK:

+    Type = L"Network";

+    break;

+

+  default:

+    Type = NULL;

+    break;

+  }

+

+  if (Type != NULL) {

+    UefiDevicePathLibCatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);

+  } else {

+    UefiDevicePathLibCatPrint (Str, L"BBS(0x%x,%a", Bbs->DeviceType, Bbs->String);

+  }

+

+  if (DisplayOnly) {

+    UefiDevicePathLibCatPrint (Str, L")");

+    return ;

+  }

+

+  UefiDevicePathLibCatPrint (Str, L",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.

+

+**/

+VOID

+DevPathToTextEndInstance (

+  IN OUT POOL_PRINT  *Str,

+  IN VOID            *DevPath,

+  IN BOOLEAN         DisplayOnly,

+  IN BOOLEAN         AllowShortcuts

+  )

+{

+  UefiDevicePathLibCatPrint (Str, L",");

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_GENERIC_TABLE mUefiDevicePathLibToTextTableGeneric[] = {

+  {HARDWARE_DEVICE_PATH,  L"HardwarePath"   },

+  {ACPI_DEVICE_PATH,      L"AcpiPath"       },

+  {MESSAGING_DEVICE_PATH, L"Msg"            },

+  {MEDIA_DEVICE_PATH,     L"MediaPath"      },

+  {BBS_DEVICE_PATH,       L"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.

+

+**/

+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, L"Path(%d,%d", DevicePathType (Node), DevicePathSubType (Node));

+  } else {

+    //

+    // It's a node whose type can be recognized

+    //

+    UefiDevicePathLibCatPrint (Str, L"%s(%d", mUefiDevicePathLibToTextTableGeneric[Index].Text, DevicePathSubType (Node));

+  }

+

+  Index = sizeof (EFI_DEVICE_PATH_PROTOCOL);

+  if (Index < DevicePathNodeLength (Node)) {

+    UefiDevicePathLibCatPrint (Str, L",");

+    for (; Index < DevicePathNodeLength (Node); Index++) {

+      UefiDevicePathLibCatPrint (Str, L"%02x", ((UINT8 *) Node)[Index]);

+    }

+  }

+

+  UefiDevicePathLibCatPrint (Str, L")");

+}

+

+GLOBAL_REMOVE_IF_UNREFERENCED 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     },

+  {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_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           },

+  {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  },

+  {BBS_DEVICE_PATH,       BBS_BBS_DP,                       DevPathToTextBBS            },

+  {END_DEVICE_PATH_TYPE,  END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance    },

+  {0, 0, NULL}

+};

+

+/**

+  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;

+}

+

+/**

+  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

+  )

+{

+  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 = (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] != L',') {

+        UefiDevicePathLibCatPrint (&Str, L"/");

+      }

+    }

+    

+    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;

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
new file mode 100644
index 0000000..7f21a60
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
@@ -0,0 +1,878 @@
+/** @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 - 2014, 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"

+

+//

+// Template for an end-of-device path node.

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL  mUefiDevicePathLibEndDevicePath = {

+  END_DEVICE_PATH_TYPE,

+  END_ENTIRE_DEVICE_PATH_SUBTYPE,

+  {

+    END_DEVICE_PATH_LENGTH,

+    0

+  }

+};

+

+/**

+  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);

+

+  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {

+    NodeLength = DevicePathNodeLength (DevicePath);

+    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {

+      return FALSE;

+    }

+

+    if (MaxSize > 0) {

+      Size += NodeLength;

+      if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {

+        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 ((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 ((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 ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);

+}

+

+/**

+  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 *)((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);

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Node != NULL);

+  return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);

+}

+

+/**

+  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));

+}

+

+/**

+  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);

+  CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));

+}

+

+/**

+  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

+  )

+{

+  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);

+}

+

+/**

+  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

+  )

+{

+  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

+UefiDevicePathLibAppendDevicePath (

+  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

+UefiDevicePathLibAppendDevicePathNode (

+  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;

+}

+

+/**

+  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

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

+  UINTN                     SrcSize;

+  UINTN                     InstanceSize;

+

+  if (DevicePath == NULL) {

+    return DuplicateDevicePath (DevicePathInstance);

+  }

+

+  if (DevicePathInstance == NULL) {

+    return NULL;

+  }

+

+  if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) {

+    return NULL;

+  }

+

+  SrcSize       = GetDevicePathSize (DevicePath);

+  InstanceSize  = GetDevicePathSize (DevicePathInstance);

+

+  NewDevicePath = AllocatePool (SrcSize + InstanceSize);

+  if (NewDevicePath != NULL) {

+    

+    TempDevicePath = CopyMem (NewDevicePath, DevicePath, SrcSize);;

+ 

+    while (!IsDevicePathEnd (TempDevicePath)) {

+      TempDevicePath = NextDevicePathNode (TempDevicePath);

+    }

+    

+    TempDevicePath->SubType  = END_INSTANCE_DEVICE_PATH_SUBTYPE;

+    TempDevicePath           = NextDevicePathNode (TempDevicePath);

+    CopyMem (TempDevicePath, DevicePathInstance, InstanceSize);

+  }

+

+  return NewDevicePath;

+}

+

+/**

+  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

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;

+  EFI_DEVICE_PATH_PROTOCOL  *ReturnValue;

+  UINT8                     Temp;

+

+  ASSERT (Size != NULL);

+

+  if (DevicePath == NULL || *DevicePath == NULL) {

+    *Size = 0;

+    return NULL;

+  }

+

+  if (!IsDevicePathValid (*DevicePath, 0)) {

+    return NULL;

+  }

+

+  //

+  // Find the end of the device path instance

+  //

+  DevPath = *DevicePath;

+  while (!IsDevicePathEndType (DevPath)) {

+    DevPath = NextDevicePathNode (DevPath);

+  }

+

+  //

+  // Compute the size of the device path instance

+  //

+  *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);

+ 

+  //

+  // Make a copy and return the device path instance

+  //

+  Temp              = DevPath->SubType;

+  DevPath->SubType  = END_ENTIRE_DEVICE_PATH_SUBTYPE;

+  ReturnValue       = DuplicateDevicePath (*DevicePath);

+  DevPath->SubType  = Temp;

+

+  //

+  // If DevPath is the end of an entire device path, then another instance

+  // does not follow, so *DevicePath is set to NULL.

+  //

+  if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {

+    *DevicePath = NULL;

+  } else {

+    *DevicePath = NextDevicePathNode (DevPath);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  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

+  )

+{

+  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;

+}

+

+/**

+  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

+  )

+{

+  CONST EFI_DEVICE_PATH_PROTOCOL     *Node;

+

+  if (DevicePath == NULL) {

+    return FALSE;

+  }

+

+  if (!IsDevicePathValid (DevicePath, 0)) {

+    return FALSE;

+  }

+

+  Node = DevicePath;

+  while (!IsDevicePathEnd (Node)) {

+    if (IsDevicePathEndInstance (Node)) {

+      return TRUE;

+    }

+

+    Node = NextDevicePathNode (Node);

+  }

+

+  return FALSE;

+}

+

+

+/**

+  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

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_STATUS                Status;

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID *) &DevicePath

+                  );

+  if (EFI_ERROR (Status)) {

+    DevicePath = NULL;

+  }

+  return DevicePath;

+}

+

+/**

+  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

+  )

+{

+  UINTN                     Size;

+  FILEPATH_DEVICE_PATH      *FilePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *FileDevicePath;

+

+  DevicePath = NULL;

+

+  Size = StrSize (FileName);

+  FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);

+  if (FileDevicePath != NULL) {

+    FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;

+    FilePath->Header.Type    = MEDIA_DEVICE_PATH;

+    FilePath->Header.SubType = MEDIA_FILEPATH_DP;

+    CopyMem (&FilePath->PathName, FileName, Size);

+    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);

+    SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));

+

+    if (Device != NULL) {

+      DevicePath = DevicePathFromHandle (Device);

+    }

+

+    DevicePath = AppendDevicePath (DevicePath, FileDevicePath);

+    FreePool (FileDevicePath);

+  }

+

+  return DevicePath;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
new file mode 100644
index 0000000..baad7bc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
@@ -0,0 +1,360 @@
+/** @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 - 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.             

+

+**/

+

+

+#include "UefiDevicePathLib.h"

+

+/**

+  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

+  )

+{

+  return UefiDevicePathLibGetDevicePathSize (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

+  )

+{

+  return UefiDevicePathLibDuplicateDevicePath (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

+  )

+{

+  return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);

+}

+

+/**

+  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

+  )

+{

+  return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);

+}

+

+/**

+  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

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

+  )

+{

+  return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);

+}

+

+/**

+  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

+  )

+{

+  return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, 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

+  )

+{

+  return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, 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

+  )

+{

+  return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);

+}

+

+/**

+  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

+  )

+{

+  return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+}

+

+/**

+  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

+  )

+{

+  return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, 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

+  )

+{

+  return UefiDevicePathLibConvertTextToDeviceNode (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

+  )

+{

+  return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
new file mode 100644
index 0000000..233844c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
@@ -0,0 +1,456 @@
+/** @file

+  Definition for Device Path library.

+

+Copyright (c) 2013 - 2014, 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>

+

+#define IS_COMMA(a)                ((a) == L',')

+#define IS_HYPHEN(a)               ((a) == L'-')

+#define IS_DOT(a)                  ((a) == L'.')

+#define IS_LEFT_PARENTH(a)         ((a) == L'(')

+#define IS_RIGHT_PARENTH(a)        ((a) == L')')

+#define IS_SLASH(a)                ((a) == L'/')

+#define IS_NULL(a)                 ((a) == L'\0')

+

+

+//

+// Private Data structure

+//

+typedef struct {

+  CHAR16  *Str;

+  UINTN   Count;

+  UINTN   Capacity;

+} POOL_PRINT;

+

+typedef

+EFI_DEVICE_PATH_PROTOCOL  *

+(*DEVICE_PATH_FROM_TEXT) (

+  IN  CHAR16 *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;

+  CHAR16               *Text;

+} DEVICE_PATH_TO_TEXT_GENERIC_TABLE;

+

+typedef struct {

+  CHAR16                    *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()

+

+/**

+  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

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
new file mode 100644
index 0000000..f4ae91f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
@@ -0,0 +1,71 @@
+## @file

+# Instance of Device Path Library based on Memory Allocation Library.

+#

+# Device Path Library that layers on top of the Memory Allocation Library.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDevicePathLib

+  MODULE_UNI_FILE                = UefiDevicePathLib.uni

+  FILE_GUID                      = 91c1677a-e57f-4191-8b8e-eb7711a716e0

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DevicePathLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DevicePathUtilities.c

+  DevicePathToText.c

+  DevicePathFromText.c

+  UefiDevicePathLib.c

+  UefiDevicePathLib.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  MemoryAllocationLib

+  DebugLib

+  BaseMemoryLib

+  PcdLib

+  PrintLib

+

+[Guids]

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiVTUTF8Guid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiVT100Guid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiVT100PlusGuid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiPcAnsiGuid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiUartDevicePathGuid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiSasDevicePathGuid

+

+[Protocols]

+  gEfiDevicePathProtocolGuid                    ## SOMETIMES_CONSUMES

+  gEfiDebugPortProtocolGuid                     ## UNDEFINED

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount    ## SOMETIMES_CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.uni
new file mode 100644
index 0000000..1a3d37a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c
new file mode 100644
index 0000000..9580e39
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c
@@ -0,0 +1,484 @@
+/** @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) 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.             

+

+**/

+

+

+#include "UefiDevicePathLib.h"

+

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *mDevicePathLibDevicePathToText    = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText  = NULL;

+

+/**

+  The constructor function caches the pointer to DevicePathUtilites protocol,

+  DevicePathToText protocol and DevicePathFromText protocol.

+  

+  The constructor function locates these three protocols from protocol database.

+  It will caches the pointer to local protocol instance if that operation fails

+  and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiDevicePathLibOptionalDevicePathProtocolConstructor (

+  IN      EFI_HANDLE                ImageHandle,

+  IN      EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiDevicePathUtilitiesProtocolGuid,

+                  NULL,

+                  (VOID**) &mDevicePathLibDevicePathUtilities

+                  );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mDevicePathLibDevicePathUtilities != NULL);

+  return Status;

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);

+  } else {

+    return UefiDevicePathLibGetDevicePathSize (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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);

+  } else {

+    return UefiDevicePathLibDuplicateDevicePath (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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);

+  } else {

+    return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);

+  }

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);

+  } else {

+    return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);

+  }

+}

+

+/**

+  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

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);

+  } else {

+    return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);

+  }

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);

+  } else {

+    return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, 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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);

+  } else {

+    return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, 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

+  )

+{

+  if (mDevicePathLibDevicePathUtilities != NULL) {

+    return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);

+  } else {

+    return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);

+  }

+}

+

+/**

+  Locate and return the protocol instance identified by the ProtocolGuid.

+

+  @param ProtocolGuid     The GUID of the protocol.

+

+  @return A pointer to the protocol instance or NULL when absent.

+**/

+VOID *

+UefiDevicePathLibLocateProtocol (

+  EFI_GUID                         *ProtocolGuid

+  )

+{

+  EFI_STATUS Status;

+  VOID       *Protocol;

+  Status = gBS->LocateProtocol (

+                  ProtocolGuid,

+                  NULL,

+                  (VOID**) &Protocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  } else {

+    return Protocol;

+  }

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+  }

+

+  return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);

+  }

+

+  return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, 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

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);

+  }

+

+  return UefiDevicePathLibConvertTextToDeviceNode (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

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);

+  }

+

+  return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
new file mode 100644
index 0000000..943ba2d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
@@ -0,0 +1,81 @@
+## @file

+# Instance of Device Path Library based on Device Path Protocol.

+#

+#  Device Path Library that layers on top of the UEFI 2.0 Device Path Protocol.

+#  If the DevicePathFromText/DevicePathToText protocol doesn't exist, the library

+#  uses its internal conversion logic.

+#

+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDevicePathLibOptionalDevicePathProtocol

+  MODULE_UNI_FILE                = UefiDevicePathLibOptionalDevicePathProtocol.uni

+  FILE_GUID                      = 3E1C696D-FCF0-45a7-85A7-E86C2A1C1080

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+  CONSTRUCTOR                    = UefiDevicePathLibOptionalDevicePathProtocolConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DevicePathUtilities.c

+  DevicePathToText.c

+  DevicePathFromText.c

+  UefiDevicePathLibOptionalDevicePathProtocol.c

+  UefiDevicePathLib.h

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  UefiBootServicesTableLib

+  MemoryAllocationLib

+  DebugLib

+  BaseMemoryLib

+  PcdLib

+  PrintLib

+

+[Guids]

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiVTUTF8Guid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiVT100Guid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiVT100PlusGuid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiPcAnsiGuid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiUartDevicePathGuid

+  ## SOMETIMES_CONSUMES  ## GUID

+  gEfiSasDevicePathGuid

+

+[Protocols]

+  gEfiDevicePathProtocolGuid                    ## SOMETIMES_CONSUMES

+  gEfiDevicePathUtilitiesProtocolGuid           ## CONSUMES

+  gEfiDevicePathToTextProtocolGuid              ## SOMETIMES_CONSUMES

+  gEfiDevicePathFromTextProtocolGuid            ## SOMETIMES_CONSUMES

+  gEfiDebugPortProtocolGuid                     ## UNDEFINED

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount ## SOMETIMES_CONSUMES

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiDevicePathUtilitiesProtocolGuid

+  
\ No newline at end of file
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.uni b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.uni
new file mode 100644
index 0000000..e33598a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
new file mode 100644
index 0000000..5cc4b35
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
@@ -0,0 +1,846 @@
+/** @file

+  Library instance that implement UEFI Device Path Library class based on protocol

+  gEfiDevicePathUtilitiesProtocolGuid.

+

+  Copyright (c) 2006 - 2014, 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 <Uefi.h>

+

+#include <Protocol/DevicePathUtilities.h>

+#include <Protocol/DevicePathToText.h>

+#include <Protocol/DevicePathFromText.h>

+

+#include <Library/DevicePathLib.h>

+#include <Library/DebugLib.h>

+#include <Library/BaseLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/PcdLib.h>

+

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   *mDevicePathLibDevicePathToText    = NULL;

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText  = NULL;

+

+//

+// Template for an end-of-device path node.

+//

+GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL  mUefiDevicePathLibEndDevicePath = {

+  END_DEVICE_PATH_TYPE,

+  END_ENTIRE_DEVICE_PATH_SUBTYPE,

+  {

+    END_DEVICE_PATH_LENGTH,

+    0

+  }

+};

+

+/**

+  The constructor function caches the pointer to DevicePathUtilites protocol.

+  

+  The constructor function locates DevicePathUtilities protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+DevicePathLibConstructor (

+  IN      EFI_HANDLE                ImageHandle,

+  IN      EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS                        Status;

+

+  Status = gBS->LocateProtocol (

+                  &gEfiDevicePathUtilitiesProtocolGuid,

+                  NULL,

+                  (VOID**) &mDevicePathLibDevicePathUtilities

+                  );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mDevicePathLibDevicePathUtilities != NULL);

+  return Status;

+}

+

+/**

+  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);

+

+  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {

+    NodeLength = DevicePathNodeLength (DevicePath);

+    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {

+      return FALSE;

+    }

+

+    if (MaxSize > 0) {

+      Size += NodeLength;

+      if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {

+        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 ((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 ((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 ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);

+}

+

+/**

+  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 *)((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);

+}

+

+/**

+  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

+  )

+{

+  ASSERT (Node != NULL);

+  return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);

+}

+

+/**

+  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));

+}

+

+/**

+  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);

+  CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));

+}

+

+/**

+  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

+  )

+{

+  return mDevicePathLibDevicePathUtilities->GetDevicePathSize (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    If 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

+  )

+{

+  return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (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

+  )

+{

+  return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);

+}

+

+/**

+  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

+  )

+{

+  return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);

+}

+

+/**

+  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

+AppendDevicePathInstance (

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,        OPTIONAL

+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePathInstance OPTIONAL

+  )

+{

+  return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);

+}

+

+/**

+  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 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

+  )

+{

+  ASSERT (Size != NULL);

+  return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, 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

+  )

+{

+  return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, 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

+  )

+{

+  return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (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

+  )

+{

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_STATUS                Status;

+

+  Status = gBS->HandleProtocol (

+                  Handle,

+                  &gEfiDevicePathProtocolGuid,

+                  (VOID *) &DevicePath

+                  );

+  if (EFI_ERROR (Status)) {

+    DevicePath = NULL;

+  }

+  return DevicePath;

+}

+

+/**

+  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

+  )

+{

+  UINTN                     Size;

+  FILEPATH_DEVICE_PATH      *FilePath;

+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

+  EFI_DEVICE_PATH_PROTOCOL  *FileDevicePath;

+

+  DevicePath = NULL;

+

+  Size = StrSize (FileName);

+  FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);

+  if (FileDevicePath != NULL) {

+    FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;

+    FilePath->Header.Type    = MEDIA_DEVICE_PATH;

+    FilePath->Header.SubType = MEDIA_FILEPATH_DP;

+    CopyMem (&FilePath->PathName, FileName, Size);

+    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);

+    SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));

+

+    if (Device != NULL) {

+      DevicePath = DevicePathFromHandle (Device);

+    }

+

+    DevicePath = AppendDevicePath (DevicePath, FileDevicePath);

+    FreePool (FileDevicePath);

+  }

+

+  return DevicePath;

+}

+

+/**

+  Locate and return the protocol instance identified by the ProtocolGuid.

+

+  @param ProtocolGuid     The GUID of the protocol.

+

+  @return A pointer to the protocol instance or NULL when absent.

+**/

+VOID *

+UefiDevicePathLibLocateProtocol (

+  EFI_GUID                         *ProtocolGuid

+  )

+{

+  EFI_STATUS Status;

+  VOID       *Protocol;

+  Status = gBS->LocateProtocol (

+                  ProtocolGuid,

+                  NULL,

+                  (VOID**) &Protocol

+                  );

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  } else {

+    return Protocol;

+  }

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);

+  } else {

+    return NULL;

+  }

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathToText == NULL) {

+    mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathToText != NULL) {

+    return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);

+  } else {

+    return 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.

+

+**/

+EFI_DEVICE_PATH_PROTOCOL *

+EFIAPI

+ConvertTextToDeviceNode (

+  IN CONST CHAR16 *TextDeviceNode

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);

+  } else {

+    return NULL;

+  }

+}

+

+/**

+  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

+  )

+{

+  if (mDevicePathLibDevicePathFromText == NULL) {

+    mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);

+  }

+  if (mDevicePathLibDevicePathFromText != NULL) {

+    return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);

+  } else {

+    return NULL;

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
new file mode 100644
index 0000000..5cab72e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
@@ -0,0 +1,61 @@
+## @file

+# Instance of Device Path Library based on Device Path Utilities Protocol.

+#

+#  Device Path Library that layers on top of the UEFI 2.0 Device Path Utilities Protocol.

+#  This library is not available for EFI 1.10 modules.

+#

+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDevicePathLibDevicePathProtocol

+  MODULE_UNI_FILE                = UefiDevicePathLibDevicePathProtocol.uni

+  FILE_GUID                      = 050EB8C6-C12E-4b86-892B-40985E8B3137

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+  CONSTRUCTOR                    = DevicePathLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  UefiDevicePathLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+  BaseMemoryLib

+  MemoryAllocationLib

+  BaseLib

+  DebugLib

+  PcdLib

+

+[Protocols]

+  gEfiDevicePathProtocolGuid                    ## SOMETIMES_CONSUMES

+  gEfiDevicePathUtilitiesProtocolGuid           ## CONSUMES

+  gEfiDevicePathToTextProtocolGuid              ## SOMETIMES_CONSUMES

+  gEfiDevicePathFromTextProtocolGuid            ## SOMETIMES_CONSUMES

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount    ## SOMETIMES_CONSUMES

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiDevicePathUtilitiesProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.uni b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.uni
new file mode 100644
index 0000000..37c327e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c b/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c
new file mode 100644
index 0000000..f5da5ac
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c
@@ -0,0 +1,173 @@
+/** @file

+  Entry point to a EFI/DXE driver.

+

+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

+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 <Uefi.h>

+

+#include <Protocol/LoadedImage.h>

+

+#include <Library/UefiDriverEntryPoint.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+

+/**

+  Unloads an image from memory.

+

+  This function is a callback that a driver registers to do cleanup 

+  when the UnloadImage boot service function is called.

+

+  @param  ImageHandle The handle to the image to unload.

+

+  @return Status returned by all unload().

+

+**/

+EFI_STATUS

+EFIAPI

+_DriverUnloadHandler (

+  EFI_HANDLE ImageHandle

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // If an UnloadImage() handler is specified, then call it

+  //

+  Status = ProcessModuleUnloadList (ImageHandle);

+

+  //

+  // If the driver specific unload handler does not return an error, then call all of the

+  // library destructors.  If the unload handler returned an error, then the driver can not be

+  // unloaded, and the library destructors should not be called

+  //

+  if (!EFI_ERROR (Status)) {

+    ProcessLibraryDestructorList (ImageHandle, gST);

+  }

+

+  //

+  // Return the status from the driver specific unload handler

+  //

+  return Status;

+}

+

+

+/**

+  The entry point of PE/COFF Image for a DXE Driver, DXE Runtime Driver, DXE SMM 

+  Driver, or UEFI Driver. 

+

+  This function is the entry point for a DXE Driver, DXE Runtime Driver, DXE SMM Driver,

+  or UEFI Driver.  This function must call ProcessLibraryConstructorList() and

+  ProcessModuleEntryPointList(). If the return status from ProcessModuleEntryPointList()

+  is an error status, then ProcessLibraryDestructorList() must be called. The return 

+  value from ProcessModuleEntryPointList() is returned. If _gDriverUnloadImageCount 

+  is greater than zero, then an unload handler must be registered for this image 

+  and the unload handler must invoke ProcessModuleUnloadList().

+  If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than 

+  _gUefiDriverRevison, then return EFI_INCOMPATIBLE_VERSION.

+

+

+  @param  ImageHandle  The image handle of the DXE Driver, DXE Runtime Driver, 

+                       DXE SMM Driver, or UEFI Driver.

+  @param  SystemTable  A pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS               The DXE Driver, DXE Runtime Driver, DXE SMM 

+                                     Driver, or UEFI Driver exited normally.

+  @retval  EFI_INCOMPATIBLE_VERSION  _gUefiDriverRevision is greater than 

+                                    SystemTable->Hdr.Revision.

+  @retval  Other                     Return value from ProcessModuleEntryPointList().

+

+**/

+EFI_STATUS

+EFIAPI

+_ModuleEntryPoint (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                 Status;

+  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;

+

+  if (_gUefiDriverRevision != 0) {

+    //

+    // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver

+    //

+    if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {

+      return EFI_INCOMPATIBLE_VERSION;

+    }

+  }

+

+  //

+  // Call constructor for all libraries

+  //

+  ProcessLibraryConstructorList (ImageHandle, SystemTable);

+

+  //

+  //  Install unload handler...

+  //

+  if (_gDriverUnloadImageCount != 0) {

+    Status = gBS->HandleProtocol (

+                    ImageHandle,

+                    &gEfiLoadedImageProtocolGuid,

+                    (VOID **)&LoadedImage

+                    );

+    ASSERT_EFI_ERROR (Status);

+    LoadedImage->Unload = _DriverUnloadHandler;

+  }

+

+  //

+  // Call the driver entry point

+  //

+  Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);

+

+  //

+  // If all of the drivers returned errors, then invoke all of the library destructors

+  //

+  if (EFI_ERROR (Status)) {

+    ProcessLibraryDestructorList (ImageHandle, SystemTable);

+  }

+

+  //

+  // Return the cummalative return status code from all of the driver entry points

+  //

+  return Status;

+}

+

+

+/**

+  Required by the EBC compiler and identical in functionality to _ModuleEntryPoint(). 

+

+  This function is required to call _ModuleEntryPoint() passing in ImageHandle,

+  and SystemTable.

+

+  @param  ImageHandle  The image handle of the DXE Driver, DXE Runtime Driver, DXE 

+                       SMM Driver, or UEFI Driver.

+  @param  SystemTable  A pointer to the EFI System Table.

+

+  @retval  EFI_SUCCESS               The DXE Driver, DXE Runtime Driver, DXE SMM 

+                                     Driver, or UEFI Driver exited normally.

+  @retval  EFI_INCOMPATIBLE_VERSION  _gUefiDriverRevision is greater than 

+                                     SystemTable->Hdr.Revision.

+  @retval  Other                     Return value from ProcessModuleEntryPointList().

+**/

+EFI_STATUS

+EFIAPI

+EfiMain (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return _ModuleEntryPoint (ImageHandle, SystemTable);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf b/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
new file mode 100644
index 0000000..7a9dcbc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
@@ -0,0 +1,67 @@
+## @file

+# Module entry point library for UEFI driver, DXE driver and SMM driver.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiDriverEntryPoint

+  MODULE_UNI_FILE                = UefiDriverEntryPoint.uni

+  FILE_GUID                      = 331deb15-454b-48d8-9b74-70d01f3f3556

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  DriverEntryPoint.c

+

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+  DebugLib

+  BaseLib

+

+

+[Protocols]

+  gEfiLoadedImageProtocolGuid                   ## SOMETIMES_CONSUMES

+

+

+#

+# For UEFI drivers, these architectural protocols defined in PI 1.0 spec need

+# to be appended and merged to the final dependency section.

+#

+[Depex.common.UEFI_DRIVER]

+  gEfiBdsArchProtocolGuid AND

+  gEfiCpuArchProtocolGuid AND

+  gEfiMetronomeArchProtocolGuid AND

+  gEfiMonotonicCounterArchProtocolGuid AND

+  gEfiRealTimeClockArchProtocolGuid AND

+  gEfiResetArchProtocolGuid AND

+  gEfiRuntimeArchProtocolGuid AND

+  gEfiSecurityArchProtocolGuid AND

+  gEfiTimerArchProtocolGuid AND

+  gEfiVariableWriteArchProtocolGuid AND

+  gEfiVariableArchProtocolGuid AND

+  gEfiWatchdogTimerArchProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.uni b/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.uni
new file mode 100644
index 0000000..9be80af
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.c
new file mode 100644
index 0000000..be66c57
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.c
@@ -0,0 +1,1155 @@
+/** @file

+  Provides interface to EFI_FILE_HANDLE functionality.

+

+  Copyright (c) 2006 - 2014, 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 <Uefi.h>

+

+#include <Protocol/SimpleFileSystem.h>

+#include <Protocol/UnicodeCollation.h>

+

+#include <Guid/FileInfo.h>

+

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/FileHandleLib.h>

+#include <Library/PcdLib.h>

+#include <Library/PrintLib.h>

+

+CONST UINT16 gUnicodeFileTag = EFI_UNICODE_BYTE_ORDER_MARK;

+

+#define MAX_FILE_NAME_LEN 522 // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes)

+#define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)

+

+/**

+  This function will retrieve the information about the file for the handle

+  specified and store it in allocated pool memory.

+

+  This function allocates a buffer to store the file's information. It is the

+  caller's responsibility to free the buffer

+

+  @param  FileHandle  The file handle of the file for which information is

+  being requested.

+

+  @retval NULL information could not be retrieved.

+

+  @return the information about the file

+**/

+EFI_FILE_INFO*

+EFIAPI

+FileHandleGetInfo (

+  IN EFI_FILE_HANDLE            FileHandle

+  )

+{

+  EFI_FILE_INFO   *FileInfo;

+  UINTN           FileInfoSize;

+  EFI_STATUS      Status;

+

+  if (FileHandle == NULL) {

+    return (NULL);

+  }

+

+  //

+  // Get the required size to allocate

+  //

+  FileInfoSize = 0;

+  FileInfo = NULL;

+  Status = FileHandle->GetInfo(FileHandle,

+                               &gEfiFileInfoGuid,

+                               &FileInfoSize,

+                               NULL);

+  if (Status == EFI_BUFFER_TOO_SMALL){

+    //

+    // error is expected.  getting size to allocate

+    //

+    FileInfo = AllocateZeroPool(FileInfoSize);

+    //

+    // now get the information

+    //

+    Status = FileHandle->GetInfo(FileHandle,

+                                 &gEfiFileInfoGuid,

+                                 &FileInfoSize,

+                                 FileInfo);

+    //

+    // if we got an error free the memory and return NULL

+    //

+    if (EFI_ERROR(Status) && (FileInfo != NULL)) {

+      FreePool(FileInfo);

+      FileInfo = NULL;

+    }

+  }

+  return (FileInfo);

+}

+

+/**

+  This function sets the information about the file for the opened handle

+  specified.

+

+  @param[in]  FileHandle        The file handle of the file for which information

+                                is being set.

+

+  @param[in]  FileInfo          The information to set.

+

+  @retval EFI_SUCCESS           The information was set.

+  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.

+  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.

+  @retval EFI_NO_MEDIA          The device has no medium.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.

+  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.

+  @retval EFI_ACCESS_DENIED     The file was opened read only.

+  @retval EFI_VOLUME_FULL       The volume is full.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleSetInfo (

+  IN EFI_FILE_HANDLE            FileHandle,

+  IN CONST EFI_FILE_INFO        *FileInfo

+  )

+{

+

+  if (FileHandle == NULL || FileInfo == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Set the info

+  //

+  return (FileHandle->SetInfo(FileHandle,

+                              &gEfiFileInfoGuid,

+                              (UINTN)FileInfo->Size,

+                              (EFI_FILE_INFO*)FileInfo));

+}

+

+/**

+  This function reads information from an opened file.

+

+  If FileHandle is not a directory, the function reads the requested number of

+  bytes from the file at the file's current position and returns them in Buffer.

+  If the read goes beyond the end of the file, the read length is truncated to the

+  end of the file. The file's current position is increased by the number of bytes

+  returned.  If FileHandle is a directory, the function reads the directory entry

+  at the file's current position and returns the entry in Buffer. If the Buffer

+  is not large enough to hold the current directory entry, then

+  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.

+  BufferSize is set to be the size of the buffer needed to read the entry. On

+  success, the current position is updated to the next directory entry. If there

+  are no more directory entries, the read returns a zero-length buffer.

+  EFI_FILE_INFO is the structure returned as the directory entry.

+

+  @param FileHandle             the opened file handle

+  @param BufferSize             on input the size of buffer in bytes.  on return

+                                the number of bytes written.

+  @param Buffer                 the buffer to put read data into.

+

+  @retval EFI_SUCCESS           Data was read.

+  @retval EFI_NO_MEDIA          The device has no media.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.

+  @retval EFI_BUFFER_TO_SMALL   Buffer is too small. ReadSize contains required

+                                size.

+

+**/

+EFI_STATUS

+EFIAPI

+FileHandleRead(

+  IN EFI_FILE_HANDLE            FileHandle,

+  IN OUT UINTN                  *BufferSize,

+  OUT VOID                      *Buffer

+  )

+{

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the read based on EFI_FILE_PROTOCOL

+  //

+  return (FileHandle->Read(FileHandle, BufferSize, Buffer));

+}

+

+

+/**

+  Write data to a file.

+

+  This function writes the specified number of bytes to the file at the current

+  file position. The current file position is advanced the actual number of bytes

+  written, which is returned in BufferSize. Partial writes only occur when there

+  has been a data error during the write attempt (such as "volume space full").

+  The file is automatically grown to hold the data if required. Direct writes to

+  opened directories are not supported.

+

+  @param FileHandle           The opened file for writing

+  @param BufferSize           on input the number of bytes in Buffer.  On output

+                              the number of bytes written.

+  @param Buffer               the buffer containing data to write is stored.

+

+ @retval EFI_SUCCESS          Data was written.

+ @retval EFI_UNSUPPORTED      Writes to an open directory are not supported.

+ @retval EFI_NO_MEDIA         The device has no media.

+ @retval EFI_DEVICE_ERROR     The device reported an error.

+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.

+ @retval EFI_WRITE_PROTECTED  The device is write-protected.

+ @retval EFI_ACCESS_DENIED    The file was open for read only.

+ @retval EFI_VOLUME_FULL      The volume is full.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleWrite(

+  IN EFI_FILE_HANDLE            FileHandle,

+  IN OUT UINTN                  *BufferSize,

+  IN VOID                       *Buffer

+  )

+{

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the write based on EFI_FILE_PROTOCOL

+  //

+  return (FileHandle->Write(FileHandle, BufferSize, Buffer));

+}

+

+/**

+  Close an open file handle.

+

+  This function closes a specified file handle. All "dirty" cached file data is

+  flushed to the device, and the file is closed. In all cases the handle is

+  closed.

+

+@param FileHandle               the file handle to close.

+

+@retval EFI_SUCCESS             the file handle was closed sucessfully.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleClose (

+  IN EFI_FILE_HANDLE            FileHandle

+  )

+{

+  EFI_STATUS Status;

+

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the Close based on EFI_FILE_PROTOCOL

+  //

+  Status = FileHandle->Close(FileHandle);

+  return Status;

+}

+

+/**

+  Delete a file and close the handle

+

+  This function closes and deletes a file. In all cases the file handle is closed.

+  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is

+  returned, but the handle is still closed.

+

+  @param FileHandle             the file handle to delete

+

+  @retval EFI_SUCCESS           the file was closed sucessfully

+  @retval EFI_WARN_DELETE_FAILURE the handle was closed, but the file was not

+                                deleted

+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleDelete (

+  IN EFI_FILE_HANDLE    FileHandle

+  )

+{

+  EFI_STATUS Status;

+

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the Delete based on EFI_FILE_PROTOCOL

+  //

+  Status = FileHandle->Delete(FileHandle);

+  return Status;

+}

+

+/**

+  Set the current position in a file.

+

+  This function sets the current file position for the handle to the position

+  supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only

+  absolute positioning is supported, and seeking past the end of the file is

+  allowed (a subsequent write would grow the file). Seeking to position

+  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.

+  If FileHandle is a directory, the only position that may be set is zero. This

+  has the effect of starting the read process of the directory entries over.

+

+  @param FileHandle             The file handle on which the position is being set

+  @param Position               Byte position from begining of file

+

+  @retval EFI_SUCCESS           Operation completed sucessfully.

+  @retval EFI_UNSUPPORTED       the seek request for non-zero is not valid on

+                                directories.

+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleSetPosition (

+  IN EFI_FILE_HANDLE    FileHandle,

+  IN UINT64             Position

+  )

+{

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the SetPosition based on EFI_FILE_PROTOCOL

+  //

+  return (FileHandle->SetPosition(FileHandle, Position));

+}

+

+/**

+  Gets a file's current position

+

+  This function retrieves the current file position for the file handle. For

+  directories, the current file position has no meaning outside of the file

+  system driver and as such the operation is not supported. An error is returned

+  if FileHandle is a directory.

+

+  @param FileHandle             The open file handle on which to get the position.

+  @param Position               Byte position from begining of file.

+

+  @retval EFI_SUCCESS           the operation completed sucessfully.

+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.

+  @retval EFI_UNSUPPORTED       the request is not valid on directories.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleGetPosition (

+  IN EFI_FILE_HANDLE            FileHandle,

+  OUT UINT64                    *Position

+  )

+{

+  if (Position == NULL || FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the GetPosition based on EFI_FILE_PROTOCOL

+  //

+  return (FileHandle->GetPosition(FileHandle, Position));

+}

+/**

+  Flushes data on a file

+

+  This function flushes all modified data associated with a file to a device.

+

+  @param FileHandle             The file handle on which to flush data

+

+  @retval EFI_SUCCESS           The data was flushed.

+  @retval EFI_NO_MEDIA          The device has no media.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.

+  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.

+  @retval EFI_ACCESS_DENIED     The file was opened for read only.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleFlush (

+  IN EFI_FILE_HANDLE            FileHandle

+  )

+{

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // Perform the Flush based on EFI_FILE_PROTOCOL

+  //

+  return (FileHandle->Flush(FileHandle));

+}

+

+/**

+  function to determine if a given handle is a directory handle

+

+  if DirHandle is NULL then return error

+

+  open the file information on the DirHandle and verify that the Attribute

+  includes EFI_FILE_DIRECTORY bit set.

+

+  @param DirHandle              Handle to open file

+

+  @retval EFI_SUCCESS           DirHandle is a directory

+  @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available

+  @retval EFI_NOT_FOUND         DirHandle is not a directory

+**/

+EFI_STATUS

+EFIAPI

+FileHandleIsDirectory (

+  IN EFI_FILE_HANDLE            DirHandle

+  )

+{

+  EFI_FILE_INFO *DirInfo;

+

+  if (DirHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // get the file information for DirHandle

+  //

+  DirInfo = FileHandleGetInfo (DirHandle);

+

+  //

+  // Parse DirInfo

+  //

+  if (DirInfo == NULL) {

+    //

+    // We got nothing...

+    //

+    return (EFI_INVALID_PARAMETER);

+  }

+  if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) {

+    //

+    // Attributes say this is not a directory

+    //

+    FreePool (DirInfo);

+    return (EFI_NOT_FOUND);

+  }

+  //

+  // all good...

+  //

+  FreePool (DirInfo);

+  return (EFI_SUCCESS);

+}

+

+/** Retrieve first entry from a directory.

+

+  This function takes an open directory handle and gets information from the

+  first entry in the directory.  A buffer is allocated to contain

+  the information and a pointer to the buffer is returned in *Buffer.  The

+  caller can use FileHandleFindNextFile() to get subsequent directory entries.

+

+  The buffer will be freed by FileHandleFindNextFile() when the last directory

+  entry is read.  Otherwise, the caller must free the buffer, using FreePool,

+  when finished with it.

+

+  @param[in]  DirHandle         The file handle of the directory to search.

+  @param[out] Buffer            The pointer to pointer to buffer for file's information.

+

+  @retval EFI_SUCCESS           Found the first file.

+  @retval EFI_NOT_FOUND         Cannot find the directory.

+  @retval EFI_NO_MEDIA          The device has no media.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.

+  @return Others                status of FileHandleGetInfo, FileHandleSetPosition,

+                                or FileHandleRead

+**/

+EFI_STATUS

+EFIAPI

+FileHandleFindFirstFile (

+  IN EFI_FILE_HANDLE            DirHandle,

+  OUT EFI_FILE_INFO             **Buffer

+  )

+{

+  EFI_STATUS    Status;

+  UINTN         BufferSize;

+

+  if (Buffer == NULL || DirHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // verify that DirHandle is a directory

+  //

+  Status = FileHandleIsDirectory(DirHandle);

+  if (EFI_ERROR(Status)) {

+    return (Status);

+  }

+

+  //

+  // Allocate a buffer sized to struct size + enough for the string at the end

+  //

+  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;

+  *Buffer = AllocateZeroPool(BufferSize);

+  if (*Buffer == NULL){

+    return (EFI_OUT_OF_RESOURCES);

+  }

+

+  //

+  // reset to the begining of the directory

+  //

+  Status = FileHandleSetPosition(DirHandle, 0);

+  if (EFI_ERROR(Status)) {

+    FreePool(*Buffer);

+    *Buffer = NULL;

+    return (Status);

+  }

+

+  //

+  // read in the info about the first file

+  //

+  Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);

+  ASSERT(Status != EFI_BUFFER_TOO_SMALL);

+  if (EFI_ERROR(Status) || BufferSize == 0) {

+    FreePool(*Buffer);

+    *Buffer = NULL;

+    if (BufferSize == 0) {

+      return (EFI_NOT_FOUND);

+    }

+    return (Status);

+  }

+  return (EFI_SUCCESS);

+}

+

+/** Retrieve next entries from a directory.

+

+  To use this function, the caller must first call the FileHandleFindFirstFile()

+  function to get the first directory entry.  Subsequent directory entries are

+  retrieved by using the FileHandleFindNextFile() function.  This function can

+  be called several times to get each entry from the directory.  If the call of

+  FileHandleFindNextFile() retrieved the last directory entry, the next call of

+  this function will set *NoFile to TRUE and free the buffer.

+

+  @param[in]  DirHandle         The file handle of the directory.

+  @param[out] Buffer            The pointer to buffer for file's information.

+  @param[out] NoFile            The pointer to boolean when last file is found.

+

+  @retval EFI_SUCCESS           Found the next file, or reached last file

+  @retval EFI_NO_MEDIA          The device has no media.

+  @retval EFI_DEVICE_ERROR      The device reported an error.

+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleFindNextFile(

+  IN EFI_FILE_HANDLE          DirHandle,

+  OUT EFI_FILE_INFO          *Buffer,

+  OUT BOOLEAN                *NoFile

+  )

+{

+  EFI_STATUS    Status;

+  UINTN         BufferSize;

+

+  if (DirHandle == NULL || Buffer == NULL || NoFile == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile

+  //

+  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;

+

+  //

+  // read in the info about the next file

+  //

+  Status = FileHandleRead (DirHandle, &BufferSize, Buffer);

+  ASSERT(Status != EFI_BUFFER_TOO_SMALL);

+  if (EFI_ERROR(Status)) {

+    return (Status);

+  }

+

+  //

+  // If we read 0 bytes (but did not have erros) we already read in the last file.

+  //

+  if (BufferSize == 0) {

+    FreePool(Buffer);

+    *NoFile = TRUE;

+  }

+

+  return (EFI_SUCCESS);

+}

+

+/**

+  Retrieve the size of a file.

+

+  if FileHandle is NULL then return error

+  if Size is NULL then return error

+

+  This function extracts the file size info from the FileHandle's EFI_FILE_INFO

+  data.

+

+  @param FileHandle             file handle from which size is retrieved

+  @param Size                   pointer to size

+

+  @retval EFI_SUCCESS           operation was completed sucessfully

+  @retval EFI_DEVICE_ERROR      cannot access the file

+**/

+EFI_STATUS

+EFIAPI

+FileHandleGetSize (

+  IN EFI_FILE_HANDLE            FileHandle,

+  OUT UINT64                    *Size

+  )

+{

+  EFI_FILE_INFO                 *FileInfo;

+

+  if (FileHandle == NULL || Size == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // get the FileInfo structure

+  //

+  FileInfo = FileHandleGetInfo(FileHandle);

+  if (FileInfo == NULL) {

+    return (EFI_DEVICE_ERROR);

+  }

+

+  //

+  // Assign the Size pointer to the correct value

+  //

+  *Size = FileInfo->FileSize;

+

+  //

+  // free the FileInfo memory

+  //

+  FreePool(FileInfo);

+

+  return (EFI_SUCCESS);

+}

+

+/**

+  Set the size of a file.

+

+  If FileHandle is NULL then return error.

+

+  This function changes the file size info from the FileHandle's EFI_FILE_INFO

+  data.

+

+  @param FileHandle             File handle whose size is to be changed.

+  @param Size                   New size.

+

+  @retval EFI_SUCCESS           operation was completed sucessfully.

+  @retval EFI_DEVICE_ERROR      cannot access the file.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleSetSize (

+  IN EFI_FILE_HANDLE            FileHandle,

+  IN UINT64                     Size

+  )

+{

+  EFI_FILE_INFO                 *FileInfo;

+  EFI_STATUS                    Status;

+

+  if (FileHandle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  //

+  // get the FileInfo structure

+  //

+  FileInfo = FileHandleGetInfo(FileHandle);

+  if (FileInfo == NULL) {

+    return (EFI_DEVICE_ERROR);

+  }

+

+  //

+  // Assign the FileSize pointer to the new value

+  //

+  FileInfo->FileSize = Size;

+

+  Status = FileHandleSetInfo(FileHandle, FileInfo);

+  //

+  // free the FileInfo memory

+  //

+  FreePool(FileInfo);

+

+  return (Status);

+}

+

+/**

+  Safely append (on the left) with automatic string resizing given length of Destination and

+  desired length of copy from Source.

+

+  append the first D characters of Source to the end of Destination, where D is

+  the lesser of Count and the StrLen() of Source. If appending those D characters

+  will fit within Destination (whose Size is given as CurrentSize) and

+  still leave room for a NULL terminator, then those characters are appended,

+  starting at the original terminating NULL of Destination, and a new terminating

+  NULL is appended.

+

+  If appending D characters onto Destination will result in a overflow of the size

+  given in CurrentSize the string will be grown such that the copy can be performed

+  and CurrentSize will be updated to the new size.

+

+  If Source is NULL, there is nothing to append, just return the current buffer in

+  Destination.

+

+  if Destination is NULL, then return error

+  if Destination's current length (including NULL terminator) is already more then

+  CurrentSize, then ASSERT()

+

+  @param[in, out] Destination   The String to append onto

+  @param[in, out] CurrentSize   on call the number of bytes in Destination.  On

+                                return possibly the new size (still in bytes).  if NULL

+                                then allocate whatever is needed.

+  @param[in]      Source        The String to append from

+  @param[in]      Count         Maximum number of characters to append.  if 0 then

+                                all are appended.

+

+  @return Destination           return the resultant string.

+**/

+CHAR16*

+EFIAPI

+StrnCatGrowLeft (

+  IN OUT CHAR16           **Destination,

+  IN OUT UINTN            *CurrentSize,

+  IN     CONST CHAR16     *Source,

+  IN     UINTN            Count

+  )

+{

+  UINTN DestinationStartSize;

+  UINTN NewSize;

+  UINTN CopySize;

+

+  if (Destination == NULL) {

+    return (NULL);

+  }

+

+  //

+  // If there's nothing to do then just return Destination

+  //

+  if (Source == NULL) {

+    return (*Destination);

+  }

+

+  //

+  // allow for NULL pointers address as Destination

+  //

+  if (*Destination != NULL) {

+    ASSERT(CurrentSize != 0);

+    DestinationStartSize = StrSize(*Destination);

+    ASSERT(DestinationStartSize <= *CurrentSize);

+  } else {

+    DestinationStartSize = 0;

+//    ASSERT(*CurrentSize == 0);

+  }

+

+  //

+  // Append all of Source?

+  //

+  if (Count == 0) {

+    Count = StrSize(Source);

+  }

+

+  //

+  // Test and grow if required

+  //

+  if (CurrentSize != NULL) {

+    NewSize = *CurrentSize;

+    while (NewSize < (DestinationStartSize + Count)) {

+      NewSize += 2 * Count;

+    }

+    *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination);

+    *CurrentSize = NewSize;

+  } else {

+    *Destination = AllocateZeroPool(Count+sizeof(CHAR16));

+  }

+  if (*Destination == NULL) {

+    return NULL;

+  }

+

+  CopySize = StrSize(*Destination);

+  CopyMem((*Destination)+((Count-2)/sizeof(CHAR16)), *Destination, CopySize);

+  CopyMem(*Destination, Source, Count-2);

+  return (*Destination);

+}

+

+/**

+  Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the

+  directory 'stack'.

+

+  if Handle is NULL, return EFI_INVALID_PARAMETER

+

+  @param[in] Handle             Handle to the Directory or File to create path to.

+  @param[out] FullFileName      pointer to pointer to generated full file name.  It

+                                is the responsibility of the caller to free this memory

+                                with a call to FreePool().

+  @retval EFI_SUCCESS           the operation was sucessful and the FullFileName is valid.

+  @retval EFI_INVALID_PARAMETER Handle was NULL.

+  @retval EFI_INVALID_PARAMETER FullFileName was NULL.

+  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.

+**/

+EFI_STATUS

+EFIAPI

+FileHandleGetFileName (

+  IN CONST EFI_FILE_HANDLE      Handle,

+  OUT CHAR16                    **FullFileName

+  )

+{

+  EFI_STATUS      Status;

+  UINTN           Size;

+  EFI_FILE_HANDLE CurrentHandle;

+  EFI_FILE_HANDLE NextHigherHandle;

+  EFI_FILE_INFO   *FileInfo;

+

+  Size = 0;

+

+  //

+  // Check our parameters

+  //

+  if (FullFileName == NULL || Handle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  *FullFileName = NULL;

+  CurrentHandle = NULL;

+

+  Status = Handle->Open(Handle, &CurrentHandle, L".", EFI_FILE_MODE_READ, 0);

+  if (!EFI_ERROR(Status)) {

+    //

+    // Reverse out the current directory on the device

+    //

+    for (;;) {

+      FileInfo = FileHandleGetInfo(CurrentHandle);

+      if (FileInfo == NULL) {

+        Status = EFI_OUT_OF_RESOURCES;

+        break;

+      } else {

+        //

+        // We got info... do we have a name? if yes preceed the current path with it...

+        //

+        if (StrLen (FileInfo->FileName) == 0) {

+          if (*FullFileName == NULL) {

+            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));

+            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);

+          }

+          FreePool(FileInfo);

+          break;

+        } else {

+          if (*FullFileName == NULL) {

+            ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));

+            *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);

+          }

+          ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));

+          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, FileInfo->FileName, 0);

+          *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);

+          FreePool(FileInfo);

+        }

+      }

+      //

+      // Move to the parent directory

+      //

+      Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);

+      if (EFI_ERROR (Status)) {

+        break;

+      }

+

+      FileHandleClose(CurrentHandle);

+      CurrentHandle = NextHigherHandle;

+    }

+  } else if (Status == EFI_NOT_FOUND) {

+    Status = EFI_SUCCESS;

+    ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));

+    *FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);

+  }

+

+  if (CurrentHandle != NULL) {

+    CurrentHandle->Close (CurrentHandle);

+  }

+

+  if (EFI_ERROR(Status) && *FullFileName != NULL) {

+    FreePool(*FullFileName);

+  }

+

+  return (Status);

+}

+

+/**

+  Function to read a single line from a file. The \n is not included in the returned

+  buffer.  The returned buffer must be callee freed.

+

+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be

+  maintained and not changed for all operations with the same file.

+

+  @param[in]       Handle        FileHandle to read from.

+  @param[in, out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);

+

+  @return                       The line of text from the file.

+

+  @sa FileHandleReadLine

+**/

+CHAR16*

+EFIAPI

+FileHandleReturnLine(

+  IN EFI_FILE_HANDLE            Handle,

+  IN OUT BOOLEAN                *Ascii

+  )

+{

+  CHAR16          *RetVal;

+  UINTN           Size;

+  EFI_STATUS      Status;

+

+  Size = 0;

+  RetVal = NULL;

+

+  Status = FileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);

+  if (Status == EFI_BUFFER_TOO_SMALL) {

+    RetVal = AllocateZeroPool(Size);

+    Status = FileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii);

+  }

+  ASSERT_EFI_ERROR(Status);

+  if (EFI_ERROR(Status) && (RetVal != NULL)) {

+    FreePool(RetVal);

+    RetVal = NULL;

+  }

+  return (RetVal);

+}

+

+/**

+  Function to read a single line (up to but not including the \n) from a EFI_FILE_HANDLE.

+

+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be

+  maintained and not changed for all operations with the same file.

+

+  @param[in]       Handle        FileHandle to read from

+  @param[in, out]  Buffer        pointer to buffer to read into

+  @param[in, out]  Size          pointer to number of bytes in buffer

+  @param[in]       Truncate      if TRUE then allows for truncation of the line to fit.

+                                 if FALSE will reset the position to the begining of the

+                                 line if the buffer is not large enough.

+  @param[in, out]  Ascii         Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE);

+

+  @retval EFI_SUCCESS           the operation was sucessful.  the line is stored in

+                                Buffer.

+  @retval EFI_INVALID_PARAMETER Handle was NULL.

+  @retval EFI_INVALID_PARAMETER Size was NULL.

+  @retval EFI_BUFFER_TOO_SMALL  Size was not enough space to store the line.

+                                Size was updated to minimum space required.

+  @sa FileHandleRead

+**/

+EFI_STATUS

+EFIAPI

+FileHandleReadLine(

+  IN EFI_FILE_HANDLE            Handle,

+  IN OUT CHAR16                 *Buffer,

+  IN OUT UINTN                  *Size,

+  IN BOOLEAN                    Truncate,

+  IN OUT BOOLEAN                *Ascii

+  )

+{

+  EFI_STATUS  Status;

+  CHAR16      CharBuffer;

+  UINTN       CharSize;

+  UINTN       CountSoFar;

+  UINT64      OriginalFilePosition;

+

+

+  if (Handle == NULL

+    ||Size   == NULL

+    ||(Buffer==NULL&&*Size!=0)

+   ){

+    return (EFI_INVALID_PARAMETER);

+  }

+  if (Buffer != NULL) {

+    *Buffer = CHAR_NULL;

+  }

+  FileHandleGetPosition(Handle, &OriginalFilePosition);

+  if (OriginalFilePosition == 0) {

+    CharSize = sizeof(CHAR16);

+    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);

+    ASSERT_EFI_ERROR(Status);

+    if (CharBuffer == gUnicodeFileTag) {

+      *Ascii = FALSE;

+    } else {

+      *Ascii = TRUE;

+      FileHandleSetPosition(Handle, OriginalFilePosition);

+    }

+  }

+

+  for (CountSoFar = 0;;CountSoFar++){

+    CharBuffer = 0;

+    if (*Ascii) {

+      CharSize = sizeof(CHAR8);

+    } else {

+      CharSize = sizeof(CHAR16);

+    }

+    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);

+    if (  EFI_ERROR(Status)

+       || CharSize == 0

+       || (CharBuffer == L'\n' && !(*Ascii))

+       || (CharBuffer ==  '\n' && *Ascii)

+     ){

+      break;

+    }

+    //

+    // if we have space save it...

+    //

+    if ((CountSoFar+1)*sizeof(CHAR16) < *Size){

+      ASSERT(Buffer != NULL);

+      ((CHAR16*)Buffer)[CountSoFar] = CharBuffer;

+      ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL;

+    }

+  }

+

+  //

+  // if we ran out of space tell when...

+  //

+  if ((CountSoFar+1)*sizeof(CHAR16) > *Size){

+    *Size = (CountSoFar+1)*sizeof(CHAR16);

+    if (!Truncate) {

+      FileHandleSetPosition(Handle, OriginalFilePosition);

+    } else {

+      DEBUG((DEBUG_WARN, "The line was truncated in FileHandleReadLine"));

+    }

+    return (EFI_BUFFER_TOO_SMALL);

+  }

+  while(Buffer[StrLen(Buffer)-1] == L'\r') {

+    Buffer[StrLen(Buffer)-1] = CHAR_NULL;

+  }

+

+  return (Status);

+}

+

+/**

+  function to write a line of unicode text to a file.

+

+  if Handle is NULL, return error.

+  if Buffer is NULL, do nothing.  (return SUCCESS)

+

+  @param[in]     Handle         FileHandle to write to

+  @param[in]     Buffer         Buffer to write

+

+  @retval  EFI_SUCCESS          the data was written.

+  @retval  other                failure.

+

+  @sa FileHandleWrite

+**/

+EFI_STATUS

+EFIAPI

+FileHandleWriteLine(

+  IN EFI_FILE_HANDLE Handle,

+  IN CHAR16          *Buffer

+  )

+{

+  EFI_STATUS Status;

+  UINTN      Size;

+

+  if (Buffer == NULL) {

+    return (EFI_SUCCESS);

+  }

+

+  if (Handle == NULL) {

+    return (EFI_INVALID_PARAMETER);

+  }

+

+  Size = StrSize(Buffer) - sizeof(Buffer[0]);

+  Status = FileHandleWrite(Handle, &Size, Buffer);

+  if (EFI_ERROR(Status)) {

+    return (Status);

+  }

+  Size = StrSize(L"\r\n") - sizeof(CHAR16);

+  return FileHandleWrite(Handle, &Size, L"\r\n");

+}

+

+/**

+  function to take a formatted argument and print it to a file.

+

+  @param[in] Handle   the file handle for the file to write to

+  @param[in] Format   the format argument (see printlib for format specifier)

+  @param[in] ...      the variable arguments for the format

+

+  @retval EFI_SUCCESS the operation was sucessful

+  @return other       a return value from FileHandleWriteLine

+

+  @sa FileHandleWriteLine

+**/

+EFI_STATUS

+EFIAPI

+FileHandlePrintLine(

+  IN EFI_FILE_HANDLE  Handle,

+  IN CONST CHAR16     *Format,

+  ...

+  )

+{

+  VA_LIST           Marker;

+  CHAR16            *Buffer;

+  EFI_STATUS        Status;

+

+  //

+  // Get a buffer to print into

+  //

+  Buffer = AllocateZeroPool (PcdGet16 (PcdUefiFileHandleLibPrintBufferSize));

+  if (Buffer == NULL) {

+    return (EFI_OUT_OF_RESOURCES);

+  }

+

+  //

+  // Print into our buffer

+  //

+  VA_START (Marker, Format);

+  UnicodeVSPrint (Buffer, PcdGet16 (PcdUefiFileHandleLibPrintBufferSize), Format, Marker);

+  VA_END (Marker);

+

+  //

+  // Print buffer into file

+  //

+  Status = FileHandleWriteLine(Handle, Buffer);

+

+  //

+  // Cleanup and return

+  //

+  FreePool(Buffer);

+  return (Status);

+}

+

+/**

+  Function to determine if a FILE_HANDLE is at the end of the file.

+

+  This will NOT work on directories.

+

+  If Handle is NULL, then return False.

+

+  @param[in] Handle     the file handle

+

+  @retval TRUE          the position is at the end of the file

+  @retval FALSE         the position is not at the end of the file

+**/

+BOOLEAN

+EFIAPI

+FileHandleEof(

+  IN EFI_FILE_HANDLE Handle

+  )

+{

+  EFI_FILE_INFO *Info;

+  UINT64        Pos;

+  BOOLEAN       RetVal;

+

+  if (Handle == NULL) {

+    return (FALSE);

+  }

+

+  FileHandleGetPosition(Handle, &Pos);

+  Info = FileHandleGetInfo (Handle);

+

+  if (Info == NULL) {

+    return (FALSE);

+  }

+

+  FileHandleSetPosition(Handle, Pos);

+

+  if (Pos == Info->FileSize) {

+    RetVal = TRUE;

+  } else {

+    RetVal = FALSE;

+  }

+

+  FreePool (Info);

+

+  return (RetVal);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
new file mode 100644
index 0000000..6c98df0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
@@ -0,0 +1,47 @@
+##  @file

+# Provides interface to shell functionality for shell commands and applications.

+#

+#   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

+#   which accompanies this distribution. The full text of the license may be found at

+#   http://opensource.org/licenses/bsd-license.php

+#

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010006

+  BASE_NAME                      = BaseFileHandleLib

+  FILE_GUID                      = 9495D344-9D8A-41f3-8D17-E2FD238C4E71

+  MODULE_TYPE                    = DXE_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = FileHandleLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER DXE_RUNTIME_DRIVER

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources.common]

+  UefiFileHandleLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  MemoryAllocationLib

+  BaseLib

+  BaseMemoryLib

+  DebugLib

+  PrintLib

+  PcdLib

+

+[Protocols]

+  gEfiSimpleFileSystemProtocolGuid              ## SOMETIMES_CONSUMES

+

+[Guids]

+  gEfiFileInfoGuid                              ## SOMETIMES_CONSUMES ## GUID

+

+[Pcd.common]

+  gEfiMdePkgTokenSpaceGuid.PcdUefiFileHandleLibPrintBufferSize  ## SOMETIMES_CONSUMES

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/Console.c b/uefi/linaro-edk2/MdePkg/Library/UefiLib/Console.c
new file mode 100644
index 0000000..73f9915
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/Console.c
@@ -0,0 +1,572 @@
+/** @file

+  This module provide help function for displaying unicode string.

+

+  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.             

+

+**/

+

+

+

+

+#include "UefiLibInternal.h"

+

+typedef struct {

+  CHAR16  WChar;

+  UINT32  Width;

+} UNICODE_WIDTH_ENTRY;

+

+#define NARROW_CHAR         0xFFF0

+#define WIDE_CHAR           0xFFF1

+

+GLOBAL_REMOVE_IF_UNREFERENCED CONST UNICODE_WIDTH_ENTRY mUnicodeWidthTable[] = {

+  //

+  // General script area

+  //

+  {(CHAR16)0x1FFF,  1},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all narrow glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x007F,  1},       // C0 controls and basic Latin. 0x0000-0x007F

+  {(CHAR16)0x00FF,  1},       // C1 controls and Latin-1 support. 0x0080-0x00FF

+  {(CHAR16)0x017F,  1},       // Latin extended-A. 0x0100-0x017F

+  {(CHAR16)0x024F,  1},       // Latin extended-B. 0x0180-0x024F

+  {(CHAR16)0x02AF,  1},       // IPA extensions. 0x0250-0x02AF

+  {(CHAR16)0x02FF,  1},       // Spacing modifier letters. 0x02B0-0x02FF

+  {(CHAR16)0x036F,  1},       // Combining diacritical marks. 0x0300-0x036F

+  {(CHAR16)0x03FF,  1},       // Greek. 0x0370-0x03FF

+  {(CHAR16)0x04FF,  1},       // Cyrillic. 0x0400-0x04FF

+  {(CHAR16)0x052F,  0},       // Unassigned. As Armenian in ver3.0. 0x0500-0x052F

+  {(CHAR16)0x058F,  1},       // Armenian. 0x0530-0x058F

+  {(CHAR16)0x05FF,  1},       // Hebrew. 0x0590-0x05FF

+  {(CHAR16)0x06FF,  1},       // Arabic. 0x0600-0x06FF

+  {(CHAR16)0x08FF,  0},       // Unassigned. 0x0700-0x08FF

+  {(CHAR16)0x097F,  1},       // Devanagari. 0x0900-0x097F

+  {(CHAR16)0x09FF,  1},       // Bengali. 0x0980-0x09FF

+  {(CHAR16)0x0A7F,  1},       // Gurmukhi. 0x0A00-0x0A7F

+  {(CHAR16)0x0AFF,  1},       // Gujarati. 0x0A80-0x0AFF

+  {(CHAR16)0x0B7F,  1},       // Oriya. 0x0B00-0x0B7F

+  {(CHAR16)0x0BFF,  1},       // Tamil. (See page 7-92). 0x0B80-0x0BFF

+  {(CHAR16)0x0C7F,  1},       // Telugu. 0x0C00-0x0C7F

+  {(CHAR16)0x0CFF,  1},       // Kannada. (See page 7-100). 0x0C80-0x0CFF

+  {(CHAR16)0x0D7F,  1},       // Malayalam (See page 7-104). 0x0D00-0x0D7F

+  {(CHAR16)0x0DFF,  0},       // Unassigned. 0x0D80-0x0DFF

+  {(CHAR16)0x0E7F,  1},       // Thai. 0x0E00-0x0E7F

+  {(CHAR16)0x0EFF,  1},       // Lao. 0x0E80-0x0EFF

+  {(CHAR16)0x0FBF,  1},       // Tibetan. 0x0F00-0x0FBF

+  {(CHAR16)0x109F,  0},       // Unassigned. 0x0FC0-0x109F

+  {(CHAR16)0x10FF,  1},       // Georgian. 0x10A0-0x10FF

+  {(CHAR16)0x11FF,  1},       // Hangul Jamo. 0x1100-0x11FF

+  {(CHAR16)0x1DFF,  0},       // Unassigned. 0x1200-0x1DFF

+  {(CHAR16)0x1EFF,  1},       // Latin extended additional. 0x1E00-0x1EFF

+  {(CHAR16)0x1FFF,  1},       // Greek extended. 0x1F00-0x1FFF

+  *

+  */

+

+  //

+  // Symbol area

+  //

+  {(CHAR16)0x2FFF,  1},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all narrow glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x206F,  1},       // General punctuation. (See page7-154). 0x200-0x206F

+  {(CHAR16)0x209F,  1},       // Superscripts and subscripts. 0x2070-0x209F

+  {(CHAR16)0x20CF,  1},       // Currency symbols. 0x20A0-0x20CF

+  {(CHAR16)0x20FF,  1},       // Combining diacritical marks for symbols. 0x20D0-0x20FF

+  {(CHAR16)0x214F,  1},       // Letterlike sympbols. 0x2100-0x214F

+  {(CHAR16)0x218F,  1},       // Number forms. 0x2150-0x218F

+  {(CHAR16)0x21FF,  1},       // Arrows. 0x2190-0x21FF

+  {(CHAR16)0x22FF,  1},       // Mathematical operators. 0x2200-0x22FF

+  {(CHAR16)0x23FF,  1},       // Miscellaneous technical. 0x2300-0x23FF

+  {(CHAR16)0x243F,  1},       // Control pictures. 0x2400-0x243F

+  {(CHAR16)0x245F,  1},       // Optical character recognition. 0x2440-0x245F

+  {(CHAR16)0x24FF,  1},       // Enclosed alphanumerics. 0x2460-0x24FF

+  {(CHAR16)0x257F,  1},       // Box drawing. 0x2500-0x257F

+  {(CHAR16)0x259F,  1},       // Block elements. 0x2580-0x259F

+  {(CHAR16)0x25FF,  1},       // Geometric shapes. 0x25A0-0x25FF

+  {(CHAR16)0x26FF,  1},       // Miscellaneous symbols. 0x2600-0x26FF

+  {(CHAR16)0x27BF,  1},       // Dingbats. 0x2700-0x27BF

+  {(CHAR16)0x2FFF,  0},       // Reserved. 0x27C0-0x2FFF

+  *

+  */

+

+  //

+  // CJK phonetics and symbol area

+  //

+  {(CHAR16)0x33FF,  2},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all wide glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x303F,  2},       // CJK symbols and punctuation. 0x3000-0x303F

+  {(CHAR16)0x309F,  2},       // Hiragana. 0x3040-0x309F

+  {(CHAR16)0x30FF,  2},       // Katakana. 0x30A0-0x30FF

+  {(CHAR16)0x312F,  2},       // Bopomofo. 0x3100-0x312F

+  {(CHAR16)0x318F,  2},       // Hangul compatibility jamo. 0x3130-0x318F

+  {(CHAR16)0x319F,  2},       // Kanbun. 0x3190-0x319F

+  {(CHAR16)0x31FF,  0},       // Reserved. As Bopomofo extended in ver3.0. 0x31A0-0x31FF

+  {(CHAR16)0x32FF,  2},       // Enclosed CJK letters and months. 0x3200-0x32FF

+  {(CHAR16)0x33FF,  2},       // CJK compatibility. 0x3300-0x33FF

+  *

+  */

+

+  //

+  // CJK ideograph area

+  //

+  {(CHAR16)0x9FFF,  2},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all wide glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0x4DFF,  0},       // Reserved. 0x3400-0x4DBF as CJK unified ideographs 

+                      // extension A in ver3.0. 0x3400-0x4DFF

+  {(CHAR16)0x9FFF,  2},       // CJK unified ideographs. 0x4E00-0x9FFF

+  *

+  */

+

+  //

+  // Reserved

+  //

+  {(CHAR16)0xABFF,  0},       // Reserved. 0xA000-0xA490 as Yi syllables. 0xA490-0xA4D0

+  // as Yi radicals in ver3.0. 0xA000-0xABFF

+  //

+  // Hangul syllables

+  //

+  {(CHAR16)0xD7FF,  2},

+  /*

+   * Merge the blocks and replace them with the above entry as they fall to 

+   * the same category and they are all wide glyph. This will reduce search

+   * time and table size. The merge will omit the reserved code.

+   *

+   * Remove the above item if below is un-commented.

+   *

+  {(CHAR16)0xD7A3,  2},       // Hangul syllables. 0xAC00-0xD7A3

+  {(CHAR16)0xD7FF,  0},       // Reserved. 0xD7A3-0xD7FF

+  *

+  */

+

+  //

+  // Surrogates area

+  //

+  {(CHAR16)0xDFFF,  0},       // Surrogates, not used now. 0xD800-0xDFFF

+

+  //

+  // Private use area

+  //

+  {(CHAR16)0xF8FF,  0},       // Private use area. 0xE000-0xF8FF

+

+  //

+  // Compatibility area and specials

+  //

+  {(CHAR16)0xFAFF,  2},       // CJK compatibility ideographs. 0xF900-0xFAFF

+  {(CHAR16)0xFB4F,  1},       // Alphabetic presentation forms. 0xFB00-0xFB4F

+  {(CHAR16)0xFDFF,  1},       // Arabic presentation forms-A. 0xFB50-0xFDFF

+  {(CHAR16)0xFE1F,  0},       // Reserved. As variation selectors in ver3.0. 0xFE00-0xFE1F

+  {(CHAR16)0xFE2F,  1},       // Combining half marks. 0xFE20-0xFE2F

+  {(CHAR16)0xFE4F,  2},       // CJK compatibility forms. 0xFE30-0xFE4F

+  {(CHAR16)0xFE6F,  1},       // Small Form Variants. 0xFE50-0xFE6F

+  {(CHAR16)0xFEFF,  1},       // Arabic presentation forms-B. 0xFE70-0xFEFF

+  {(CHAR16)0xFFEF,  1},       // Half width and full width forms. 0xFF00-0xFFEF

+  {(CHAR16)0xFFFF,  0},       // Speicials. 0xFFF0-0xFFFF

+};

+

+/**

+  Retrieves the width of a Unicode character.

+

+  This function computes and returns the width of the Unicode character specified

+  by UnicodeChar.

+

+  @param  UnicodeChar   A Unicode character.

+

+  @retval 0             The width if UnicodeChar could not be determined.

+  @retval 1             UnicodeChar is a narrow glyph.

+  @retval 2             UnicodeChar is a wide glyph.

+

+**/

+UINTN

+EFIAPI

+GetGlyphWidth (

+  IN CHAR16  UnicodeChar

+  )

+{

+  UINTN                     Index;

+  UINTN                     Low;

+  UINTN                     High;

+  CONST UNICODE_WIDTH_ENTRY *Item;

+

+  Item  = NULL;

+  Low   = 0;

+  High  = (sizeof (mUnicodeWidthTable)) / (sizeof (UNICODE_WIDTH_ENTRY)) - 1;

+  while (Low <= High) {

+    Index = (Low + High) >> 1;

+    Item  = &(mUnicodeWidthTable[Index]);

+    if (Index == 0) {

+      if (UnicodeChar <= Item->WChar) {

+        break;

+      }

+

+      return 0;

+    }

+

+    if (UnicodeChar > Item->WChar) {

+      Low = Index + 1;

+    } else if (UnicodeChar <= mUnicodeWidthTable[Index - 1].WChar) {

+      High = Index - 1;

+    } else {

+      //

+      // Index - 1 < UnicodeChar <= Index. Found

+      //

+      break;

+    }

+  }

+

+  if (Low <= High) {

+    return Item->Width;

+  }

+

+  return 0;

+}

+

+/**

+  Computes the display length of a Null-terminated Unicode String.

+

+  This function computes and returns the display length of the Null-terminated 

+  Unicode string specified by String.  If String is NULL then 0 is returned. If 

+  any of the widths of the Unicode characters in String can not be determined, 

+  then 0 is returned. The display width of String can be computed by summing the 

+  display widths of each Unicode character in String.  Unicode characters that 

+  are narrow glyphs have a width of 1, and Unicode characters that are width glyphs 

+  have a width of 2.  If String is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  String      A pointer to a Null-terminated Unicode string.

+

+  @return The display length of the Null-terminated Unicode string specified by String.

+  

+**/

+UINTN

+EFIAPI

+UnicodeStringDisplayLength (

+  IN CONST CHAR16  *String

+  )

+{

+  UINTN      Length;

+  UINTN      Width;

+

+  if (String == NULL) {

+    return 0;

+  }

+

+  Length = 0;

+  while (*String != 0) {

+    Width = GetGlyphWidth (*String);

+    if (Width == 0) {

+      return 0;

+    }

+

+    Length += Width;

+    String++;

+  }

+

+  return Length;

+}

+

+/**

+  Count the storage space of a Unicode string. 

+

+  This function handles the Unicode string with NARROW_CHAR

+  and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR

+  does not count in the resultant output. If a WIDE_CHAR is

+  hit, then 2 Unicode character will consume an output storage

+  space with size of CHAR16 till a NARROW_CHAR is hit.

+

+  @param String          The input string to be counted.

+  @param LimitLen        Whether need to limit the string length.

+  @param MaxWidth        The max length this function supported.

+  @param Offset          The max index of the string can be show out. 

+

+  @return Storage space for the input string.

+

+**/

+UINTN

+UefiLibGetStringWidth (

+  IN  CHAR16               *String,

+  IN  BOOLEAN              LimitLen,

+  IN  UINTN                MaxWidth,

+  OUT UINTN                *Offset

+  )

+{

+  UINTN Index;

+  UINTN Count;

+  UINTN IncrementValue;

+

+  if (String == NULL) {

+    return 0;

+  }

+

+  Index           = 0;

+  Count           = 0;

+  IncrementValue  = 1;

+

+  do {

+    //

+    // Advance to the null-terminator or to the first width directive

+    //

+    for (;(String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0); Index++) {

+      Count = Count + IncrementValue;

+

+      if (LimitLen && Count > MaxWidth) {

+        break;

+      }

+    }

+

+    //

+    // We hit the null-terminator, we now have a count

+    //

+    if (String[Index] == 0) {

+      break;

+    }

+

+    if (LimitLen && Count > MaxWidth) {

+      *Offset = Index;

+      break;

+    }

+

+    //

+    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed

+    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)

+    //

+    if (String[Index] == NARROW_CHAR) {

+      //

+      // Skip to the next character

+      //

+      Index++;

+      IncrementValue = 1;

+    } else {

+      //

+      // Skip to the next character

+      //

+      Index++;

+      IncrementValue = 2;

+    }

+  } while (String[Index] != 0);

+

+  return Count * sizeof (CHAR16);

+}

+

+/**

+  Draws a dialog box to the console output device specified by 

+  ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke

+  from the console input device specified by ConIn defined in the 

+  EFI_SYSTEM_TABLE.

+

+  If there are no strings in the variable argument list, then ASSERT().

+  If all the strings in the variable argument list are empty, then ASSERT().

+

+  @param[in]   Attribute  Specifies the foreground and background color of the popup.

+  @param[out]  Key        A pointer to the EFI_KEY value of the key that was 

+                          pressed.  This is an optional parameter that may be NULL.

+                          If it is NULL then no wait for a keypress will be performed.

+  @param[in]  ...         The variable argument list that contains pointers to Null-

+                          terminated Unicode strings to display in the dialog box.  

+                          The variable argument list is terminated by a NULL.

+

+**/

+VOID

+EFIAPI

+CreatePopUp (

+  IN  UINTN          Attribute,                

+  OUT EFI_INPUT_KEY  *Key,      OPTIONAL

+  ...

+  )

+{

+  EFI_STATUS                       Status;

+  VA_LIST                          Args;

+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;

+  EFI_SIMPLE_TEXT_OUTPUT_MODE      SavedConsoleMode;

+  UINTN                            Columns;

+  UINTN                            Rows;

+  UINTN                            Column;

+  UINTN                            Row;

+  UINTN                            NumberOfLines;

+  UINTN                            MaxLength;

+  CHAR16                           *String;

+  UINTN                            Length;

+  CHAR16                           *Line;

+  UINTN                            EventIndex;

+  CHAR16                           *TmpString;

+

+  //

+  // Determine the length of the longest line in the popup and the the total 

+  // number of lines in the popup

+  //

+  VA_START (Args, Key);

+  MaxLength = 0;

+  NumberOfLines = 0;

+  while ((String = VA_ARG (Args, CHAR16 *)) != NULL) {

+    MaxLength = MAX (MaxLength, UefiLibGetStringWidth (String, FALSE, 0, NULL) / 2);

+    NumberOfLines++;

+  }

+  VA_END (Args);

+

+  //

+  // If the total number of lines in the popup is zero, then ASSERT()

+  //

+  ASSERT (NumberOfLines != 0);

+

+  //

+  // If the maximum length of all the strings is zero, then ASSERT()

+  //

+  ASSERT (MaxLength != 0);

+

+  //

+  // Cache a pointer to the Simple Text Output Protocol in the EFI System Table

+  //

+  ConOut = gST->ConOut;

+  

+  //

+  // Save the current console cursor position and attributes

+  //

+  CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode));

+

+  //

+  // Retrieve the number of columns and rows in the current console mode

+  //

+  ConOut->QueryMode (ConOut, SavedConsoleMode.Mode, &Columns, &Rows);

+

+  //

+  // Disable cursor and set the foreground and background colors specified by Attribute

+  //

+  ConOut->EnableCursor (ConOut, FALSE);

+  ConOut->SetAttribute (ConOut, Attribute);

+

+  //

+  // Limit NumberOfLines to height of the screen minus 3 rows for the box itself

+  //

+  NumberOfLines = MIN (NumberOfLines, Rows - 3);

+

+  //

+  // Limit MaxLength to width of the screen minus 2 columns for the box itself

+  //

+  MaxLength = MIN (MaxLength, Columns - 2);

+

+  //

+  // Compute the starting row and starting column for the popup

+  //

+  Row    = (Rows - (NumberOfLines + 3)) / 2;

+  Column = (Columns - (MaxLength + 2)) / 2;

+

+  //

+  // Allocate a buffer for a single line of the popup with borders and a Null-terminator

+  //

+  Line = AllocateZeroPool ((MaxLength + 3) * sizeof (CHAR16));

+  ASSERT (Line != NULL);

+

+  //

+  // Draw top of popup box   

+  //

+  SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);

+  Line[0]             = BOXDRAW_DOWN_RIGHT;

+  Line[MaxLength + 1] = BOXDRAW_DOWN_LEFT;

+  Line[MaxLength + 2] = L'\0';

+  ConOut->SetCursorPosition (ConOut, Column, Row++);

+  ConOut->OutputString (ConOut, Line);

+

+  //

+  // Draw middle of the popup with strings

+  //

+  VA_START (Args, Key);

+  while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) {

+    SetMem16 (Line, (MaxLength + 2) * 2, L' ');

+    Line[0]             = BOXDRAW_VERTICAL;

+    Line[MaxLength + 1] = BOXDRAW_VERTICAL;

+    Line[MaxLength + 2] = L'\0';

+    ConOut->SetCursorPosition (ConOut, Column, Row);

+    ConOut->OutputString (ConOut, Line);

+    Length = UefiLibGetStringWidth (String, FALSE, 0, NULL) / 2;

+    if (Length <= MaxLength) {

+      //

+      // Length <= MaxLength

+      //

+      ConOut->SetCursorPosition (ConOut, Column + 1 + (MaxLength - Length) / 2, Row++);

+      ConOut->OutputString (ConOut, String);

+    } else {

+      //

+      // Length > MaxLength

+      //

+      UefiLibGetStringWidth (String, TRUE, MaxLength, &Length);

+      TmpString = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));

+      ASSERT (TmpString != NULL);

+      StrnCpy(TmpString, String, Length - 3);

+      StrCat (TmpString, L"...");

+

+      ConOut->SetCursorPosition (ConOut, Column + 1, Row++);

+      ConOut->OutputString (ConOut, TmpString);

+      FreePool (TmpString);

+    }

+    NumberOfLines--;

+  }

+  VA_END (Args);

+

+  //

+  // Draw bottom of popup box

+  //

+  SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);

+  Line[0]             = BOXDRAW_UP_RIGHT;

+  Line[MaxLength + 1] = BOXDRAW_UP_LEFT;

+  Line[MaxLength + 2] = L'\0';

+  ConOut->SetCursorPosition (ConOut, Column, Row++);

+  ConOut->OutputString (ConOut, Line);

+

+  //

+  // Free the allocated line buffer

+  //

+  FreePool (Line);

+

+  //

+  // Restore the cursor visibility, position, and attributes

+  //

+  ConOut->EnableCursor      (ConOut, SavedConsoleMode.CursorVisible);

+  ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);

+  ConOut->SetAttribute      (ConOut, SavedConsoleMode.Attribute);

+

+  //

+  // Wait for a keystroke

+  //

+  if (Key != NULL) {

+    while (TRUE) {

+      Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);

+      if (!EFI_ERROR (Status)) {

+        break;

+      }

+

+      //

+      // If we encounter error, continue to read another key in.

+      //

+      if (Status != EFI_NOT_READY) {

+        continue;

+      }

+      gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);

+    }

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiDriverModel.c b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiDriverModel.c
new file mode 100644
index 0000000..fb6067e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiDriverModel.c
@@ -0,0 +1,1056 @@
+/** @file

+  Library functions that abstract driver model protocols

+  installation.

+

+  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.

+

+**/ 

+

+

+#include "UefiLibInternal.h"

+

+/**

+  Installs and completes the initialization of a Driver Binding Protocol instance.

+  

+  Installs the Driver Binding Protocol specified by DriverBinding onto the handle

+  specified by DriverBindingHandle. If DriverBindingHandle is NULL, then DriverBinding

+  is installed onto a newly created handle. DriverBindingHandle is typically the same

+  as the driver's ImageHandle, but it can be different if the driver produces multiple

+  Driver Binding Protocols. 

+  If DriverBinding is NULL, then ASSERT(). 

+  If DriverBinding can not be installed onto a handle, then ASSERT().

+

+  @param  ImageHandle          The image handle of the driver.

+  @param  SystemTable          The EFI System Table that was passed to the driver's entry point.

+  @param  DriverBinding        A Driver Binding Protocol instance that this driver is producing.

+  @param  DriverBindingHandle  The handle that DriverBinding is to be installed onto.  If this

+                               parameter is NULL, then a new handle is created.

+

+  @retval EFI_SUCCESS           The protocol installation successfully completed.

+  @retval EFI_OUT_OF_RESOURCES  There was not enough system resources to install the protocol.

+  @retval Others                Status from gBS->InstallMultipleProtocolInterfaces().

+

+**/

+EFI_STATUS

+EFIAPI

+EfiLibInstallDriverBinding (

+  IN CONST EFI_HANDLE             ImageHandle,

+  IN CONST EFI_SYSTEM_TABLE       *SystemTable,

+  IN EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,

+  IN EFI_HANDLE                   DriverBindingHandle

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (DriverBinding != NULL);

+

+  //

+  // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol

+  //

+  DriverBinding->ImageHandle         = ImageHandle;

+  DriverBinding->DriverBindingHandle = DriverBindingHandle;

+

+  Status = gBS->InstallMultipleProtocolInterfaces (

+                  &DriverBinding->DriverBindingHandle,

+                  &gEfiDriverBindingProtocolGuid, DriverBinding,

+                  NULL

+                  );

+  //

+  // ASSERT if the call to InstallMultipleProtocolInterfaces() failed

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+

+/**

+  Installs and completes the initialization of a Driver Binding Protocol instance and

+  optionally installs the Component Name, Driver Configuration and Driver Diagnostics Protocols.

+

+  Initializes a driver by installing the Driver Binding Protocol together with the

+  optional Component Name, optional Driver Configure and optional Driver Diagnostic

+  Protocols onto the driver's DriverBindingHandle. If DriverBindingHandle is NULL,

+  then the protocols are  installed onto a newly created handle. DriverBindingHandle

+  is typically the same as the driver's ImageHandle, but it can be different if the

+  driver produces multiple Driver Binding Protocols. 

+  If DriverBinding is NULL, then ASSERT(). 

+  If the installation fails, then ASSERT().

+  

+  @param  ImageHandle          The image handle of the driver.

+  @param  SystemTable          The EFI System Table that was passed to the driver's entry point.

+  @param  DriverBinding        A Driver Binding Protocol instance that this driver is producing.

+  @param  DriverBindingHandle  The handle that DriverBinding is to be installed onto.  If this

+                               parameter is NULL, then a new handle is created.

+  @param  ComponentName        A Component Name Protocol instance that this driver is producing.

+  @param  DriverConfiguration  A Driver Configuration Protocol instance that this driver is producing.

+  @param  DriverDiagnostics    A Driver Diagnostics Protocol instance that this driver is producing.

+

+  @retval EFI_SUCCESS           The protocol installation successfully completed.

+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiLibInstallAllDriverProtocols (

+  IN CONST EFI_HANDLE                         ImageHandle,

+  IN CONST EFI_SYSTEM_TABLE                   *SystemTable,

+  IN EFI_DRIVER_BINDING_PROTOCOL              *DriverBinding,

+  IN EFI_HANDLE                               DriverBindingHandle,

+  IN CONST EFI_COMPONENT_NAME_PROTOCOL        *ComponentName,       OPTIONAL

+  IN CONST EFI_DRIVER_CONFIGURATION_PROTOCOL  *DriverConfiguration, OPTIONAL

+  IN CONST EFI_DRIVER_DIAGNOSTICS_PROTOCOL    *DriverDiagnostics    OPTIONAL

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (DriverBinding != NULL);

+

+  //

+  // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol

+  //

+  DriverBinding->ImageHandle         = ImageHandle;

+  DriverBinding->DriverBindingHandle = DriverBindingHandle;

+  

+  if (DriverDiagnostics == NULL || FeaturePcdGet(PcdDriverDiagnosticsDisable)) {

+    if (DriverConfiguration == NULL) {

+      if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid, DriverBinding,

+                        NULL

+                        );

+      } else {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid, DriverBinding,

+                        &gEfiComponentNameProtocolGuid, ComponentName,

+                        NULL

+                        );

+      }

+    } else {

+      if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid,       DriverBinding,

+                        &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                        NULL

+                        );

+      } else {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid,       DriverBinding,

+                        &gEfiComponentNameProtocolGuid,       ComponentName,

+                        &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                        NULL

+                        );

+      }

+    }

+  } else {

+    if (DriverConfiguration == NULL) {

+      if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid,     DriverBinding,

+                        &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                        NULL

+                        );

+      } else {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid,     DriverBinding,

+                        &gEfiComponentNameProtocolGuid,     ComponentName,

+                        &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                        NULL

+                        );

+      }

+    } else {

+      if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+       Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid,       DriverBinding,

+                        &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                        &gEfiDriverDiagnosticsProtocolGuid,   DriverDiagnostics,

+                        NULL

+                        );

+      } else {

+        Status = gBS->InstallMultipleProtocolInterfaces (

+                        &DriverBinding->DriverBindingHandle,

+                        &gEfiDriverBindingProtocolGuid,       DriverBinding,

+                        &gEfiComponentNameProtocolGuid,       ComponentName,

+                        &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                        &gEfiDriverDiagnosticsProtocolGuid,   DriverDiagnostics,

+                        NULL

+                        );

+      }

+    }

+  }

+

+  //

+  // ASSERT if the call to InstallMultipleProtocolInterfaces() failed

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+

+

+/**

+  Installs Driver Binding Protocol with optional Component Name and Component Name 2 Protocols.

+

+  Initializes a driver by installing the Driver Binding Protocol together with the

+  optional Component Name and optional Component Name 2 protocols onto the driver's

+  DriverBindingHandle.  If DriverBindingHandle is NULL, then the protocols are installed

+  onto a newly created handle.  DriverBindingHandle is typically the same as the driver's

+  ImageHandle, but it can be different if the driver produces multiple Driver Binding Protocols. 

+  If DriverBinding is NULL, then ASSERT(). 

+  If the installation fails, then ASSERT().

+

+  @param  ImageHandle          The image handle of the driver.

+  @param  SystemTable          The EFI System Table that was passed to the driver's entry point.

+  @param  DriverBinding        A Driver Binding Protocol instance that this driver is producing.

+  @param  DriverBindingHandle  The handle that DriverBinding is to be installed onto.  If this

+                               parameter is NULL, then a new handle is created.

+  @param  ComponentName        A Component Name Protocol instance that this driver is producing.

+  @param  ComponentName2       A Component Name 2 Protocol instance that this driver is producing.

+

+  @retval EFI_SUCCESS           The protocol installation successfully completed.

+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiLibInstallDriverBindingComponentName2 (

+  IN CONST EFI_HANDLE                         ImageHandle,

+  IN CONST EFI_SYSTEM_TABLE                   *SystemTable,

+  IN EFI_DRIVER_BINDING_PROTOCOL              *DriverBinding,

+  IN EFI_HANDLE                               DriverBindingHandle,

+  IN CONST EFI_COMPONENT_NAME_PROTOCOL        *ComponentName,       OPTIONAL

+  IN CONST EFI_COMPONENT_NAME2_PROTOCOL       *ComponentName2       OPTIONAL

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (DriverBinding != NULL);

+

+  //

+  // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol

+  //

+  DriverBinding->ImageHandle         = ImageHandle;

+  DriverBinding->DriverBindingHandle = DriverBindingHandle;

+

+  if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+    if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &DriverBinding->DriverBindingHandle,

+                      &gEfiDriverBindingProtocolGuid, DriverBinding,

+                      NULL

+                      );

+      } else {

+      Status = gBS->InstallMultipleProtocolInterfaces (

+                      &DriverBinding->DriverBindingHandle,

+                      &gEfiDriverBindingProtocolGuid, DriverBinding,

+                      &gEfiComponentName2ProtocolGuid, ComponentName2,

+                      NULL

+                      );

+     }

+  } else {

+     if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+       Status = gBS->InstallMultipleProtocolInterfaces (

+                       &DriverBinding->DriverBindingHandle,

+                       &gEfiDriverBindingProtocolGuid, DriverBinding,

+                       &gEfiComponentNameProtocolGuid, ComponentName,

+                       NULL

+                       );

+     } else {

+       Status = gBS->InstallMultipleProtocolInterfaces (

+                       &DriverBinding->DriverBindingHandle,

+                       &gEfiDriverBindingProtocolGuid, DriverBinding,

+                       &gEfiComponentNameProtocolGuid, ComponentName,

+                       &gEfiComponentName2ProtocolGuid, ComponentName2,

+                       NULL

+                       );

+    }

+  }

+

+  //

+  // ASSERT if the call to InstallMultipleProtocolInterfaces() failed

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+

+

+/**

+  Installs Driver Binding Protocol with optional Component Name, Component Name 2, Driver

+  Configuration, Driver Configuration 2, Driver Diagnostics, and Driver Diagnostics 2 Protocols.

+

+  Initializes a driver by installing the Driver Binding Protocol together with the optional

+  Component Name, optional Component Name 2, optional Driver Configuration, optional Driver Configuration 2,

+  optional Driver Diagnostic, and optional Driver Diagnostic 2 Protocols onto the driver's DriverBindingHandle.

+  DriverBindingHandle is typically the same as the driver's ImageHandle, but it can be different if the driver

+  produces multiple Driver Binding Protocols. 

+  If DriverBinding is NULL, then ASSERT(). 

+  If the installation fails, then ASSERT().

+

+

+  @param  ImageHandle           The image handle of the driver.

+  @param  SystemTable           The EFI System Table that was passed to the driver's entry point.

+  @param  DriverBinding         A Driver Binding Protocol instance that this driver is producing.

+  @param  DriverBindingHandle   The handle that DriverBinding is to be installed onto.  If this

+                                parameter is NULL, then a new handle is created.

+  @param  ComponentName         A Component Name Protocol instance that this driver is producing.

+  @param  ComponentName2        A Component Name 2 Protocol instance that this driver is producing.

+  @param  DriverConfiguration   A Driver Configuration Protocol instance that this driver is producing.

+  @param  DriverConfiguration2  A Driver Configuration Protocol 2 instance that this driver is producing.

+  @param  DriverDiagnostics     A Driver Diagnostics Protocol instance that this driver is producing.

+  @param  DriverDiagnostics2    A Driver Diagnostics Protocol 2 instance that this driver is producing.

+

+  @retval EFI_SUCCESS           The protocol installation successfully completed.

+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiLibInstallAllDriverProtocols2 (

+  IN CONST EFI_HANDLE                         ImageHandle,

+  IN CONST EFI_SYSTEM_TABLE                   *SystemTable,

+  IN EFI_DRIVER_BINDING_PROTOCOL              *DriverBinding,

+  IN EFI_HANDLE                               DriverBindingHandle,

+  IN CONST EFI_COMPONENT_NAME_PROTOCOL        *ComponentName,        OPTIONAL

+  IN CONST EFI_COMPONENT_NAME2_PROTOCOL       *ComponentName2,       OPTIONAL

+  IN CONST EFI_DRIVER_CONFIGURATION_PROTOCOL  *DriverConfiguration,  OPTIONAL

+  IN CONST EFI_DRIVER_CONFIGURATION2_PROTOCOL *DriverConfiguration2, OPTIONAL

+  IN CONST EFI_DRIVER_DIAGNOSTICS_PROTOCOL    *DriverDiagnostics,    OPTIONAL

+  IN CONST EFI_DRIVER_DIAGNOSTICS2_PROTOCOL   *DriverDiagnostics2    OPTIONAL

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (DriverBinding != NULL); 

+

+  //

+  // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol

+  //

+  DriverBinding->ImageHandle         = ImageHandle;

+  DriverBinding->DriverBindingHandle = DriverBindingHandle;

+  

+  if (DriverConfiguration2 == NULL) {

+    if (DriverConfiguration == NULL) {

+      if (DriverDiagnostics == NULL || FeaturePcdGet(PcdDriverDiagnosticsDisable)) {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      } else {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      }

+    } else {

+      if (DriverDiagnostics == NULL || FeaturePcdGet(PcdDriverDiagnosticsDisable)) {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      } else {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      }

+    }

+  } else {

+    if (DriverConfiguration == NULL) {

+      if (DriverDiagnostics == NULL || FeaturePcdGet(PcdDriverDiagnosticsDisable)) {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      } else {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      }

+    } else {

+      if (DriverDiagnostics == NULL || FeaturePcdGet(PcdDriverDiagnosticsDisable)) {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      } else {

+        if (DriverDiagnostics2 == NULL || FeaturePcdGet(PcdDriverDiagnostics2Disable)) {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              NULL

+                              );

+            }

+          }

+        } else {

+          if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          } else {

+            if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            } else {

+              Status = gBS->InstallMultipleProtocolInterfaces (

+                              &DriverBinding->DriverBindingHandle,

+                              &gEfiDriverBindingProtocolGuid, DriverBinding,

+                              &gEfiComponentNameProtocolGuid, ComponentName,

+                              &gEfiComponentName2ProtocolGuid, ComponentName2,

+                              &gEfiDriverConfigurationProtocolGuid, DriverConfiguration,

+                              &gEfiDriverConfiguration2ProtocolGuid, DriverConfiguration2,

+                              &gEfiDriverDiagnosticsProtocolGuid, DriverDiagnostics,

+                              &gEfiDriverDiagnostics2ProtocolGuid, DriverDiagnostics2,

+                              NULL

+                              );

+            }

+          }

+        }

+      }

+    }

+  }

+

+  //

+  // ASSERT if the call to InstallMultipleProtocolInterfaces() failed

+  //

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.c
new file mode 100644
index 0000000..112766a
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.c
@@ -0,0 +1,1547 @@
+/** @file

+  The UEFI Library provides functions and macros that simplify the development of 

+  UEFI Drivers and UEFI Applications.  These functions and macros help manage EFI 

+  events, build simple locks utilizing EFI Task Priority Levels (TPLs), install 

+  EFI Driver Model related protocols, manage Unicode string tables for UEFI Drivers, 

+  and print messages on the console output and standard error devices.

+

+  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.

+

+**/

+

+

+#include "UefiLibInternal.h"

+

+/**

+  Empty constructor function that is required to resolve dependencies between 

+  libraries.

+  

+    ** DO NOT REMOVE **

+  

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor executed correctly.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  return EFI_SUCCESS;

+}

+

+/**

+  Compare whether two names of languages are identical.

+

+  @param  Language1 Name of language 1.

+  @param  Language2 Name of language 2.

+

+  @retval TRUE      Language 1 and language 2 are the same.

+  @retval FALSE     Language 1 and language 2 are not the same.

+

+**/

+BOOLEAN

+CompareIso639LanguageCode (

+  IN CONST CHAR8  *Language1,

+  IN CONST CHAR8  *Language2

+  )

+{

+  UINT32  Name1;

+  UINT32  Name2;

+

+  Name1 = ReadUnaligned24 ((CONST UINT32 *) Language1);

+  Name2 = ReadUnaligned24 ((CONST UINT32 *) Language2);

+

+  return (BOOLEAN) (Name1 == Name2);

+}

+

+/**

+  Retrieves a pointer to the system configuration table from the EFI System Table

+  based on a specified GUID.

+  

+  This function searches the list of configuration tables stored in the EFI System Table

+  for a table with a GUID that matches TableGuid.  If a match is found, then a pointer to

+  the configuration table is returned in Table., and EFI_SUCCESS is returned. If a matching GUID

+  is not found, then EFI_NOT_FOUND is returned.

+  If TableGuid is NULL, then ASSERT().

+  If Table is NULL, then ASSERT().

+

+  @param  TableGuid       The pointer to table's GUID type.

+  @param  Table           The pointer to the table associated with TableGuid in the EFI System Table.

+

+  @retval EFI_SUCCESS     A configuration table matching TableGuid was found.

+  @retval EFI_NOT_FOUND   A configuration table matching TableGuid could not be found.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetSystemConfigurationTable (

+  IN  EFI_GUID  *TableGuid,

+  OUT VOID      **Table

+  )

+{

+  EFI_SYSTEM_TABLE  *SystemTable;

+  UINTN             Index;

+

+  ASSERT (TableGuid != NULL);

+  ASSERT (Table != NULL);

+

+  SystemTable = gST;

+  *Table = NULL;

+  for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {

+    if (CompareGuid (TableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {

+      *Table = SystemTable->ConfigurationTable[Index].VendorTable;

+      return EFI_SUCCESS;

+    }

+  }

+

+  return EFI_NOT_FOUND;

+}

+

+/**

+  Creates and returns a notification event and registers that event with all the protocol

+  instances specified by ProtocolGuid.

+

+  This function causes the notification function to be executed for every protocol of type

+  ProtocolGuid instance that exists in the system when this function is invoked. If there are

+  no instances of ProtocolGuid in the handle database at the time this function is invoked,

+  then the notification function is still executed one time. In addition, every time a protocol

+  of type ProtocolGuid instance is installed or reinstalled, the notification function is also

+  executed. This function returns the notification event that was created. 

+  If ProtocolGuid is NULL, then ASSERT().

+  If NotifyTpl is not a legal TPL value, then ASSERT().

+  If NotifyFunction is NULL, then ASSERT().

+  If Registration is NULL, then ASSERT().

+

+

+  @param  ProtocolGuid    Supplies GUID of the protocol upon whose installation the event is fired.

+  @param  NotifyTpl       Supplies the task priority level of the event notifications.

+  @param  NotifyFunction  Supplies the function to notify when the event is signaled.

+  @param  NotifyContext   The context parameter to pass to NotifyFunction.

+  @param  Registration    A pointer to a memory location to receive the registration value.

+                          This value is passed to LocateHandle() to obtain new handles that

+                          have been added that support the ProtocolGuid-specified protocol. 

+

+  @return The notification event that was created.

+

+**/

+EFI_EVENT

+EFIAPI

+EfiCreateProtocolNotifyEvent(

+  IN  EFI_GUID          *ProtocolGuid,

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT VOID              **Registration

+  )

+{

+  EFI_STATUS  Status;

+  EFI_EVENT   Event;

+

+  ASSERT (ProtocolGuid != NULL);

+  ASSERT (NotifyFunction != NULL);

+  ASSERT (Registration != NULL);

+

+  //

+  // Create the event

+  //

+

+  Status = gBS->CreateEvent (

+                  EVT_NOTIFY_SIGNAL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  NotifyContext,

+                  &Event

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Register for protocol notifications on this event

+  //

+

+  Status = gBS->RegisterProtocolNotify (

+                  ProtocolGuid,

+                  Event,

+                  Registration

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // Kick the event so we will perform an initial pass of

+  // current installed drivers

+  //

+

+  gBS->SignalEvent (Event);

+  return Event;

+}

+

+/**

+  Creates a named event that can be signaled with EfiNamedEventSignal().

+

+  This function creates an event using NotifyTpl, NoifyFunction, and NotifyContext.

+  This event is signaled with EfiNamedEventSignal(). This provides the ability for one or more

+  listeners on the same event named by the GUID specified by Name. 

+  If Name is NULL, then ASSERT().

+  If NotifyTpl is not a legal TPL value, then ASSERT().

+  If NotifyFunction is NULL, then ASSERT().

+

+  @param  Name                  Supplies the GUID name of the event.

+  @param  NotifyTpl             Supplies the task priority level of the event notifications.

+  @param  NotifyFunction        Supplies the function to notify when the event is signaled.

+  @param  NotifyContext         The context parameter to pass to NotifyFunction. 

+  @param  Registration          A pointer to a memory location to receive the registration value.

+

+  @retval EFI_SUCCESS           A named event was created.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to create the named event.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiNamedEventListen (

+  IN CONST EFI_GUID    *Name,

+  IN EFI_TPL           NotifyTpl,

+  IN EFI_EVENT_NOTIFY  NotifyFunction,

+  IN CONST VOID        *NotifyContext,  OPTIONAL

+  OUT VOID             *Registration OPTIONAL

+  )

+{

+  EFI_STATUS  Status;

+  EFI_EVENT   Event;

+  VOID        *RegistrationLocal;

+

+  ASSERT (Name != NULL);

+  ASSERT (NotifyFunction != NULL);

+  ASSERT (NotifyTpl <= TPL_HIGH_LEVEL);

+  

+  //

+  // Create event

+  //

+  Status = gBS->CreateEvent (

+                  EVT_NOTIFY_SIGNAL,

+                  NotifyTpl,

+                  NotifyFunction,

+                  (VOID *) NotifyContext,

+                  &Event

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  //

+  // The Registration is not optional to RegisterProtocolNotify().

+  // To make it optional to EfiNamedEventListen(), may need to substitute with a local.

+  //

+  if (Registration != NULL) {

+    RegistrationLocal = Registration;

+  } else {

+    RegistrationLocal = &RegistrationLocal;

+  }

+

+  //

+  // Register for an installation of protocol interface

+  //

+

+  Status = gBS->RegisterProtocolNotify (

+                  (EFI_GUID *) Name,

+                  Event,

+                  RegistrationLocal

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  Signals a named event created with EfiNamedEventListen().

+

+  This function signals the named event specified by Name. The named event must have been

+  created with EfiNamedEventListen().

+  If Name is NULL, then ASSERT().

+

+  @param  Name                  Supplies the GUID name of the event.

+

+  @retval EFI_SUCCESS           A named event was signaled.

+  @retval EFI_OUT_OF_RESOURCES  There are not enough resource to signal the named event.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiNamedEventSignal (

+  IN CONST EFI_GUID  *Name

+  )

+{

+  EFI_STATUS  Status;

+  EFI_HANDLE  Handle;

+

+  ASSERT(Name != NULL);

+

+  Handle = NULL;

+  Status = gBS->InstallProtocolInterface (

+                  &Handle,

+                  (EFI_GUID *) Name,

+                  EFI_NATIVE_INTERFACE,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gBS->UninstallProtocolInterface (

+                  Handle,

+                  (EFI_GUID *) Name,

+                  NULL

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/** 

+  Returns the current TPL.

+

+  This function returns the current TPL.  There is no EFI service to directly 

+  retrieve the current TPL. Instead, the RaiseTPL() function is used to raise 

+  the TPL to TPL_HIGH_LEVEL.  This will return the current TPL.  The TPL level 

+  can then immediately be restored back to the current TPL level with a call 

+  to RestoreTPL().

+

+  @return The current TPL.

+

+**/

+EFI_TPL

+EFIAPI

+EfiGetCurrentTpl (

+  VOID

+  )

+{

+  EFI_TPL Tpl;

+

+  Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+  gBS->RestoreTPL (Tpl);

+

+  return Tpl;

+}

+

+

+/**

+  Initializes a basic mutual exclusion lock.

+

+  This function initializes a basic mutual exclusion lock to the released state 

+  and returns the lock.  Each lock provides mutual exclusion access at its task 

+  priority level.  Since there is no preemption or multiprocessor support in EFI,

+  acquiring the lock only consists of raising to the locks TPL.

+  If Lock is NULL, then ASSERT().

+  If Priority is not a valid TPL value, then ASSERT().

+

+  @param  Lock       A pointer to the lock data structure to initialize.

+  @param  Priority   EFI TPL is associated with the lock.

+

+  @return The lock.

+

+**/

+EFI_LOCK *

+EFIAPI

+EfiInitializeLock (

+  IN OUT EFI_LOCK  *Lock,

+  IN EFI_TPL        Priority

+  )

+{

+  ASSERT (Lock != NULL);

+  ASSERT (Priority <= TPL_HIGH_LEVEL);

+

+  Lock->Tpl       = Priority;

+  Lock->OwnerTpl  = TPL_APPLICATION;

+  Lock->Lock      = EfiLockReleased ;

+  return Lock;

+}

+

+/**

+  Acquires ownership of a lock.

+

+  This function raises the system's current task priority level to the task 

+  priority level of the mutual exclusion lock.  Then, it places the lock in the 

+  acquired state.

+  If Lock is NULL, then ASSERT().

+  If Lock is not initialized, then ASSERT().

+  If Lock is already in the acquired state, then ASSERT().

+

+  @param  Lock              A pointer to the lock to acquire.

+

+**/

+VOID

+EFIAPI

+EfiAcquireLock (

+  IN EFI_LOCK  *Lock

+  )

+{

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock == EfiLockReleased);

+

+  Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);

+  Lock->Lock     = EfiLockAcquired;

+}

+

+/**

+  Acquires ownership of a lock.

+

+  This function raises the system's current task priority level to the task priority

+  level of the mutual exclusion lock.  Then, it attempts to place the lock in the acquired state.

+  If the lock is already in the acquired state, then EFI_ACCESS_DENIED is returned.

+  Otherwise, EFI_SUCCESS is returned.

+  If Lock is NULL, then ASSERT().

+  If Lock is not initialized, then ASSERT().

+

+  @param  Lock              A pointer to the lock to acquire.

+

+  @retval EFI_SUCCESS       The lock was acquired.

+  @retval EFI_ACCESS_DENIED The lock could not be acquired because it is already owned.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiAcquireLockOrFail (

+  IN EFI_LOCK  *Lock

+  )

+{

+

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock != EfiLockUninitialized);

+

+  if (Lock->Lock == EfiLockAcquired) {

+    //

+    // Lock is already owned, so bail out

+    //

+    return EFI_ACCESS_DENIED;

+  }

+

+  Lock->OwnerTpl = gBS->RaiseTPL (Lock->Tpl);

+

+  Lock->Lock = EfiLockAcquired;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Releases ownership of a lock.

+

+  This function transitions a mutual exclusion lock from the acquired state to 

+  the released state, and restores the system's task priority level to its 

+  previous level.

+  If Lock is NULL, then ASSERT().

+  If Lock is not initialized, then ASSERT().

+  If Lock is already in the released state, then ASSERT().

+

+  @param  Lock  A pointer to the lock to release.

+

+**/

+VOID

+EFIAPI

+EfiReleaseLock (

+  IN EFI_LOCK  *Lock

+  )

+{

+  EFI_TPL Tpl;

+

+  ASSERT (Lock != NULL);

+  ASSERT (Lock->Lock == EfiLockAcquired);

+

+  Tpl = Lock->OwnerTpl;

+

+  Lock->Lock = EfiLockReleased;

+

+  gBS->RestoreTPL (Tpl);

+}

+

+/**

+  Tests whether a controller handle is being managed by a specific driver.

+

+  This function tests whether the driver specified by DriverBindingHandle is

+  currently managing the controller specified by ControllerHandle.  This test

+  is performed by evaluating if the the protocol specified by ProtocolGuid is

+  present on ControllerHandle and is was opened by DriverBindingHandle with an

+  attribute of EFI_OPEN_PROTOCOL_BY_DRIVER. 

+  If ProtocolGuid is NULL, then ASSERT().

+

+  @param  ControllerHandle     A handle for a controller to test.

+  @param  DriverBindingHandle  Specifies the driver binding handle for the

+                               driver.

+  @param  ProtocolGuid         Specifies the protocol that the driver specified

+                               by DriverBindingHandle opens in its Start()

+                               function.

+

+  @retval EFI_SUCCESS          ControllerHandle is managed by the driver

+                               specified by DriverBindingHandle.

+  @retval EFI_UNSUPPORTED      ControllerHandle is not managed by the driver

+                               specified by DriverBindingHandle.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiTestManagedDevice (

+  IN CONST EFI_HANDLE       ControllerHandle,

+  IN CONST EFI_HANDLE       DriverBindingHandle,

+  IN CONST EFI_GUID         *ProtocolGuid

+  )

+{

+  EFI_STATUS     Status;

+  VOID           *ManagedInterface;

+

+  ASSERT (ProtocolGuid != NULL);

+

+  Status = gBS->OpenProtocol (

+                  ControllerHandle,

+                  (EFI_GUID *) ProtocolGuid,

+                  &ManagedInterface,

+                  DriverBindingHandle,

+                  ControllerHandle,

+                  EFI_OPEN_PROTOCOL_BY_DRIVER

+                  );

+  if (!EFI_ERROR (Status)) {

+    gBS->CloseProtocol (

+           ControllerHandle,

+           (EFI_GUID *) ProtocolGuid,

+           DriverBindingHandle,

+           ControllerHandle

+           );

+    return EFI_UNSUPPORTED;

+  }

+

+  if (Status != EFI_ALREADY_STARTED) {

+    return EFI_UNSUPPORTED;

+  }

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Tests whether a child handle is a child device of the controller.

+

+  This function tests whether ChildHandle is one of the children of

+  ControllerHandle.  This test is performed by checking to see if the protocol

+  specified by ProtocolGuid is present on ControllerHandle and opened by

+  ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

+  If ProtocolGuid is NULL, then ASSERT().

+

+  @param  ControllerHandle     A handle for a (parent) controller to test. 

+  @param  ChildHandle          A child handle to test.

+  @param  ProtocolGuid         Supplies the protocol that the child controller

+                               opens on its parent controller. 

+

+  @retval EFI_SUCCESS          ChildHandle is a child of the ControllerHandle.

+  @retval EFI_UNSUPPORTED      ChildHandle is not a child of the

+                               ControllerHandle.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiTestChildHandle (

+  IN CONST EFI_HANDLE       ControllerHandle,

+  IN CONST EFI_HANDLE       ChildHandle,

+  IN CONST EFI_GUID         *ProtocolGuid

+  )

+{

+  EFI_STATUS                            Status;

+  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY   *OpenInfoBuffer;

+  UINTN                                 EntryCount;

+  UINTN                                 Index;

+

+  ASSERT (ProtocolGuid != NULL);

+

+  //

+  // Retrieve the list of agents that are consuming the specific protocol

+  // on ControllerHandle.

+  //

+  Status = gBS->OpenProtocolInformation (

+                  ControllerHandle,

+                  (EFI_GUID *) ProtocolGuid,

+                  &OpenInfoBuffer,

+                  &EntryCount

+                  );

+  if (EFI_ERROR (Status)) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Inspect if ChildHandle is one of the agents.

+  //

+  Status = EFI_UNSUPPORTED;

+  for (Index = 0; Index < EntryCount; Index++) {

+    if ((OpenInfoBuffer[Index].ControllerHandle == ChildHandle) &&

+        (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {

+      Status = EFI_SUCCESS;

+      break;

+    }

+  }

+

+  FreePool (OpenInfoBuffer);

+  return Status;

+}

+

+/**

+  This function looks up a Unicode string in UnicodeStringTable.

+

+  If Language is a member of SupportedLanguages and a Unicode string is found in

+  UnicodeStringTable that matches the language code specified by Language, then it

+  is returned in UnicodeString.

+

+  @param  Language                A pointer to the ISO 639-2 language code for the 

+                                  Unicode string to look up and return.

+  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes 

+                                  that the Unicode string table supports.  Language 

+                                  must be a member of this set.

+  @param  UnicodeStringTable      A pointer to the table of Unicode strings.

+  @param  UnicodeString           A pointer to the Unicode string from UnicodeStringTable

+                                  that matches the language specified by Language.

+

+  @retval EFI_SUCCESS             The Unicode string that matches the language 

+                                  specified by Language was found

+                                  in the table of Unicode strings UnicodeStringTable, 

+                                  and it was returned in UnicodeString.

+  @retval EFI_INVALID_PARAMETER   Language is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is NULL.

+  @retval EFI_UNSUPPORTED         SupportedLanguages is NULL.

+  @retval EFI_UNSUPPORTED         UnicodeStringTable is NULL.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not a 

+                                  member of SupportedLanguages.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not 

+                                  supported by UnicodeStringTable.

+

+**/

+EFI_STATUS

+EFIAPI

+LookupUnicodeString (

+  IN CONST CHAR8                     *Language,

+  IN CONST CHAR8                     *SupportedLanguages,

+  IN CONST EFI_UNICODE_STRING_TABLE  *UnicodeStringTable,

+  OUT CHAR16                         **UnicodeString

+  )

+{

+  //

+  // Make sure the parameters are valid

+  //

+  if (Language == NULL || UnicodeString == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If there are no supported languages, or the Unicode String Table is empty, then the

+  // Unicode String specified by Language is not supported by this Unicode String Table

+  //

+  if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Make sure Language is in the set of Supported Languages

+  //

+  while (*SupportedLanguages != 0) {

+    if (CompareIso639LanguageCode (Language, SupportedLanguages)) {

+

+      //

+      // Search the Unicode String Table for the matching Language specifier

+      //

+      while (UnicodeStringTable->Language != NULL) {

+        if (CompareIso639LanguageCode (Language, UnicodeStringTable->Language)) {

+

+          //

+          // A matching string was found, so return it

+          //

+          *UnicodeString = UnicodeStringTable->UnicodeString;

+          return EFI_SUCCESS;

+        }

+

+        UnicodeStringTable++;

+      }

+

+      return EFI_UNSUPPORTED;

+    }

+

+    SupportedLanguages += 3;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+

+

+/**

+  This function looks up a Unicode string in UnicodeStringTable.

+

+  If Language is a member of SupportedLanguages and a Unicode string is found in

+  UnicodeStringTable that matches the language code specified by Language, then

+  it is returned in UnicodeString.

+

+  @param  Language             A pointer to an ASCII string containing the ISO 639-2 or the

+                               RFC 4646 language code for the Unicode string to look up and

+                               return. If Iso639Language is TRUE, then this ASCII string is

+                               not assumed to be Null-terminated, and only the first three

+                               characters are used. If Iso639Language is FALSE, then this ASCII

+                               string must be Null-terminated. 

+  @param  SupportedLanguages   A pointer to a Null-terminated ASCII string that contains a

+                               set of ISO 639-2 or RFC 4646 language codes that the Unicode

+                               string table supports.  Language must be a member of this set.

+                               If Iso639Language is TRUE, then this string contains one or more

+                               ISO 639-2 language codes with no separator characters. If Iso639Language

+                               is FALSE, then is string contains one or more RFC 4646 language

+                               codes separated by ';'.

+  @param  UnicodeStringTable   A pointer to the table of Unicode strings. Type EFI_UNICODE_STRING_TABLE

+                               is defined in "Related Definitions".

+  @param  UnicodeString        A pointer to the Null-terminated Unicode string from UnicodeStringTable

+                               that matches the language specified by Language.

+  @param  Iso639Language       Specifies the supported language code format. If it is TRUE, then

+                               Language and SupportedLanguages follow ISO 639-2 language code format.

+                               Otherwise, they follow RFC 4646 language code format.

+

+

+  @retval  EFI_SUCCESS            The Unicode string that matches the language specified by Language

+                                  was found in the table of Unicode strings UnicodeStringTable, and

+                                  it was returned in UnicodeString.

+  @retval  EFI_INVALID_PARAMETER  Language is NULL.  

+  @retval  EFI_INVALID_PARAMETER  UnicodeString is NULL.  

+  @retval  EFI_UNSUPPORTED        SupportedLanguages is NULL.  

+  @retval  EFI_UNSUPPORTED        UnicodeStringTable is NULL.  

+  @retval  EFI_UNSUPPORTED        The language specified by Language is not a member of SupportedLanguages.  

+  @retval  EFI_UNSUPPORTED        The language specified by Language is not supported by UnicodeStringTable.

+

+**/

+EFI_STATUS

+EFIAPI

+LookupUnicodeString2 (

+  IN CONST CHAR8                     *Language,

+  IN CONST CHAR8                     *SupportedLanguages,

+  IN CONST EFI_UNICODE_STRING_TABLE  *UnicodeStringTable,

+  OUT CHAR16                         **UnicodeString,

+  IN BOOLEAN                         Iso639Language

+  )

+{

+  BOOLEAN   Found;

+  UINTN     Index;

+  CHAR8     *LanguageString;

+

+  //

+  // Make sure the parameters are valid

+  //

+  if (Language == NULL || UnicodeString == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If there are no supported languages, or the Unicode String Table is empty, then the

+  // Unicode String specified by Language is not supported by this Unicode String Table

+  //

+  if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Make sure Language is in the set of Supported Languages

+  //

+  Found = FALSE;

+  while (*SupportedLanguages != 0) {

+    if (Iso639Language) {

+      if (CompareIso639LanguageCode (Language, SupportedLanguages)) {

+        Found = TRUE;

+        break;

+      }

+      SupportedLanguages += 3;

+    } else {

+      for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);

+      if ((AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) && (Language[Index] == 0)) {

+        Found = TRUE;

+        break;

+      }

+      SupportedLanguages += Index;

+      for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);

+    }

+  }

+

+  //

+  // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED

+  //

+  if (!Found) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Search the Unicode String Table for the matching Language specifier

+  //

+  while (UnicodeStringTable->Language != NULL) {

+    LanguageString = UnicodeStringTable->Language;

+    while (0 != *LanguageString) {

+      for (Index = 0 ;LanguageString[Index] != 0 && LanguageString[Index] != ';'; Index++);

+      if (AsciiStrnCmp(LanguageString, Language, Index) == 0) {

+        *UnicodeString = UnicodeStringTable->UnicodeString;

+        return EFI_SUCCESS;

+      }

+      LanguageString += Index;

+      for (Index = 0 ;LanguageString[Index] != 0 && LanguageString[Index] == ';'; Index++);

+    }

+    UnicodeStringTable++;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  This function adds a Unicode string to UnicodeStringTable.

+

+  If Language is a member of SupportedLanguages then UnicodeString is added to 

+  UnicodeStringTable.  New buffers are allocated for both Language and 

+  UnicodeString.  The contents of Language and UnicodeString are copied into 

+  these new buffers.  These buffers are automatically freed when 

+  FreeUnicodeStringTable() is called.

+

+  @param  Language                A pointer to the ISO 639-2 language code for the Unicode 

+                                  string to add.

+  @param  SupportedLanguages      A pointer to the set of ISO 639-2 language codes

+                                  that the Unicode string table supports.

+                                  Language must be a member of this set.

+  @param  UnicodeStringTable      A pointer to the table of Unicode strings.

+  @param  UnicodeString           A pointer to the Unicode string to add.

+

+  @retval EFI_SUCCESS             The Unicode string that matches the language 

+                                  specified by Language was found in the table of 

+                                  Unicode strings UnicodeStringTable, and it was 

+                                  returned in UnicodeString.

+  @retval EFI_INVALID_PARAMETER   Language is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is NULL.

+  @retval EFI_INVALID_PARAMETER   UnicodeString is an empty string.

+  @retval EFI_UNSUPPORTED         SupportedLanguages is NULL.

+  @retval EFI_ALREADY_STARTED     A Unicode string with language Language is 

+                                  already present in UnicodeStringTable.

+  @retval EFI_OUT_OF_RESOURCES    There is not enough memory to add another 

+                                  Unicode string to UnicodeStringTable.

+  @retval EFI_UNSUPPORTED         The language specified by Language is not a 

+                                  member of SupportedLanguages.

+

+**/

+EFI_STATUS

+EFIAPI

+AddUnicodeString (

+  IN CONST CHAR8               *Language,

+  IN CONST CHAR8               *SupportedLanguages,

+  IN EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,

+  IN CONST CHAR16              *UnicodeString

+  )

+{

+  UINTN                     NumberOfEntries;

+  EFI_UNICODE_STRING_TABLE  *OldUnicodeStringTable;

+  EFI_UNICODE_STRING_TABLE  *NewUnicodeStringTable;

+  UINTN                     UnicodeStringLength;

+

+  //

+  // Make sure the parameter are valid

+  //

+  if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If there are no supported languages, then a Unicode String can not be added

+  //

+  if (SupportedLanguages == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // If the Unicode String is empty, then a Unicode String can not be added

+  //

+  if (UnicodeString[0] == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Make sure Language is a member of SupportedLanguages

+  //

+  while (*SupportedLanguages != 0) {

+    if (CompareIso639LanguageCode (Language, SupportedLanguages)) {

+

+      //

+      // Determine the size of the Unicode String Table by looking for a NULL Language entry

+      //

+      NumberOfEntries = 0;

+      if (*UnicodeStringTable != NULL) {

+        OldUnicodeStringTable = *UnicodeStringTable;

+        while (OldUnicodeStringTable->Language != NULL) {

+          if (CompareIso639LanguageCode (Language, OldUnicodeStringTable->Language)) {

+            return EFI_ALREADY_STARTED;

+          }

+

+          OldUnicodeStringTable++;

+          NumberOfEntries++;

+        }

+      }

+

+      //

+      // Allocate space for a new Unicode String Table.  It must hold the current number of

+      // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table

+      // marker

+      //

+      NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));

+      if (NewUnicodeStringTable == NULL) {

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // If the current Unicode String Table contains any entries, then copy them to the

+      // newly allocated Unicode String Table.

+      //

+      if (*UnicodeStringTable != NULL) {

+        CopyMem (

+           NewUnicodeStringTable,

+           *UnicodeStringTable,

+           NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)

+           );

+      }

+

+      //

+      // Allocate space for a copy of the Language specifier

+      //

+      NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (3, Language);

+      if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {

+        FreePool (NewUnicodeStringTable);

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // Compute the length of the Unicode String

+      //

+      for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)

+        ;

+

+      //

+      // Allocate space for a copy of the Unicode String

+      //

+      NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (

+                                                              (UnicodeStringLength + 1) * sizeof (CHAR16),

+                                                              UnicodeString

+                                                              );

+      if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {

+        FreePool (NewUnicodeStringTable[NumberOfEntries].Language);

+        FreePool (NewUnicodeStringTable);

+        return EFI_OUT_OF_RESOURCES;

+      }

+

+      //

+      // Mark the end of the Unicode String Table

+      //

+      NewUnicodeStringTable[NumberOfEntries + 1].Language       = NULL;

+      NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString  = NULL;

+

+      //

+      // Free the old Unicode String Table

+      //

+      if (*UnicodeStringTable != NULL) {

+        FreePool (*UnicodeStringTable);

+      }

+

+      //

+      // Point UnicodeStringTable at the newly allocated Unicode String Table

+      //

+      *UnicodeStringTable = NewUnicodeStringTable;

+

+      return EFI_SUCCESS;

+    }

+

+    SupportedLanguages += 3;

+  }

+

+  return EFI_UNSUPPORTED;

+}

+

+

+/**

+  This function adds the Null-terminated Unicode string specified by UnicodeString

+  to UnicodeStringTable.

+

+  If Language is a member of SupportedLanguages then UnicodeString is added to

+  UnicodeStringTable.  New buffers are allocated for both Language and UnicodeString.

+  The contents of Language and UnicodeString are copied into these new buffers.

+  These buffers are automatically freed when EfiLibFreeUnicodeStringTable() is called.

+

+  @param  Language            A pointer to an ASCII string containing the ISO 639-2 or

+                              the RFC 4646 language code for the Unicode string to add.

+                              If Iso639Language is TRUE, then this ASCII string is not

+                              assumed to be Null-terminated, and only the first three

+                              chacters are used. If Iso639Language is FALSE, then this

+                              ASCII string must be Null-terminated.

+  @param  SupportedLanguages  A pointer to a Null-terminated ASCII string that contains

+                              a set of ISO 639-2 or RFC 4646 language codes that the Unicode

+                              string table supports.  Language must be a member of this set.

+                              If Iso639Language is TRUE, then this string contains one or more

+                              ISO 639-2 language codes with no separator characters.

+                              If Iso639Language is FALSE, then is string contains one or more

+                              RFC 4646 language codes separated by ';'.

+  @param  UnicodeStringTable  A pointer to the table of Unicode strings. Type EFI_UNICODE_STRING_TABLE

+                              is defined in "Related Definitions".

+  @param  UnicodeString       A pointer to the Unicode string to add.  

+  @param  Iso639Language      Specifies the supported language code format. If it is TRUE,

+                              then Language and SupportedLanguages follow ISO 639-2 language code format.

+                              Otherwise, they follow RFC 4646 language code format.

+

+  @retval EFI_SUCCESS            The Unicode string that matches the language specified by

+                                 Language was found in the table of Unicode strings UnicodeStringTable,

+                                 and it was returned in UnicodeString.  

+  @retval EFI_INVALID_PARAMETER  Language is NULL.  

+  @retval EFI_INVALID_PARAMETER  UnicodeString is NULL.  

+  @retval EFI_INVALID_PARAMETER  UnicodeString is an empty string.  

+  @retval EFI_UNSUPPORTED        SupportedLanguages is NULL.  

+  @retval EFI_ALREADY_STARTED    A Unicode string with language Language is already present in

+                                 UnicodeStringTable.  

+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory to add another Unicode string UnicodeStringTable.  

+  @retval EFI_UNSUPPORTED        The language specified by Language is not a member of SupportedLanguages.

+

+**/

+EFI_STATUS

+EFIAPI

+AddUnicodeString2 (

+  IN CONST CHAR8               *Language,

+  IN CONST CHAR8               *SupportedLanguages,

+  IN EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,

+  IN CONST CHAR16              *UnicodeString,

+  IN BOOLEAN                   Iso639Language

+  )

+{

+  UINTN                     NumberOfEntries;

+  EFI_UNICODE_STRING_TABLE  *OldUnicodeStringTable;

+  EFI_UNICODE_STRING_TABLE  *NewUnicodeStringTable;

+  UINTN                     UnicodeStringLength;

+  BOOLEAN                   Found;

+  UINTN                     Index;

+  CHAR8                     *LanguageString;

+

+  //

+  // Make sure the parameter are valid

+  //

+  if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // If there are no supported languages, then a Unicode String can not be added

+  //

+  if (SupportedLanguages == NULL) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // If the Unicode String is empty, then a Unicode String can not be added

+  //

+  if (UnicodeString[0] == 0) {

+    return EFI_INVALID_PARAMETER;

+  }

+

+  //

+  // Make sure Language is a member of SupportedLanguages

+  //

+  Found = FALSE;

+  while (*SupportedLanguages != 0) {

+    if (Iso639Language) {

+      if (CompareIso639LanguageCode (Language, SupportedLanguages)) {

+        Found = TRUE;

+        break;

+      }

+      SupportedLanguages += 3;

+    } else {

+      for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);

+      if (AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) {

+        Found = TRUE;

+        break;

+      }

+      SupportedLanguages += Index;

+      for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);

+    }

+  }

+

+  //

+  // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED

+  //

+  if (!Found) {

+    return EFI_UNSUPPORTED;

+  }

+

+  //

+  // Determine the size of the Unicode String Table by looking for a NULL Language entry

+  //

+  NumberOfEntries = 0;

+  if (*UnicodeStringTable != NULL) {

+    OldUnicodeStringTable = *UnicodeStringTable;

+    while (OldUnicodeStringTable->Language != NULL) {

+      LanguageString = OldUnicodeStringTable->Language;

+

+      while (*LanguageString != 0) {

+        for (Index = 0; LanguageString[Index] != 0 && LanguageString[Index] != ';'; Index++);

+

+        if (AsciiStrnCmp (Language, LanguageString, Index) == 0) { 

+          return EFI_ALREADY_STARTED;

+        }

+        LanguageString += Index;

+        for (; *LanguageString != 0 && *LanguageString == ';'; LanguageString++);

+      }

+      OldUnicodeStringTable++;

+      NumberOfEntries++;

+    }

+  }

+

+  //

+  // Allocate space for a new Unicode String Table.  It must hold the current number of

+  // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table

+  // marker

+  //

+  NewUnicodeStringTable = AllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));

+  if (NewUnicodeStringTable == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // If the current Unicode String Table contains any entries, then copy them to the

+  // newly allocated Unicode String Table.

+  //

+  if (*UnicodeStringTable != NULL) {

+    CopyMem (

+      NewUnicodeStringTable,

+      *UnicodeStringTable,

+      NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)

+      );

+  }

+

+  //

+  // Allocate space for a copy of the Language specifier

+  //

+  NewUnicodeStringTable[NumberOfEntries].Language = AllocateCopyPool (AsciiStrSize(Language), Language);

+  if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {

+    FreePool (NewUnicodeStringTable);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Compute the length of the Unicode String

+  //

+  for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++);

+

+  //

+  // Allocate space for a copy of the Unicode String

+  //

+  NewUnicodeStringTable[NumberOfEntries].UnicodeString = AllocateCopyPool (StrSize (UnicodeString), UnicodeString);

+  if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {

+    FreePool (NewUnicodeStringTable[NumberOfEntries].Language);

+    FreePool (NewUnicodeStringTable);

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Mark the end of the Unicode String Table

+  //

+  NewUnicodeStringTable[NumberOfEntries + 1].Language       = NULL;

+  NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString  = NULL;

+

+  //

+  // Free the old Unicode String Table

+  //

+  if (*UnicodeStringTable != NULL) {

+    FreePool (*UnicodeStringTable);

+  }

+

+  //

+  // Point UnicodeStringTable at the newly allocated Unicode String Table

+  //

+  *UnicodeStringTable = NewUnicodeStringTable;

+

+  return EFI_SUCCESS;

+}

+

+/**

+  This function frees the table of Unicode strings in UnicodeStringTable.

+

+  If UnicodeStringTable is NULL, then EFI_SUCCESS is returned.

+  Otherwise, each language code, and each Unicode string in the Unicode string 

+  table are freed, and EFI_SUCCESS is returned.

+

+  @param  UnicodeStringTable  A pointer to the table of Unicode strings.

+

+  @retval EFI_SUCCESS         The Unicode string table was freed.

+

+**/

+EFI_STATUS

+EFIAPI

+FreeUnicodeStringTable (

+  IN EFI_UNICODE_STRING_TABLE  *UnicodeStringTable

+  )

+{

+  UINTN Index;

+

+  //

+  // If the Unicode String Table is NULL, then it is already freed

+  //

+  if (UnicodeStringTable == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Loop through the Unicode String Table until we reach the end of table marker

+  //

+  for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {

+

+    //

+    // Free the Language string from the Unicode String Table

+    //

+    FreePool (UnicodeStringTable[Index].Language);

+

+    //

+    // Free the Unicode String from the Unicode String Table

+    //

+    if (UnicodeStringTable[Index].UnicodeString != NULL) {

+      FreePool (UnicodeStringTable[Index].UnicodeString);

+    }

+  }

+

+  //

+  // Free the Unicode String Table itself

+  //

+  FreePool (UnicodeStringTable);

+

+  return EFI_SUCCESS;

+}

+

+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

+

+/**

+  [ATTENTION] This function will be deprecated for security reason.

+

+  Returns a pointer to an allocated buffer that contains the contents of a 

+  variable retrieved through the UEFI Runtime Service GetVariable().  The 

+  returned buffer is allocated using AllocatePool().  The caller is responsible

+  for freeing this buffer with FreePool().

+

+  If Name is NULL, then ASSERT().

+  If Guid is NULL, then ASSERT().

+

+  @param[in]  Name  The pointer to a Null-terminated Unicode string.

+  @param[in]  Guid  The pointer to an EFI_GUID structure

+

+  @retval NULL   The variable could not be retrieved.

+  @retval NULL   There are not enough resources available for the variable contents.

+  @retval Other  A pointer to allocated buffer containing the variable contents.

+

+**/

+VOID *

+EFIAPI

+GetVariable (

+  IN CONST CHAR16    *Name,

+  IN CONST EFI_GUID  *Guid

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       Size;

+  VOID        *Value;

+

+  ASSERT (Name != NULL);

+  ASSERT (Guid != NULL);

+

+  //

+  // Try to get the variable size.

+  //

+  Value = NULL;

+  Size = 0;

+  Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &Size, Value);

+  if (Status != EFI_BUFFER_TOO_SMALL) {

+    return NULL;

+  }

+

+  //

+  // Allocate buffer to get the variable.

+  //

+  Value = AllocatePool (Size);

+  if (Value == NULL) {

+    return NULL;

+  }

+

+  //

+  // Get the variable data.

+  //

+  Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &Size, Value);

+  if (EFI_ERROR (Status)) {

+    FreePool(Value);

+    return NULL;

+  }

+

+  return Value;

+}

+

+/**

+  [ATTENTION] This function will be deprecated for security reason.

+

+  Returns a pointer to an allocated buffer that contains the contents of a 

+  variable retrieved through the UEFI Runtime Service GetVariable().  This 

+  function always uses the EFI_GLOBAL_VARIABLE GUID to retrieve variables.

+  The returned buffer is allocated using AllocatePool().  The caller is 

+  responsible for freeing this buffer with FreePool().

+

+  If Name is NULL, then ASSERT().

+

+  @param[in]  Name  The pointer to a Null-terminated Unicode string.

+

+  @retval NULL   The variable could not be retrieved.

+  @retval NULL   There are not enough resources available for the variable contents.

+  @retval Other  A pointer to allocated buffer containing the variable contents.

+

+**/

+VOID *

+EFIAPI

+GetEfiGlobalVariable (

+  IN CONST CHAR16  *Name

+  )

+{

+  return GetVariable (Name, &gEfiGlobalVariableGuid);

+}

+#endif

+

+/**

+  Returns the status whether get the variable success. The function retrieves 

+  variable  through the UEFI Runtime Service GetVariable().  The 

+  returned buffer is allocated using AllocatePool().  The caller is responsible

+  for freeing this buffer with FreePool().

+

+  If Name  is NULL, then ASSERT().

+  If Guid  is NULL, then ASSERT().

+  If Value is NULL, then ASSERT().

+

+  @param[in]  Name  The pointer to a Null-terminated Unicode string.

+  @param[in]  Guid  The pointer to an EFI_GUID structure

+  @param[out] Value The buffer point saved the variable info.

+  @param[out] Size  The buffer size of the variable.

+

+  @return EFI_OUT_OF_RESOURCES      Allocate buffer failed.

+  @return EFI_SUCCESS               Find the specified variable.

+  @return Others Errors             Return errors from call to gRT->GetVariable.

+

+**/

+EFI_STATUS

+EFIAPI

+GetVariable2 (

+  IN CONST CHAR16    *Name,

+  IN CONST EFI_GUID  *Guid,

+  OUT VOID           **Value,

+  OUT UINTN          *Size OPTIONAL

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       BufferSize;

+

+  ASSERT (Name != NULL && Guid != NULL && Value != NULL);

+

+  //

+  // Try to get the variable size.

+  //

+  BufferSize = 0;

+  *Value     = NULL;

+  if (Size != NULL) {

+    *Size  = 0;

+  }

+  

+  Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);

+  if (Status != EFI_BUFFER_TOO_SMALL) {

+    return Status;

+  }

+

+  //

+  // Allocate buffer to get the variable.

+  //

+  *Value = AllocatePool (BufferSize);

+  ASSERT (*Value != NULL);

+  if (*Value == NULL) {

+    return EFI_OUT_OF_RESOURCES;

+  }

+

+  //

+  // Get the variable data.

+  //

+  Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);

+  if (EFI_ERROR (Status)) {

+    FreePool(*Value);

+    *Value = NULL;

+  }

+

+  if (Size != NULL) {

+    *Size = BufferSize;

+  }

+

+  return Status;

+}

+

+/**

+  Returns a pointer to an allocated buffer that contains the contents of a 

+  variable retrieved through the UEFI Runtime Service GetVariable().  This 

+  function always uses the EFI_GLOBAL_VARIABLE GUID to retrieve variables.

+  The returned buffer is allocated using AllocatePool().  The caller is 

+  responsible for freeing this buffer with FreePool().

+

+  If Name is NULL, then ASSERT().

+  If Value is NULL, then ASSERT().

+

+  @param[in]  Name  The pointer to a Null-terminated Unicode string.

+  @param[out] Value The buffer point saved the variable info.

+  @param[out] Size  The buffer size of the variable.

+

+  @return EFI_OUT_OF_RESOURCES      Allocate buffer failed.

+  @return EFI_SUCCESS               Find the specified variable.

+  @return Others Errors             Return errors from call to gRT->GetVariable.

+

+**/

+EFI_STATUS

+EFIAPI

+GetEfiGlobalVariable2 (

+  IN CONST CHAR16    *Name,

+  OUT VOID           **Value,

+  OUT UINTN          *Size OPTIONAL

+  )

+{

+  return GetVariable2 (Name, &gEfiGlobalVariableGuid, Value, Size);

+}

+

+/**

+  Returns a pointer to an allocated buffer that contains the best matching language 

+  from a set of supported languages.  

+  

+  This function supports both ISO 639-2 and RFC 4646 language codes, but language 

+  code types may not be mixed in a single call to this function.  The language 

+  code returned is allocated using AllocatePool().  The caller is responsible for 

+  freeing the allocated buffer using FreePool().  This function supports a variable

+  argument list that allows the caller to pass in a prioritized list of language 

+  codes to test against all the language codes in SupportedLanguages. 

+

+  If SupportedLanguages is NULL, then ASSERT().

+

+  @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string that

+                                  contains a set of language codes in the format 

+                                  specified by Iso639Language.

+  @param[in]  Iso639Language      If TRUE, then all language codes are assumed to be

+                                  in ISO 639-2 format.  If FALSE, then all language

+                                  codes are assumed to be in RFC 4646 language format

+  @param[in]  ...                 A variable argument list that contains pointers to 

+                                  Null-terminated ASCII strings that contain one or more

+                                  language codes in the format specified by Iso639Language.

+                                  The first language code from each of these language

+                                  code lists is used to determine if it is an exact or

+                                  close match to any of the language codes in 

+                                  SupportedLanguages.  Close matches only apply to RFC 4646

+                                  language codes, and the matching algorithm from RFC 4647

+                                  is used to determine if a close match is present.  If 

+                                  an exact or close match is found, then the matching

+                                  language code from SupportedLanguages is returned.  If

+                                  no matches are found, then the next variable argument

+                                  parameter is evaluated.  The variable argument list 

+                                  is terminated by a NULL.

+

+  @retval NULL   The best matching language could not be found in SupportedLanguages.

+  @retval NULL   There are not enough resources available to return the best matching 

+                 language.

+  @retval Other  A pointer to a Null-terminated ASCII string that is the best matching 

+                 language in SupportedLanguages.

+

+**/

+CHAR8 *

+EFIAPI

+GetBestLanguage (

+  IN CONST CHAR8  *SupportedLanguages, 

+  IN BOOLEAN      Iso639Language,

+  ...

+  )

+{

+  VA_LIST      Args;

+  CHAR8        *Language;

+  UINTN        CompareLength;

+  UINTN        LanguageLength;

+  CONST CHAR8  *Supported;

+  CHAR8        *BestLanguage;

+

+  ASSERT (SupportedLanguages != NULL);

+

+  VA_START (Args, Iso639Language);

+  while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) {

+    //

+    // Default to ISO 639-2 mode

+    //

+    CompareLength  = 3;

+    LanguageLength = MIN (3, AsciiStrLen (Language));

+

+    //

+    // If in RFC 4646 mode, then determine the length of the first RFC 4646 language code in Language

+    //

+    if (!Iso639Language) {

+      for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);

+    }

+

+    //

+    // Trim back the length of Language used until it is empty

+    //

+    while (LanguageLength > 0) {

+      //

+      // Loop through all language codes in SupportedLanguages

+      //

+      for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {

+        //

+        // In RFC 4646 mode, then Loop through all language codes in SupportedLanguages

+        //

+        if (!Iso639Language) {

+          //

+          // Skip ';' characters in Supported

+          //

+          for (; *Supported != '\0' && *Supported == ';'; Supported++);

+          //

+          // Determine the length of the next language code in Supported

+          //

+          for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);

+          //

+          // If Language is longer than the Supported, then skip to the next language

+          //

+          if (LanguageLength > CompareLength) {

+            continue;

+          }

+        }

+        //

+        // See if the first LanguageLength characters in Supported match Language

+        //

+        if (AsciiStrnCmp (Supported, Language, LanguageLength) == 0) {

+          VA_END (Args);

+          //

+          // Allocate, copy, and return the best matching language code from SupportedLanguages

+          //

+          BestLanguage = AllocateZeroPool (CompareLength + 1);

+          if (BestLanguage == NULL) {

+            return NULL;

+          }

+          return CopyMem (BestLanguage, Supported, CompareLength);

+        }

+      }

+

+      if (Iso639Language) {

+        //

+        // If ISO 639 mode, then each language can only be tested once

+        //

+        LanguageLength = 0;

+      } else {

+        //

+        // If RFC 4646 mode, then trim Language from the right to the next '-' character 

+        //

+        for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);

+      }

+    }

+  }

+  VA_END (Args);

+

+  //

+  // No matches were found 

+  //

+  return NULL;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.inf
new file mode 100644
index 0000000..8284dc5
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.inf
@@ -0,0 +1,89 @@
+## @file

+# Instance of UEFI Library.

+#

+# The UEFI Library provides functions and macros that simplify the development of 

+#  UEFI Drivers and UEFI Applications.  These functions and macros help manage EFI 

+#  events, build simple locks utilizing EFI Task Priority Levels (TPLs), install 

+#  EFI Driver Model related protocols, manage Unicode string tables for UEFI Drivers, 

+#  and print messages on the console output and standard error devices.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiLib

+  MODULE_UNI_FILE                = UefiLib.uni

+  FILE_GUID                      = 3a004ba5-efe0-4a61-9f1a-267a46ae5ba9

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+  CONSTRUCTOR                    = UefiLibConstructor

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  UefiLibPrint.c

+  UefiNotTiano.c

+  UefiDriverModel.c

+  Console.c

+  UefiLib.c

+  UefiLibInternal.h

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  PrintLib

+  PcdLib

+  MemoryAllocationLib

+  DebugLib

+  BaseMemoryLib

+  BaseLib

+  UefiBootServicesTableLib

+  DevicePathLib

+  UefiRuntimeServicesTableLib

+  

+[Guids]

+  gEfiEventReadyToBootGuid                      ## SOMETIMES_CONSUMES  ## Event

+  gEfiEventLegacyBootGuid                       ## SOMETIMES_CONSUMES  ## Event

+  gEfiGlobalVariableGuid                        ## SOMETIMES_CONSUMES  ## Variable

+

+[Protocols]

+  gEfiDriverBindingProtocolGuid                   ## SOMETIMES_PRODUCES

+  gEfiSimpleTextOutProtocolGuid                   ## SOMETIMES_CONSUMES

+  gEfiGraphicsOutputProtocolGuid                  ## SOMETIMES_CONSUMES

+  gEfiHiiFontProtocolGuid                         ## SOMETIMES_CONSUMES

+  gEfiUgaDrawProtocolGuid | gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport                 ## SOMETIMES_CONSUMES # Consumes if gEfiGraphicsOutputProtocolGuid uninstalled

+  gEfiComponentNameProtocolGuid  | NOT gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable   ## SOMETIMES_PRODUCES # User chooses to produce it

+  gEfiComponentName2ProtocolGuid | NOT gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable  ## SOMETIMES_PRODUCES # User chooses to produce it

+  gEfiDriverConfigurationProtocolGuid                            ## SOMETIMES_PRODUCES # User chooses to produce it

+  gEfiDriverConfiguration2ProtocolGuid                           ## SOMETIMES_PRODUCES # User chooses to produce it

+  gEfiDriverDiagnosticsProtocolGuid | NOT gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable  ## SOMETIMES_PRODUCES # User chooses to produce it

+  gEfiDriverDiagnostics2ProtocolGuid| NOT gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable ## SOMETIMES_PRODUCES # User chooses to produce it

+

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize   ## SOMETIMES_CONSUMES

+

+[FeaturePcd]

+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable    ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable        ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable   ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable       ## CONSUMES

+  gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport           ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.uni
new file mode 100644
index 0000000..6ae9eff
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLibInternal.h b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLibInternal.h
new file mode 100644
index 0000000..196830e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLibInternal.h
@@ -0,0 +1,44 @@
+/** @file

+  Internal include file for UefiLib.

+

+  Copyright (c) 2007 - 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_LIB_INTERNAL_H_

+#define __UEFI_LIB_INTERNAL_H_

+

+

+#include <Uefi.h>

+#include <Protocol/DriverBinding.h>

+#include <Protocol/ComponentName.h>

+#include <Protocol/ComponentName2.h>

+#include <Protocol/DriverConfiguration.h>

+#include <Protocol/DriverConfiguration2.h>

+#include <Protocol/DriverDiagnostics.h>

+#include <Protocol/DriverDiagnostics2.h>

+#include <Protocol/LoadedImage.h>

+#include <Protocol/GraphicsOutput.h>

+#include <Protocol/UgaDraw.h>

+#include <Protocol/HiiFont.h>

+

+#include <Guid/EventGroup.h>

+#include <Guid/EventLegacyBios.h>

+#include <Guid/GlobalVariable.h>

+#include <Library/UefiLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/BaseLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/PcdLib.h>

+#include <Library/PrintLib.h>

+#include <Library/DevicePathLib.h>

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLibPrint.c b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLibPrint.c
new file mode 100644
index 0000000..1bf6d26
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiLibPrint.c
@@ -0,0 +1,813 @@
+/** @file

+  Mde UEFI library API implementation.

+  Print to StdErr or ConOut defined in EFI_SYSTEM_TABLE

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include "UefiLibInternal.h"

+

+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_BLT_PIXEL mEfiColors[16] = {

+  { 0x00, 0x00, 0x00, 0x00 },

+  { 0x98, 0x00, 0x00, 0x00 },

+  { 0x00, 0x98, 0x00, 0x00 },

+  { 0x98, 0x98, 0x00, 0x00 },

+  { 0x00, 0x00, 0x98, 0x00 },

+  { 0x98, 0x00, 0x98, 0x00 },

+  { 0x00, 0x98, 0x98, 0x00 },

+  { 0x98, 0x98, 0x98, 0x00 },

+  { 0x10, 0x10, 0x10, 0x00 },

+  { 0xff, 0x10, 0x10, 0x00 },

+  { 0x10, 0xff, 0x10, 0x00 },

+  { 0xff, 0xff, 0x10, 0x00 },

+  { 0x10, 0x10, 0xff, 0x00 },

+  { 0xf0, 0x10, 0xff, 0x00 },

+  { 0x10, 0xff, 0xff, 0x00 },

+  { 0xff, 0xff, 0xff, 0x00 }

+};

+

+/**

+  Internal function which prints a formatted Unicode string to the console output device

+  specified by Console

+

+  This function prints a formatted Unicode string to the console output device

+  specified by Console and returns the number of Unicode characters that printed

+  to it.  If the length of the formatted Unicode string is greater than PcdUefiLibMaxPrintBufferSize,

+  then only the first PcdUefiLibMaxPrintBufferSize characters are sent to Console.

+  If Format is NULL, then ASSERT().

+  If Format is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param Format   A Null-terminated Unicode format string.

+  @param Console  The output console.

+  @param Marker   A 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

+InternalPrint (

+  IN  CONST CHAR16                     *Format,

+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,

+  IN  VA_LIST                          Marker

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       Return;

+  CHAR16      *Buffer;

+  UINTN       BufferSize;

+

+  ASSERT (Format != NULL);

+  ASSERT (((UINTN) Format & BIT0) == 0);

+  ASSERT (Console != NULL);

+

+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);

+

+  Buffer = (CHAR16 *) AllocatePool(BufferSize);

+  ASSERT (Buffer != NULL);

+

+  Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);

+

+  if (Console != NULL && Return > 0) {

+    //

+    // To be extra safe make sure Console has been initialized

+    //

+    Status = Console->OutputString (Console, Buffer);

+    if (EFI_ERROR (Status)) {

+      Return = 0;

+    }

+  }

+

+  FreePool (Buffer);

+

+  return Return;

+}

+

+/** 

+  Prints a formatted Unicode string to the console output device specified by 

+  ConOut defined in the EFI_SYSTEM_TABLE.

+

+  This function prints a formatted Unicode string to the console output device 

+  specified by ConOut in EFI_SYSTEM_TABLE and returns the number of Unicode 

+  characters that printed to ConOut.  If the length of the formatted Unicode 

+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first 

+  PcdUefiLibMaxPrintBufferSize characters are sent to ConOut.

+  If Format is NULL, then ASSERT().

+  If Format is not aligned on a 16-bit boundary, then ASSERT().

+  If gST->ConOut is NULL, then ASSERT().

+

+  @param Format   A Null-terminated Unicode format string.

+  @param ...      A Variable argument list whose contents are accessed based 

+                  on the format string specified by Format.

+  

+  @return The number of Unicode characters printed to ConOut.

+

+**/

+UINTN

+EFIAPI

+Print (

+  IN CONST CHAR16  *Format,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   Return;

+

+  VA_START (Marker, Format);

+

+  Return = InternalPrint (Format, gST->ConOut, Marker);

+

+  VA_END (Marker);

+

+  return Return;

+}

+

+/** 

+  Prints a formatted Unicode string to the console output device specified by 

+  StdErr defined in the EFI_SYSTEM_TABLE.

+

+  This function prints a formatted Unicode string to the console output device 

+  specified by StdErr in EFI_SYSTEM_TABLE and returns the number of Unicode 

+  characters that printed to StdErr.  If the length of the formatted Unicode 

+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first 

+  PcdUefiLibMaxPrintBufferSize characters are sent to StdErr.

+  If Format is NULL, then ASSERT().

+  If Format is not aligned on a 16-bit boundary, then ASSERT().

+  If gST->StdErr is NULL, then ASSERT().

+

+  @param Format   A Null-terminated Unicode format string.

+  @param ...      Variable argument list whose contents are accessed based 

+                  on the format string specified by Format.

+  

+  @return The number of Unicode characters printed to StdErr.

+

+**/

+UINTN

+EFIAPI

+ErrorPrint (

+  IN CONST CHAR16  *Format,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   Return;

+

+  VA_START (Marker, Format);

+

+  Return = InternalPrint( Format, gST->StdErr, Marker);

+

+  VA_END (Marker);

+

+  return Return;

+}

+

+

+/**

+  Internal function which prints a formatted ASCII string to the console output device

+  specified by Console

+

+  This function prints a formatted ASCII string to the console output device

+  specified by Console and returns the number of ASCII characters that printed

+  to it.  If the length of the formatted ASCII string is greater than PcdUefiLibMaxPrintBufferSize,

+  then only the first PcdUefiLibMaxPrintBufferSize characters are sent to Console.

+

+  If Format is NULL, then ASSERT().

+

+  @param Format   A Null-terminated ASCII format string.

+  @param Console  The output console.

+  @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

+AsciiInternalPrint (

+  IN  CONST CHAR8                      *Format,

+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,

+  IN  VA_LIST                          Marker

+  )

+{

+  EFI_STATUS  Status;

+  UINTN       Return;

+  CHAR16      *Buffer;

+  UINTN       BufferSize;

+

+  ASSERT (Format != NULL);

+  ASSERT (Console != NULL);

+

+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);

+

+  Buffer = (CHAR16 *) AllocatePool(BufferSize);

+  ASSERT (Buffer != NULL);

+

+  Return = UnicodeVSPrintAsciiFormat (Buffer, BufferSize, Format, Marker);

+

+  if (Console != NULL) {

+    //

+    // To be extra safe make sure Console has been initialized

+    //

+    Status = Console->OutputString (Console, Buffer);

+    if (EFI_ERROR (Status)) {

+      Return = 0;

+    }

+  }

+

+  FreePool (Buffer);

+

+  return Return;

+}

+

+/** 

+  Prints a formatted ASCII string to the console output device specified by 

+  ConOut defined in the EFI_SYSTEM_TABLE.

+

+  This function prints a formatted ASCII string to the console output device 

+  specified by ConOut in EFI_SYSTEM_TABLE and returns the number of ASCII 

+  characters that printed to ConOut.  If the length of the formatted ASCII 

+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first 

+  PcdUefiLibMaxPrintBufferSize characters are sent to ConOut.

+  If Format is NULL, then ASSERT().

+  If gST->ConOut is NULL, then ASSERT().

+

+  @param Format   A Null-terminated ASCII format string.

+  @param ...      Variable argument list whose contents are accessed based 

+                  on the format string specified by Format.

+  

+  @return The number of ASCII characters printed to ConOut.

+

+**/

+UINTN

+EFIAPI

+AsciiPrint (

+  IN CONST CHAR8  *Format,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   Return;

+  ASSERT (Format != NULL);

+

+  VA_START (Marker, Format);

+

+  Return = AsciiInternalPrint( Format, gST->ConOut, Marker);

+

+  VA_END (Marker);

+

+  return Return;

+}

+

+/** 

+  Prints a formatted ASCII string to the console output device specified by 

+  StdErr defined in the EFI_SYSTEM_TABLE.

+

+  This function prints a formatted ASCII string to the console output device 

+  specified by StdErr in EFI_SYSTEM_TABLE and returns the number of ASCII 

+  characters that printed to StdErr.  If the length of the formatted ASCII 

+  string is greater than PcdUefiLibMaxPrintBufferSize, then only the first 

+  PcdUefiLibMaxPrintBufferSize characters are sent to StdErr.

+  If Format is NULL, then ASSERT().

+  If gST->StdErr is NULL, then ASSERT().

+

+  @param Format   A Null-terminated ASCII format string.

+  @param ...      Variable argument list whose contents are accessed based 

+                  on the format string specified by Format.

+  

+  @return The number of ASCII characters printed to ConErr.

+

+**/

+UINTN

+EFIAPI

+AsciiErrorPrint (

+  IN CONST CHAR8  *Format,

+  ...

+  )

+{

+  VA_LIST Marker;

+  UINTN   Return;

+

+  ASSERT (Format != NULL);

+

+  VA_START (Marker, Format);

+

+  Return = AsciiInternalPrint( Format, gST->StdErr, Marker);

+

+  VA_END (Marker);

+

+  return Return;

+}

+

+/**

+  Internal function to print a formatted Unicode string to a graphics console device specified by

+  ConsoleOutputHandle defined in the EFI_SYSTEM_TABLE at the given (X,Y) coordinates.

+

+  This function prints a formatted Unicode string to the graphics console device

+  specified by ConsoleOutputHandle in EFI_SYSTEM_TABLE and returns the number of

+  Unicode characters printed. The EFI_HII_FONT_PROTOCOL is used to convert the

+  string to a bitmap using the glyphs registered with the

+  HII database.  No wrapping is performed, so any portions of the string the fall

+  outside the active display region will not be displayed.

+

+  If a graphics console device is not associated with the ConsoleOutputHandle

+  defined in the EFI_SYSTEM_TABLE then no string is printed, and 0 is returned.

+  If the EFI_HII_FONT_PROTOCOL is not present in the handle database, then no

+  string is printed, and 0 is returned.

+

+  @param  PointX       An X coordinate to print the string.

+  @param  PointY       A Y coordinate to print the string.

+  @param  Foreground   The foreground color of the string being printed.  This is

+                       an optional parameter that may be NULL.  If it is NULL,

+                       then the foreground color of the current ConOut device

+                       in the EFI_SYSTEM_TABLE is used.

+  @param  Background   The background color of the string being printed.  This is

+                       an optional parameter that may be NULL.  If it is NULL,

+                       then the background color of the current ConOut device

+                       in the EFI_SYSTEM_TABLE is used.

+  @param  Buffer       A Null-terminated Unicode formatted string.

+  @param  PrintNum     The number of Unicode formatted string to be printed.

+

+  @return  The number of Unicode Characters printed. Zero means no any character

+           displayed successfully.

+

+**/

+UINTN

+InternalPrintGraphic (

+  IN UINTN                            PointX,

+  IN UINTN                            PointY,

+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Foreground,

+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *Background,

+  IN CHAR16                           *Buffer,

+  IN UINTN                            PrintNum

+  )

+{

+  EFI_STATUS                          Status;

+  UINT32                              HorizontalResolution;

+  UINT32                              VerticalResolution;

+  UINT32                              ColorDepth;

+  UINT32                              RefreshRate;

+  EFI_HII_FONT_PROTOCOL               *HiiFont;

+  EFI_IMAGE_OUTPUT                    *Blt;

+  EFI_FONT_DISPLAY_INFO               FontInfo;

+  EFI_HII_ROW_INFO                    *RowInfoArray;

+  UINTN                               RowInfoArraySize;

+  EFI_GRAPHICS_OUTPUT_PROTOCOL        *GraphicsOutput;

+  EFI_UGA_DRAW_PROTOCOL               *UgaDraw;

+  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL     *Sto;

+  EFI_HANDLE                          ConsoleHandle;

+  UINTN                               Width;

+  UINTN                               Height;

+  UINTN                               Delta;

+

+  HorizontalResolution  = 0;

+  VerticalResolution    = 0;

+  Blt                   = NULL;

+  RowInfoArray          = NULL;

+

+  ConsoleHandle = gST->ConsoleOutHandle;

+  

+  ASSERT( ConsoleHandle != NULL);

+

+  Status = gBS->HandleProtocol (

+                  ConsoleHandle,

+                  &gEfiGraphicsOutputProtocolGuid,

+                  (VOID **) &GraphicsOutput

+                  );

+

+  UgaDraw = NULL;

+  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {

+    //

+    // If no GOP available, try to open UGA Draw protocol if supported.

+    //

+    GraphicsOutput = NULL;

+

+    Status = gBS->HandleProtocol (

+                    ConsoleHandle,

+                    &gEfiUgaDrawProtocolGuid,

+                    (VOID **) &UgaDraw

+                    );

+  }

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  Status = gBS->HandleProtocol (

+                  ConsoleHandle,

+                  &gEfiSimpleTextOutProtocolGuid,

+                  (VOID **) &Sto

+                  );

+

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  if (GraphicsOutput != NULL) {

+    HorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;

+    VerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;

+  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {

+    UgaDraw->GetMode (UgaDraw, &HorizontalResolution, &VerticalResolution, &ColorDepth, &RefreshRate);

+  } else {

+    goto Error;

+  }

+

+  ASSERT ((HorizontalResolution != 0) && (VerticalResolution !=0));

+

+  Status = gBS->LocateProtocol (&gEfiHiiFontProtocolGuid, NULL, (VOID **) &HiiFont);

+  if (EFI_ERROR (Status)) {

+    goto Error;

+  }

+

+  Blt = (EFI_IMAGE_OUTPUT *) AllocateZeroPool (sizeof (EFI_IMAGE_OUTPUT));

+  ASSERT (Blt != NULL);

+

+  Blt->Width        = (UINT16) (HorizontalResolution);

+  Blt->Height       = (UINT16) (VerticalResolution);

+

+  ZeroMem (&FontInfo, sizeof (EFI_FONT_DISPLAY_INFO));

+

+  if (Foreground != NULL) {

+    CopyMem (&FontInfo.ForegroundColor, Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

+  } else {

+    CopyMem (

+      &FontInfo.ForegroundColor,

+      &mEfiColors[Sto->Mode->Attribute & 0x0f],

+      sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)

+      );

+  }

+  if (Background != NULL) {

+    CopyMem (&FontInfo.BackgroundColor, Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

+  } else {

+    CopyMem (

+      &FontInfo.BackgroundColor,

+      &mEfiColors[Sto->Mode->Attribute >> 4],

+      sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)

+      );

+  }

+

+  if (GraphicsOutput != NULL) {

+    Blt->Image.Screen = GraphicsOutput;

+

+    Status = HiiFont->StringToImage (

+                         HiiFont,

+                         EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_OUT_FLAG_CLIP |

+                         EFI_HII_OUT_FLAG_CLIP_CLEAN_X | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y |

+                         EFI_HII_IGNORE_LINE_BREAK | EFI_HII_DIRECT_TO_SCREEN,

+                         Buffer,

+                         &FontInfo,

+                         &Blt,

+                         PointX,

+                         PointY,

+                         &RowInfoArray,

+                         &RowInfoArraySize,

+                         NULL

+                         );

+    if (EFI_ERROR (Status)) {

+      goto Error;

+    }

+

+  } else if (FeaturePcdGet (PcdUgaConsumeSupport)) {

+    ASSERT (UgaDraw!= NULL);

+

+    Blt->Image.Bitmap = AllocateZeroPool (Blt->Width * Blt->Height * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

+    ASSERT (Blt->Image.Bitmap != NULL);

+

+    //

+    //  StringToImage only support blt'ing image to device using GOP protocol. If GOP is not supported in this platform,

+    //  we ask StringToImage to print the string to blt buffer, then blt to device using UgaDraw.

+    //

+    Status = HiiFont->StringToImage (

+                         HiiFont,

+                         EFI_HII_IGNORE_IF_NO_GLYPH | EFI_HII_OUT_FLAG_CLIP |

+                         EFI_HII_OUT_FLAG_CLIP_CLEAN_X | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y |

+                         EFI_HII_IGNORE_LINE_BREAK,

+                         Buffer,

+                         &FontInfo,

+                         &Blt,

+                         PointX,

+                         PointY,

+                         &RowInfoArray,

+                         &RowInfoArraySize,

+                         NULL

+                         );

+

+    if (!EFI_ERROR (Status)) {

+      ASSERT (RowInfoArray != NULL);

+      //

+      // Explicit Line break characters are ignored, so the updated parameter RowInfoArraySize by StringToImage will

+      // always be 1 or 0 (if there is no valid Unicode Char can be printed). ASSERT here to make sure.

+      //

+      ASSERT (RowInfoArraySize <= 1);

+

+      if (RowInfoArraySize != 0) {

+        Width  = RowInfoArray[0].LineWidth;

+        Height = RowInfoArray[0].LineHeight;

+        Delta  = Blt->Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);

+      } else {

+        Width  = 0;

+        Height = 0;

+        Delta  = 0;

+      }

+      Status = UgaDraw->Blt (

+                          UgaDraw,

+                          (EFI_UGA_PIXEL *) Blt->Image.Bitmap,

+                          EfiUgaBltBufferToVideo,

+                          PointX,

+                          PointY,

+                          PointX,

+                          PointY,

+                          Width,

+                          Height,

+                          Delta

+                          );

+    } else {

+      goto Error;

+    }

+    FreePool (Blt->Image.Bitmap);

+  } else {

+    goto Error;

+  }

+  //

+  // Calculate the number of actual printed characters

+  //

+  if (RowInfoArraySize != 0) {

+    PrintNum = RowInfoArray[0].EndIndex - RowInfoArray[0].StartIndex + 1;

+  } else {

+    PrintNum = 0;

+  }

+

+  FreePool (RowInfoArray);

+  FreePool (Blt);

+  return PrintNum;

+

+Error:

+  if (Blt != NULL) {

+    FreePool (Blt);

+  }

+  return 0;

+}

+

+/**

+  Prints a formatted Unicode string to a graphics console device specified by 

+  ConsoleOutputHandle defined in the EFI_SYSTEM_TABLE at the given (X,Y) coordinates.

+

+  This function prints a formatted Unicode string to the graphics console device 

+  specified by ConsoleOutputHandle in EFI_SYSTEM_TABLE and returns the number of 

+  Unicode characters displayed, not including partial characters that may be clipped 

+  by the right edge of the display.  If the length of the formatted Unicode string is

+  greater than PcdUefiLibMaxPrintBufferSize, then at most the first 

+  PcdUefiLibMaxPrintBufferSize characters are printed.The EFI_HII_FONT_PROTOCOL

+  StringToImage() service is used to convert the string to a bitmap using the glyphs 

+  registered with the HII database. No wrapping is performed, so any portions of the 

+  string the fall outside the active display region will not be displayed. Please see 

+  Section 27.2.6 of the UEFI Specification for a description of the supported string

+  format including the set of control codes supported by the StringToImage() service.

+

+  If a graphics console device is not associated with the ConsoleOutputHandle 

+  defined in the EFI_SYSTEM_TABLE then no string is printed, and 0 is returned.

+  If the EFI_HII_FONT_PROTOCOL is not present in the handle database, then no 

+  string is printed, and 0 is returned.

+  If Format is NULL, then ASSERT().

+  If Format is not aligned on a 16-bit boundary, then ASSERT().

+  If gST->ConsoleOutputHandle is NULL, then ASSERT().

+

+  @param  PointX       An X coordinate to print the string.

+  @param  PointY       A Y coordinate to print the string.

+  @param  ForeGround   The foreground color of the string being printed.  This is

+                       an optional parameter that may be NULL.  If it is NULL,

+                       then the foreground color of the current ConOut device

+                       in the EFI_SYSTEM_TABLE is used.

+  @param  BackGround   The background color of the string being printed.  This is

+                       an optional parameter that may be NULL.  If it is NULL, 

+                       then the background color of the current ConOut device

+                       in the EFI_SYSTEM_TABLE is used.

+  @param  Format       A Null-terminated Unicode format string.  See Print Library 

+                       for the supported format string syntax.

+  @param  ...          A Variable argument list whose contents are accessed based on 

+                       the format string specified by Format.         

+

+  @return  The number of Unicode characters printed.

+

+**/

+UINTN

+EFIAPI

+PrintXY (

+  IN UINTN                            PointX,

+  IN UINTN                            PointY,

+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *ForeGround, OPTIONAL

+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *BackGround, OPTIONAL

+  IN CONST CHAR16                     *Format,

+  ...

+  )

+{

+  VA_LIST                             Marker;

+  CHAR16                              *Buffer;

+  UINTN                               BufferSize;

+  UINTN                               PrintNum;

+  UINTN                               ReturnNum;

+

+  ASSERT (Format != NULL);

+  ASSERT (((UINTN) Format & BIT0) == 0);

+

+  VA_START (Marker, Format);

+

+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);

+

+  Buffer = (CHAR16 *) AllocatePool (BufferSize);

+  ASSERT (Buffer != NULL);

+

+  PrintNum = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);

+

+  VA_END (Marker);

+

+  ReturnNum = InternalPrintGraphic (PointX, PointY, ForeGround, BackGround, Buffer, PrintNum);

+

+  FreePool (Buffer);

+

+  return ReturnNum;

+}

+

+/**

+  Prints a formatted ASCII string to a graphics console device specified by 

+  ConsoleOutputHandle defined in the EFI_SYSTEM_TABLE at the given (X,Y) coordinates.

+

+  This function prints a formatted ASCII string to the graphics console device 

+  specified by ConsoleOutputHandle in EFI_SYSTEM_TABLE and returns the number of 

+  ASCII characters displayed, not including partial characters that may be clipped 

+  by the right edge of the display.  If the length of the formatted ASCII string is

+  greater than PcdUefiLibMaxPrintBufferSize, then at most the first 

+  PcdUefiLibMaxPrintBufferSize characters are printed.The EFI_HII_FONT_PROTOCOL

+  StringToImage() service is used to convert the string to a bitmap using the glyphs 

+  registered with the HII database. No wrapping is performed, so any portions of the 

+  string the fall outside the active display region will not be displayed. Please see 

+  Section 27.2.6 of the UEFI Specification for a description of the supported string

+  format including the set of control codes supported by the StringToImage() service.

+

+  If a graphics console device is not associated with the ConsoleOutputHandle 

+  defined in the EFI_SYSTEM_TABLE then no string is printed, and 0 is returned.

+  If the EFI_HII_FONT_PROTOCOL is not present in the handle database, then no 

+  string is printed, and 0 is returned.

+  If Format is NULL, then ASSERT().

+  If gST->ConsoleOutputHandle is NULL, then ASSERT().

+

+  @param  PointX       An X coordinate to print the string.

+  @param  PointY       A Y coordinate to print the string.

+  @param  ForeGround   The foreground color of the string being printed.  This is

+                       an optional parameter that may be NULL.  If it is NULL,

+                       then the foreground color of the current ConOut device

+                       in the EFI_SYSTEM_TABLE is used.

+  @param  BackGround   The background color of the string being printed.  This is

+                       an optional parameter that may be NULL.  If it is NULL, 

+                       then the background color of the current ConOut device

+                       in the EFI_SYSTEM_TABLE is used.

+  @param  Format       A Null-terminated ASCII format string.  See Print Library 

+                       for the supported format string syntax.

+  @param  ...          Variable argument list whose contents are accessed based on 

+                       the format string specified by Format.         

+

+  @return  The number of ASCII characters printed.

+

+**/

+UINTN

+EFIAPI

+AsciiPrintXY (

+  IN UINTN                            PointX,

+  IN UINTN                            PointY,

+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *ForeGround, OPTIONAL

+  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL    *BackGround, OPTIONAL

+  IN CONST CHAR8                      *Format,

+  ...

+  )

+{

+  VA_LIST                             Marker;

+  CHAR16                              *Buffer;

+  UINTN                               BufferSize;

+  UINTN                               PrintNum;

+  UINTN                               ReturnNum;

+

+  ASSERT (Format != NULL);

+

+  VA_START (Marker, Format);

+

+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);

+

+  Buffer = (CHAR16 *) AllocatePool (BufferSize);

+  ASSERT (Buffer != NULL);

+

+  PrintNum = UnicodeSPrintAsciiFormat (Buffer, BufferSize, Format, Marker);

+

+  VA_END (Marker);

+

+  ReturnNum = InternalPrintGraphic (PointX, PointY, ForeGround, BackGround, Buffer, PrintNum);

+

+  FreePool (Buffer);

+

+  return ReturnNum;

+}

+

+/** 

+  Appends a formatted Unicode string to a Null-terminated Unicode string

+ 

+  This function appends a formatted Unicode string to the Null-terminated 

+  Unicode string specified by String.   String is optional and may be NULL.

+  Storage for the formatted Unicode string returned is allocated using 

+  AllocatePool().  The pointer to the appended string is returned.  The caller

+  is responsible for freeing the returned string.

+ 

+  If String is not NULL and not aligned on a 16-bit boundary, then ASSERT().

+  If FormatString is NULL, then ASSERT().

+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  @param[in] String         A Null-terminated Unicode string.

+  @param[in] FormatString   A Null-terminated Unicode format string.

+  @param[in]  Marker        VA_LIST marker for the variable argument list.

+

+  @retval NULL    There was not enough available memory.

+  @return         Null-terminated Unicode string is that is the formatted 

+                  string appended to String.

+**/

+CHAR16*

+EFIAPI

+CatVSPrint (

+  IN  CHAR16  *String, OPTIONAL

+  IN  CONST CHAR16  *FormatString,

+  IN  VA_LIST       Marker

+  )

+{

+  UINTN   CharactersRequired;

+  UINTN   SizeRequired;

+  CHAR16  *BufferToReturn;

+  VA_LIST ExtraMarker;

+

+  VA_COPY (ExtraMarker, Marker);

+  CharactersRequired = SPrintLength(FormatString, ExtraMarker);

+  VA_END (ExtraMarker);

+

+  if (String != NULL) {

+    SizeRequired = StrSize(String) + (CharactersRequired * sizeof(CHAR16));

+  } else {

+    SizeRequired = sizeof(CHAR16) + (CharactersRequired * sizeof(CHAR16));

+  }

+

+  BufferToReturn = AllocateZeroPool(SizeRequired);

+

+  if (BufferToReturn == NULL) {

+    return NULL;

+  }

+

+  if (String != NULL) {

+    StrCpy(BufferToReturn, String);

+  }

+

+  UnicodeVSPrint(BufferToReturn + StrLen(BufferToReturn), (CharactersRequired+1) * sizeof(CHAR16), FormatString, Marker);

+

+  ASSERT(StrSize(BufferToReturn)==SizeRequired);

+

+  return (BufferToReturn);

+}

+

+/** 

+  Appends a formatted Unicode string to a Null-terminated Unicode string

+ 

+  This function appends a formatted Unicode string to the Null-terminated 

+  Unicode string specified by String.   String is optional and may be NULL.

+  Storage for the formatted Unicode string returned is allocated using 

+  AllocatePool().  The pointer to the appended string is returned.  The caller

+  is responsible for freeing the returned string.

+ 

+  If String is not NULL and not aligned on a 16-bit boundary, then ASSERT().

+  If FormatString is NULL, then ASSERT().

+  If FormatString is not aligned on a 16-bit boundary, then ASSERT().

+ 

+  @param[in] String         A Null-terminated Unicode string.

+  @param[in] FormatString   A Null-terminated Unicode format string.

+  @param[in] ...            The variable argument list whose contents are 

+                            accessed based on the format string specified by 

+                            FormatString.

+

+  @retval NULL    There was not enough available memory.

+  @return         Null-terminated Unicode string is that is the formatted 

+                  string appended to String.

+**/

+CHAR16 *

+EFIAPI

+CatSPrint (

+  IN  CHAR16  *String, OPTIONAL

+  IN  CONST CHAR16  *FormatString,

+  ...

+  )

+{

+  VA_LIST   Marker;

+  CHAR16    *NewString;

+

+  VA_START (Marker, FormatString);

+  NewString = CatVSPrint(String, FormatString, Marker);

+  VA_END (Marker);

+  return NewString;

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiNotTiano.c b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiNotTiano.c
new file mode 100644
index 0000000..9b95be6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiLib/UefiNotTiano.c
@@ -0,0 +1,357 @@
+/** @file

+  Library functions that abstract areas of conflict between framework and UEFI 2.0.

+

+  Help Port Framework code that has conflicts with UEFI 2.0 by hiding the

+  old conflicts with library functions and supporting implementations of the old

+  (EDK/EFI 1.10) and new (EDK II/UEFI 2.0) way. This module is a DXE driver as

+  it contains DXE enum extensions for EFI event services.

+

+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.

+

+**/

+

+

+

+#include "UefiLibInternal.h"

+

+/**

+  An empty function to pass error checking of CreateEventEx ().

+

+  This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error

+  checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.

+ 

+  @param  Event                 Event whose notification function is being invoked.

+  @param  Context               The pointer to the notification function's context,

+                                which is implementation-dependent.

+

+**/

+VOID

+EFIAPI

+InternalEmptyFunction (

+  IN EFI_EVENT                Event,

+  IN VOID                     *Context

+  )

+{

+  return;

+}

+

+/**

+  Creates an EFI event in the Legacy Boot Event Group.

+

+  Prior to UEFI 2.0 this was done via a non blessed UEFI extensions and this library

+  abstracts the implementation mechanism of this event from the caller. This function

+  abstracts the creation of the Legacy Boot Event. The Framework moved from a proprietary

+  to UEFI 2.0 based mechanism.  This library abstracts the caller from how this event

+  is created to prevent to code form having to change with the version of the

+  specification supported.

+  If LegacyBootEvent is NULL, then ASSERT().

+

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventLegacyBoot (

+  OUT EFI_EVENT  *LegacyBootEvent

+  )

+{

+  return EfiCreateEventLegacyBootEx (

+           TPL_CALLBACK,

+           InternalEmptyFunction,

+           NULL,

+           LegacyBootEvent

+           );

+}

+

+/**

+  Create an EFI event in the Legacy Boot Event Group and allows

+  the caller to specify a notification function.  

+  

+  This function abstracts the creation of the Legacy Boot Event.

+  The Framework moved from a proprietary to UEFI 2.0 based mechanism.

+  This library abstracts the caller from how this event is created to prevent

+  to code form having to change with the version of the specification supported.

+  If LegacyBootEvent is NULL, then ASSERT().

+

+  @param  NotifyTpl         The task priority level of the event.

+  @param  NotifyFunction    The notification function to call when the event is signaled.

+  @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.

+  @param  LegacyBootEvent   Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventLegacyBootEx (

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT EFI_EVENT         *LegacyBootEvent

+  )

+{

+  EFI_STATUS        Status;

+  EFI_EVENT_NOTIFY  WorkerNotifyFunction;

+

+  ASSERT (LegacyBootEvent != NULL);

+

+  if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {

+    DEBUG ((EFI_D_ERROR, "EFI1.1 can't support LegacyBootEvent!"));

+    ASSERT (FALSE);

+

+    return EFI_UNSUPPORTED;

+  } else {

+    //

+    // For UEFI 2.0 and the future use an Event Group

+    //

+    if (NotifyFunction == NULL) {

+      //

+      // CreateEventEx will check NotifyFunction is NULL or not and return error.

+      // Use dummy routine for the case NotifyFunction is NULL.

+      //

+      WorkerNotifyFunction = InternalEmptyFunction;

+    } else {

+      WorkerNotifyFunction = NotifyFunction;

+    }

+    Status = gBS->CreateEventEx (

+                    EVT_NOTIFY_SIGNAL,

+                    NotifyTpl,

+                    WorkerNotifyFunction,

+                    NotifyContext,

+                    &gEfiEventLegacyBootGuid,

+                    LegacyBootEvent

+                    );

+  }

+

+  return Status;

+}

+

+/**

+  Create an EFI event in the Ready To Boot Event Group.

+

+  Prior to UEFI 2.0 this was done via a non-standard UEFI extension, and this library

+  abstracts the implementation mechanism of this event from the caller.   

+  This function abstracts the creation of the Ready to Boot Event.  The Framework 

+  moved from a proprietary to UEFI 2.0-based mechanism.  This library abstracts 

+  the caller from how this event is created to prevent the code form having to 

+  change with the version of the specification supported.

+  If ReadyToBootEvent is NULL, then ASSERT().

+

+  @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventReadyToBoot (

+  OUT EFI_EVENT  *ReadyToBootEvent

+  )

+{

+  return EfiCreateEventReadyToBootEx (

+           TPL_CALLBACK,

+           InternalEmptyFunction,

+           NULL,

+           ReadyToBootEvent

+           );

+}

+

+/**

+  Create an EFI event in the Ready To Boot Event Group and allows

+  the caller to specify a notification function.  

+  

+  This function abstracts the creation of the Ready to Boot Event.

+  The Framework moved from a proprietary to UEFI 2.0 based mechanism.

+  This library abstracts the caller from how this event is created to prevent

+  to code form having to change with the version of the specification supported.

+  If ReadyToBootEvent is NULL, then ASSERT().

+

+  @param  NotifyTpl         The task priority level of the event.

+  @param  NotifyFunction    The notification function to call when the event is signaled.

+  @param  NotifyContext     The content to pass to NotifyFunction when the event is signaled.

+  @param  ReadyToBootEvent  Returns the EFI event returned from gBS->CreateEvent(Ex).

+

+  @retval EFI_SUCCESS       Event was created.

+  @retval Other             Event was not created.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiCreateEventReadyToBootEx (

+  IN  EFI_TPL           NotifyTpl,

+  IN  EFI_EVENT_NOTIFY  NotifyFunction,  OPTIONAL

+  IN  VOID              *NotifyContext,  OPTIONAL

+  OUT EFI_EVENT         *ReadyToBootEvent

+  )

+{

+  EFI_STATUS        Status;

+  EFI_EVENT_NOTIFY  WorkerNotifyFunction;

+

+  ASSERT (ReadyToBootEvent != NULL);

+

+  if (gST->Hdr.Revision < EFI_2_00_SYSTEM_TABLE_REVISION) {

+    DEBUG ((EFI_D_ERROR, "EFI1.1 can't support ReadyToBootEvent!"));

+    ASSERT (FALSE);

+

+    return EFI_UNSUPPORTED;

+  } else {

+    //

+    // For UEFI 2.0 and the future use an Event Group

+    //

+    if (NotifyFunction == NULL) {

+      //

+      // CreateEventEx will check NotifyFunction is NULL or not and return error.

+      // Use dummy routine for the case NotifyFunction is NULL.

+      //

+      WorkerNotifyFunction = InternalEmptyFunction;

+    } else {

+      WorkerNotifyFunction = NotifyFunction;

+    }

+    Status = gBS->CreateEventEx (

+                    EVT_NOTIFY_SIGNAL,

+                    NotifyTpl,

+                    WorkerNotifyFunction,

+                    NotifyContext,

+                    &gEfiEventReadyToBootGuid,

+                    ReadyToBootEvent

+                    );

+  }

+

+  return Status;

+}

+

+

+/**

+  Create, Signal, and Close the Ready to Boot event using EfiSignalEventReadyToBoot().

+  

+  This function abstracts the signaling of the Ready to Boot Event. The Framework moved

+  from a proprietary to UEFI 2.0 based mechanism. This library abstracts the caller

+  from how this event is created to prevent to code form having to change with the

+  version of the specification supported.

+

+**/

+VOID

+EFIAPI

+EfiSignalEventReadyToBoot (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+  EFI_EVENT     ReadyToBootEvent;

+

+  Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent);

+  if (!EFI_ERROR (Status)) {

+    gBS->SignalEvent (ReadyToBootEvent);

+    gBS->CloseEvent (ReadyToBootEvent);

+  }

+}

+

+/**

+  Create, Signal, and Close the Ready to Boot event using EfiSignalEventLegacyBoot().

+

+  This function abstracts the signaling of the Legacy Boot Event. The Framework moved from

+  a proprietary to UEFI 2.0 based mechanism.  This library abstracts the caller from how

+  this event is created to prevent to code form having to change with the version of the

+  specification supported.

+

+**/

+VOID

+EFIAPI

+EfiSignalEventLegacyBoot (

+  VOID

+  )

+{

+  EFI_STATUS    Status;

+  EFI_EVENT     LegacyBootEvent;

+

+  Status = EfiCreateEventLegacyBoot (&LegacyBootEvent);

+  if (!EFI_ERROR (Status)) {

+    gBS->SignalEvent (LegacyBootEvent);

+    gBS->CloseEvent (LegacyBootEvent);

+  }

+}

+

+

+/**

+  Check to see if the Firmware Volume (FV) Media Device Path is valid 

+  

+  The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.  

+  This library function abstracts validating a device path node.

+  Check the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure to see if it's valid.  

+  If it is valid, then return the GUID file name from the device path node.  Otherwise, 

+  return NULL.  This device path changed in the DXE CIS version 0.92 in a non back ward 

+  compatible way to not conflict with the UEFI 2.0 specification.  This function abstracts 

+  the differences from the caller.

+  If FvDevicePathNode is NULL, then ASSERT().

+

+  @param  FvDevicePathNode  The pointer to FV device path to check.

+

+  @retval NULL              FvDevicePathNode is not valid.

+  @retval Other             FvDevicePathNode is valid and pointer to NameGuid was returned.

+

+**/

+EFI_GUID *

+EFIAPI

+EfiGetNameGuidFromFwVolDevicePathNode (

+  IN CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode

+  )

+{

+  ASSERT (FvDevicePathNode != NULL);

+

+  if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&

+      DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_PIWG_FW_FILE_DP) {

+    return (EFI_GUID *) &FvDevicePathNode->FvFileName;

+  }

+

+  return NULL;

+}

+

+

+/**

+  Initialize a Firmware Volume (FV) Media Device Path node.

+  

+  The Framework FwVol Device Path changed to conform to the UEFI 2.0 specification.  

+  This library function abstracts initializing a device path node.  

+  Initialize the MEDIA_FW_VOL_FILEPATH_DEVICE_PATH data structure.  This device 

+  path changed in the DXE CIS version 0.92 in a non back ward compatible way to 

+  not conflict with the UEFI 2.0 specification.  This function abstracts the 

+  differences from the caller.

+  If FvDevicePathNode is NULL, then ASSERT().

+  If NameGuid is NULL, then ASSERT().

+  

+  @param  FvDevicePathNode  The pointer to a FV device path node to initialize

+  @param  NameGuid          FV file name to use in FvDevicePathNode

+

+**/

+VOID

+EFIAPI

+EfiInitializeFwVolDevicepathNode (

+  IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvDevicePathNode,

+  IN CONST EFI_GUID                         *NameGuid

+  )

+{

+  ASSERT (FvDevicePathNode != NULL);

+  ASSERT (NameGuid          != NULL);

+

+  //

+  // Use the new Device path that does not conflict with the UEFI

+  //

+  FvDevicePathNode->Header.Type     = MEDIA_DEVICE_PATH;

+  FvDevicePathNode->Header.SubType  = MEDIA_PIWG_FW_FILE_DP;

+  SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));

+

+  CopyGuid (&FvDevicePathNode->FvFileName, NameGuid);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c
new file mode 100644
index 0000000..f1eaccc
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c
@@ -0,0 +1,821 @@
+/** @file

+  Support routines for memory allocation routines based 

+  on boot services for Dxe phase drivers.

+

+  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.             

+

+**/

+

+

+#include <Uefi.h>

+

+

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Allocates one or more 4KB pages of a certain memory type.

+

+  Allocates the number of 4KB pages of a certain memory type 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  MemoryType            The type of memory to allocate.

+  @param  Pages                 The number of 4 KB pages to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocatePages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory; 

+

+  if (Pages == 0) {

+    return NULL;

+  }

+

+  Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+  if (EFI_ERROR (Status)) {

+    return NULL;

+  }

+  return (VOID *) (UINTN) Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocatePages (EfiBootServicesData, 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

+  )

+{

+  return InternalAllocatePages (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocatePages (EfiReservedMemoryType, 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                The 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

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (Pages != 0);

+  Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates one or more 4KB pages of a certain memory type at a specified alignment.

+

+  Allocates the number of 4KB pages specified by Pages of a certain memory type 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  MemoryType            The type of memory to allocate.

+  @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 *

+InternalAllocateAlignedPages (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            Pages,

+  IN UINTN            Alignment

+  )

+{

+  EFI_STATUS            Status;

+  EFI_PHYSICAL_ADDRESS  Memory;

+  UINTN                 AlignedMemory;

+  UINTN                 AlignmentMask;

+  UINTN                 UnalignedPages;

+  UINTN                 RealPages;

+

+  //

+  // Alignment must be a power of two or zero.

+  //

+  ASSERT ((Alignment & (Alignment - 1)) == 0);

+ 

+  if (Pages == 0) {

+    return NULL;

+  }

+  if (Alignment > EFI_PAGE_SIZE) {

+    //

+    // Caculate the total number of pages since alignment is larger than page size.

+    //

+    AlignmentMask  = Alignment - 1;

+    RealPages      = Pages + EFI_SIZE_TO_PAGES (Alignment);

+    //

+    // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.

+    //

+    ASSERT (RealPages > Pages);

+ 

+    Status         = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;

+    UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);

+    if (UnalignedPages > 0) {

+      //

+      // Free first unaligned page(s).

+      //

+      Status = gBS->FreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+    Memory         = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));

+    UnalignedPages = RealPages - Pages - UnalignedPages;

+    if (UnalignedPages > 0) {

+      //

+      // Free last unaligned page(s).

+      //

+      Status = gBS->FreePages (Memory, UnalignedPages);

+      ASSERT_EFI_ERROR (Status);

+    }

+  } else {

+    //

+    // Do not over-allocate pages in this case.

+    //

+    Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);

+    if (EFI_ERROR (Status)) {

+      return NULL;

+    }

+    AlignedMemory  = (UINTN) Memory;

+  }

+  return (VOID *) AlignedMemory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateAlignedPages (EfiBootServicesData, Pages, 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

+  )

+{

+  return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, 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

+  )

+{

+  return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, 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                The 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

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (Pages != 0);

+  Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);

+  ASSERT_EFI_ERROR (Status);

+}

+

+/**

+  Allocates a buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type 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  MemoryType            The type of memory to allocate.

+  @param  AllocationSize        The number of bytes to allocate.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocatePool (

+  IN EFI_MEMORY_TYPE  MemoryType,  

+  IN UINTN            AllocationSize

+  )

+{

+  EFI_STATUS  Status;

+  VOID        *Memory;

+

+  Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);

+  if (EFI_ERROR (Status)) {

+    Memory = NULL;

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocatePool (EfiBootServicesData, 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

+  )

+{

+  return InternalAllocatePool (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Allocates and zeros a buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type, 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  PoolType              The type of memory to allocate.

+  @param  AllocationSize        The number of bytes to allocate and zero.

+

+  @return A pointer to the allocated buffer or NULL if allocation fails.

+

+**/

+VOID *

+InternalAllocateZeroPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize

+  ) 

+{

+  VOID  *Memory;

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+    Memory = ZeroMem (Memory, AllocationSize);

+  }

+  return Memory;

+}

+

+/**

+  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

+  )

+{

+  return InternalAllocateZeroPool (EfiBootServicesData, 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

+  )

+{

+  return InternalAllocateZeroPool (EfiRuntimeServicesData, 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

+  )

+{

+  return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);

+}

+

+/**

+  Copies a buffer to an allocated buffer of a certain pool type.

+

+  Allocates the number bytes specified by AllocationSize of a certain pool type, 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  PoolType              The type of pool to allocate.

+  @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 *

+InternalAllocateCopyPool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            AllocationSize,

+  IN CONST VOID       *Buffer

+  ) 

+{

+  VOID  *Memory;

+

+  ASSERT (Buffer != NULL);

+  ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));

+

+  Memory = InternalAllocatePool (PoolType, AllocationSize);

+  if (Memory != NULL) {

+     Memory = CopyMem (Memory, Buffer, AllocationSize);

+  }

+  return Memory;

+} 

+

+/**

+  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

+  )

+{

+  return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, 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

+  )

+{

+  return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, 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

+  )

+{

+  return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);

+}

+

+/**

+  Reallocates a buffer of a specified memory type.

+

+  Allocates and zeros the number bytes specified by NewSize from memory of the type

+  specified by PoolType.  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  PoolType       The type of pool to allocate.

+  @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 *

+InternalReallocatePool (

+  IN EFI_MEMORY_TYPE  PoolType,  

+  IN UINTN            OldSize,

+  IN UINTN            NewSize,

+  IN VOID             *OldBuffer  OPTIONAL

+  )

+{

+  VOID  *NewBuffer;

+

+  NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);

+  if (NewBuffer != NULL && OldBuffer != NULL) {

+    CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));

+    FreePool (OldBuffer);

+  }

+  return NewBuffer;

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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

+  )

+{

+  return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);

+}

+

+/**

+  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                The pointer to the buffer to free.

+

+**/

+VOID

+EFIAPI

+FreePool (

+  IN VOID   *Buffer

+  )

+{

+  EFI_STATUS    Status;

+

+  Status = gBS->FreePool (Buffer);

+  ASSERT_EFI_ERROR (Status);

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
new file mode 100644
index 0000000..e5936ed
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -0,0 +1,42 @@
+## @file

+# Instance of Memory Allocation Library using EFI Boot Services.

+#

+# Memory Allocation Library that uses EFI Boot Services to allocate

+#  and free memory.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiMemoryAllocationLib

+  MODULE_UNI_FILE                = UefiMemoryAllocationLib.uni

+  FILE_GUID                      = 4674739d-3195-4fb2-8094-ac1d22d00194

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = MemoryAllocationLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  MemoryAllocationLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseMemoryLib

+  UefiBootServicesTableLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.uni
new file mode 100644
index 0000000..3e5bdd8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/CompareMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/CompareMemWrapper.c
new file mode 100644
index 0000000..3e74647
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/CompareMemWrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  CompareMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0 || DestinationBuffer == SourceBuffer) {

+    return 0;

+  }

+  ASSERT (DestinationBuffer != NULL);

+  ASSERT (SourceBuffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  return InternalMemCompareMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/CopyMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/CopyMemWrapper.c
new file mode 100644
index 0000000..21ea2d4
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/CopyMemWrapper.c
@@ -0,0 +1,63 @@
+/** @file

+  CopyMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return DestinationBuffer;

+  }

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)DestinationBuffer));

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)SourceBuffer));

+

+  if (DestinationBuffer == SourceBuffer) {

+    return DestinationBuffer;

+  }

+  return InternalMemCopyMem (DestinationBuffer, SourceBuffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLib.c
new file mode 100644
index 0000000..d37c8c8
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLib.c
@@ -0,0 +1,63 @@
+/** @file

+  Base Memory Library functions implementation bases on Uefi Boot Service.

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Copies a source buffer to a destination buffer, and returns the destination buffer.

+

+  This function wraps the gBS->CopyMem().

+

+  @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

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  )

+{

+  gBS->CopyMem (Destination, (VOID*)Source, Length);

+  return Destination;

+}

+

+/**

+  Fills a target buffer with a byte value, and returns the target buffer.

+

+  This function wraps the gBS->SetMem().

+

+  @param  Buffer    Memory to set.

+  @param  Size      The number of bytes to set.

+  @param  Value     Value of the set operation.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  )

+{

+  gBS->SetMem (Buffer, Size, Value);

+  return Buffer;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibGeneric.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibGeneric.c
new file mode 100644
index 0000000..1ec8bf6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibGeneric.c
@@ -0,0 +1,260 @@
+/** @file

+  Architecture Independent Base Memory Library Implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    PeiMemoryLib

+    UefiMemoryLib

+

+  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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  do {

+    ((UINT16*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  do {

+    ((UINT32*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  do {

+    ((UINT64*)Buffer)[--Length] = Value;

+  } while (Length != 0);

+  return Buffer;

+}

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer Memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  )

+{

+  return InternalMemSetMem (Buffer, Length, 0);

+}

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer

+  @param  SourceBuffer      The second memory buffer

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  IN      CONST VOID                *DestinationBuffer,

+  IN      CONST VOID                *SourceBuffer,

+  IN      UINTN                     Length

+  )

+{

+  while ((--Length != 0) &&

+         (*(INT8*)DestinationBuffer == *(INT8*)SourceBuffer)) {

+    DestinationBuffer = (INT8*)DestinationBuffer + 1;

+    SourceBuffer = (INT8*)SourceBuffer + 1;

+  }

+  return (INTN)*(UINT8*)DestinationBuffer - (INTN)*(UINT8*)SourceBuffer;

+}

+

+/**

+  Scans a target buffer for an 8-bit value, and returns a pointer to the

+  matching 8-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT8                     Value

+  )

+{

+  CONST UINT8                       *Pointer;

+

+  Pointer = (CONST UINT8*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 16-bit value, and returns a pointer to the

+  matching 16-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  )

+{

+  CONST UINT16                      *Pointer;

+

+  Pointer = (CONST UINT16*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 32-bit value, and returns a pointer to the

+  matching 32-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  )

+{

+  CONST UINT32                      *Pointer;

+

+  Pointer = (CONST UINT32*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

+

+/**

+  Scans a target buffer for a 64-bit value, and returns a pointer to the

+  matching 64-bit value in the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  )

+{

+  CONST UINT64                      *Pointer;

+

+  Pointer = (CONST UINT64*)Buffer;

+  do {

+    if (*(Pointer++) == Value) {

+      return --Pointer;

+    }

+  } while (--Length != 0);

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibGuid.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibGuid.c
new file mode 100644
index 0000000..6f6edd0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibGuid.c
@@ -0,0 +1,142 @@
+/** @file

+  Implementation of GUID functions.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+  

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid)

+    );

+  WriteUnaligned64 (

+    (UINT64*)DestinationGuid + 1,

+    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)

+    );

+  return DestinationGuid;

+}

+

+/**

+  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

+  )

+{

+  UINT64  LowPartOfGuid1;

+  UINT64  LowPartOfGuid2;

+  UINT64  HighPartOfGuid1;

+  UINT64  HighPartOfGuid2;

+

+  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);

+  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);

+  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);

+  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

+

+  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);

+}

+

+/**

+  Scans a target buffer for a GUID, and returns a pointer to the matching GUID

+  in the target buffer.

+

+  This function searches the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanGuid (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN CONST GUID  *Guid

+  )

+{

+  CONST GUID                        *GuidPtr;

+

+  ASSERT (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0);

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  ASSERT ((Length & (sizeof (*GuidPtr) - 1)) == 0);

+

+  GuidPtr = (GUID*)Buffer;

+  Buffer  = GuidPtr + Length / sizeof (*GuidPtr);

+  while (GuidPtr < (CONST GUID*)Buffer) {

+    if (CompareGuid (GuidPtr, Guid)) {

+      return (VOID*)GuidPtr;

+    }

+    GuidPtr++;

+  }

+  return NULL;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibInternals.h b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibInternals.h
new file mode 100644
index 0000000..0443b50
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/MemLibInternals.h
@@ -0,0 +1,232 @@
+/** @file

+  Declaration of internal functions for Base Memory Library.

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#ifndef __MEM_LIB_INTERNALS__

+#define __MEM_LIB_INTERNALS__

+

+#include <Uefi.h>

+

+#include <Library/BaseMemoryLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+

+/**

+  Copies a source buffer to a destination buffer, and returns the destination buffer.

+

+  This function wraps the gBS->CopyMem().

+

+  @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

+InternalMemCopyMem (

+  OUT     VOID                      *Destination,

+  IN      CONST VOID                *Source,

+  IN      UINTN                     Length

+  );

+

+/**

+  Fills a target buffer with a byte value, and returns the target buffer.

+

+  This function wraps the gBS->SetMem().

+

+  @param  Buffer    Memory to set.

+  @param  Size      The number of bytes to set.

+  @param  Value     Value of the set operation.

+

+  @return Buffer.

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Size,

+  IN      UINT8                     Value

+  );

+

+/**

+  Fills a target buffer with a 16-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 16-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem16 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT16                    Value

+  );

+

+/**

+  Fills a target buffer with a 32-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 32-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem32 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT32                    Value

+  );

+

+/**

+  Fills a target buffer with a 64-bit value, and returns the target buffer.

+

+  @param  Buffer  The pointer to the target buffer to fill.

+  @param  Length  The count of 64-bit value to fill.

+  @param  Value   The value with which to fill Length bytes of Buffer.

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemSetMem64 (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+/**

+  Set Buffer to 0 for Size bytes.

+

+  @param  Buffer The memory to set.

+  @param  Length The number of bytes to set

+

+  @return Buffer

+

+**/

+VOID *

+EFIAPI

+InternalMemZeroMem (

+  OUT     VOID                      *Buffer,

+  IN      UINTN                     Length

+  );

+

+/**

+  Compares two memory buffers of a given length.

+

+  @param  DestinationBuffer The first memory buffer

+  @param  SourceBuffer      The second memory buffer

+  @param  Length            The length of DestinationBuffer and SourceBuffer memory

+                            regions to compare. Must be non-zero.

+

+  @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

+InternalMemCompareMem (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 8-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem8 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 16-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem16 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 32-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem32 (

+  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.

+

+  @param  Buffer  The pointer to the target buffer to scan.

+  @param  Length  The count of 64-bit value to scan. Must be non-zero.

+  @param  Value   The value to search for in the target buffer.

+

+  @return The pointer to the first occurrence or NULL if not found.

+

+**/

+CONST VOID *

+EFIAPI

+InternalMemScanMem64 (

+  IN      CONST VOID                *Buffer,

+  IN      UINTN                     Length,

+  IN      UINT64                    Value

+  );

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem16Wrapper.c
new file mode 100644
index 0000000..69a2ce9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem16Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem16 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT16      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem32Wrapper.c
new file mode 100644
index 0000000..31f1d55
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem32Wrapper.c
@@ -0,0 +1,66 @@
+/** @file

+  ScanMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem32 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT32      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem64Wrapper.c
new file mode 100644
index 0000000..3819456
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem64Wrapper.c
@@ -0,0 +1,67 @@
+/** @file

+  ScanMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem64 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT64      Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT (((UINTN)Buffer & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return (VOID*)InternalMemScanMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem8Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem8Wrapper.c
new file mode 100644
index 0000000..7fee8ae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ScanMem8Wrapper.c
@@ -0,0 +1,99 @@
+/** @file

+  ScanMem8() and ScanMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMem8 (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINT8       Value

+  )

+{

+  if (Length == 0) {

+    return NULL;

+  }

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+ 

+  return (VOID*)InternalMemScanMem8 (Buffer, Length, 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 the target 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 or NULL otherwise.

+

+**/

+VOID *

+EFIAPI

+ScanMemN (

+  IN CONST VOID  *Buffer,

+  IN UINTN       Length,

+  IN UINTN       Value

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return ScanMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return ScanMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem16Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem16Wrapper.c
new file mode 100644
index 0000000..b15a4ea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem16Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem16() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem16 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem32Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem32Wrapper.c
new file mode 100644
index 0000000..ea6a5a9
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem32Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem32() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem32 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem64Wrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem64Wrapper.c
new file mode 100644
index 0000000..7349565
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMem64Wrapper.c
@@ -0,0 +1,64 @@
+/** @file

+  SetMem64() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT (Buffer != NULL);

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+  ASSERT ((((UINTN)Buffer) & (sizeof (Value) - 1)) == 0);

+  ASSERT ((Length & (sizeof (Value) - 1)) == 0);

+

+  return InternalMemSetMem64 (Buffer, Length / sizeof (Value), Value);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
new file mode 100644
index 0000000..6efa407
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
@@ -0,0 +1,91 @@
+/** @file

+  SetMem() and SetMemN() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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    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

+  )

+{

+  if (Length == 0) {

+    return Buffer;

+  }

+

+  ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));

+

+  return InternalMemSetMem (Buffer, Length, 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

+  )

+{

+  if (sizeof (UINTN) == sizeof (UINT64)) {

+    return SetMem64 (Buffer, Length, (UINT64)Value);

+  } else {

+    return SetMem32 (Buffer, Length, (UINT32)Value);

+  }

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf
new file mode 100644
index 0000000..e82732f
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf
@@ -0,0 +1,59 @@
+## @file

+# Instance of Base Memory Library using EFI Boot Services.

+#

+# Base Memory Library implementation that uses EFI Boot Services

+#  where possible for size reduction.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiMemoryLib

+  MODULE_UNI_FILE                = UefiMemoryLib.uni

+  FILE_GUID                      = f1bbe03d-2f28-4dee-bec7-d98d7a30c36a

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = BaseMemoryLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  ScanMem64Wrapper.c

+  ScanMem32Wrapper.c

+  ScanMem16Wrapper.c

+  ScanMem8Wrapper.c

+  ZeroMemWrapper.c

+  CompareMemWrapper.c

+  SetMem64Wrapper.c

+  SetMem32Wrapper.c

+  SetMem16Wrapper.c

+  SetMemWrapper.c

+  CopyMemWrapper.c

+  MemLibGeneric.c

+  MemLibGuid.c

+  MemLib.c

+  MemLibInternals.h

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  UefiBootServicesTableLib

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.uni
new file mode 100644
index 0000000..b0cbeea
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ZeroMemWrapper.c b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ZeroMemWrapper.c
new file mode 100644
index 0000000..5adddbb
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiMemoryLib/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file

+  ZeroMem() implementation.

+

+  The following BaseMemoryLib instances contain the same copy of this file:

+

+    BaseMemoryLib

+    BaseMemoryLibMmx

+    BaseMemoryLibSse2

+    BaseMemoryLibRepStr

+    BaseMemoryLibOptDxe

+    BaseMemoryLibOptPei

+    PeiMemoryLib

+    UefiMemoryLib

+    

+  Copyright (c) 2006 - 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.

+

+**/

+

+#include "MemLibInternals.h"

+

+/**

+  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

+  )

+{

+  ASSERT (!(Buffer == NULL && Length > 0));

+  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));

+  return InternalMemZeroMem (Buffer, Length);

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.c
new file mode 100644
index 0000000..df52a91
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.c
@@ -0,0 +1,127 @@
+/** @file

+  PAL Library implementation retrieving the PAL Entry Point from the SAL System Table

+  register in the EFI System Confguration Table.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <IndustryStandard/Sal.h>

+#include <Library/UefiLib.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+

+#include <Guid/SalSystemTable.h>

+

+UINT64               mPalProcEntry;

+

+/**

+  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. 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 4 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.

+  This function is only available on IPF.

+

+  @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

+PalCall (

+  IN UINT64                  Index,

+  IN UINT64                  Arg2,

+  IN UINT64                  Arg3,

+  IN UINT64                  Arg4

+  )

+{

+  //

+  // mPalProcEntry is initialized in library constructor as PAL entry.

+  //

+  return AsmPalCall (

+           mPalProcEntry,

+           Index,

+           Arg2,

+           Arg3,

+           Arg4

+           );

+

+}

+

+/**

+  The constructor function of UEFI Pal Lib.

+

+  The constructor function looks up the SAL System Table in the EFI System Configuration

+  Table. Once the SAL System Table is found, the PAL Entry Point in the SAL System Table

+  will be derived and stored into a global variable for library usage.

+  It will ASSERT() if the SAL System Table cannot be found or the data in the SAL System

+  Table is not the valid data.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiPalLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                     Status;

+  SAL_ST_ENTRY_POINT_DESCRIPTOR  *SalStEntryDes;

+  SAL_SYSTEM_TABLE_HEADER        *SalSystemTable;

+

+  Status = EfiGetSystemConfigurationTable (

+             &gEfiSalSystemTableGuid,

+             (VOID **) &SalSystemTable

+             );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (SalSystemTable != NULL);

+

+  //

+  // Check the first entry of SAL System Table,

+  // because the SAL entry is in ascending order with the entry type,

+  // the type 0 entry should be the first if exist.

+  //

+  SalStEntryDes = (SAL_ST_ENTRY_POINT_DESCRIPTOR *)(SalSystemTable + 1);

+

+  //

+  // Assure the SAL ENTRY Type is 0

+  //

+  ASSERT (SalStEntryDes->Type == EFI_SAL_ST_ENTRY_POINT);

+

+  mPalProcEntry = SalStEntryDes->PalProcEntry;

+  //

+  // Make sure the PalCallAddress has the valid value

+  //

+  ASSERT (mPalProcEntry != 0);

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.inf
new file mode 100644
index 0000000..914c751
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.inf
@@ -0,0 +1,49 @@
+## @file

+# UEFI Instance of PAL Library Class.

+#

+# This instance of PAL library retrieves the PAL Entry Point from the SAL System Table

+# register in the EFI System Confguration Table.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiPalLib

+  MODULE_UNI_FILE                = UefiPalLib.uni

+  FILE_GUID                      = B7F30170-9E5F-482a-B553-A145A5787003

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PalLib|UEFI_DRIVER UEFI_APPLICATION

+

+  CONSTRUCTOR                    = UefiPalLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  UefiPalLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiLib

+  BaseLib

+  DebugLib

+

+[Guids]

+  gEfiSalSystemTableGuid        ## CONSUMES ## SystemTable

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.uni
new file mode 100644
index 0000000..c18b979
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPalLib/UefiPalLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c
new file mode 100644
index 0000000..148e12c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/PciLib.c
@@ -0,0 +1,1436 @@
+/** @file

+  PCI Library using PCI Root Bridge I/O Protocol.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiDxe.h>

+

+#include <Protocol/PciRootBridgeIo.h>

+

+#include <Library/PciLib.h>

+#include <Library/BaseLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+

+/**

+  Assert the validity of a PCI address. A valid PCI address should contain 1's

+  only in the low 28 bits.

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_ADDRESS(A,M) \

+  ASSERT (((A) & (~0xfffffff | (M))) == 0)

+

+/**

+  Translate PCI Lib address into format of PCI Root Bridge I/O Protocol.

+

+  @param  A  The address that encodes the PCI Bus, Device, Function and

+             Register.

+

+**/

+#define PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS(A) \

+  ((((A) << 4) & 0xff000000) | (((A) >> 4) & 0x00000700) | (((A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))

+

+//

+// Global varible to cache pointer to PCI Root Bridge I/O protocol.

+//

+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL      *mPciRootBridgeIo = NULL; 

+

+/**

+  The constructor function caches the pointer to PCI Root Bridge I/O protocol.

+  

+  The constructor function locates PCI Root Bridge I/O protocol from protocol database.

+  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PciLibConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+  

+  Status = gBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid, NULL, (VOID**) &mPciRootBridgeIo);

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (mPciRootBridgeIo != NULL);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+DxePciLibPciRootBridgeIoReadWorker (

+  IN    UINTN                                  Address,

+  IN    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width

+  )

+{

+  UINT32  Data;

+

+  mPciRootBridgeIo->Pci.Read (

+                          mPciRootBridgeIo,

+                          Width,

+                          PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),

+                          1,

+                          &Data

+                          );

+

+  return Data;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   The width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+DxePciLibPciRootBridgeIoWriteWorker (

+  IN    UINTN                                  Address,

+  IN    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN    UINT32                                 Data

+  )

+{

+  mPciRootBridgeIo->Pci.Write (

+                          mPciRootBridgeIo,

+                          Width,

+                          PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),

+                          1,

+                          &Data

+                          );

+  return Data;

+}

+

+/**

+  Registers a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  Registers the PCI device specified by Address so all the PCI configuration registers 

+  associated with that PCI device may be accessed after SetVirtualAddressMap() is called.

+  

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciRead8 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciWrite8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with

+  an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8) (PciRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAnd8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (Address, (UINT8) (PciRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit

+  value, followed a  bitwise OR with another 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (Address, (UINT8) ((PciRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldRead8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldWrite8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     Value

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldWrite8 (PciRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldOr8 (PciRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAnd8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAnd8 (PciRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciBitFieldAndThenOr8 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT8                     AndData,

+  IN      UINT8                     OrData

+  )

+{

+  return PciWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciRead16 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciWrite16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16) (PciRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAnd16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (Address, (UINT16) (PciRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit

+  value, followed a  bitwise OR with another 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (Address, (UINT16) ((PciRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldRead16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldWrite16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    Value

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldWrite16 (PciRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldOr16 (PciRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 16-bit register.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 16-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAnd16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAnd16 (PciRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciBitFieldAndThenOr16 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT16                    AndData,

+  IN      UINT16                    OrData

+  )

+{

+  return PciWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+

+  @return The read value from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciRead32 (

+  IN      UINTN                     Address

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return DxePciLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the

+  value specified by Value. Value is returned. This function must guarantee

+  that all PCI read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Value   The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciWrite32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_ADDRESS (Address, 3);

+

+  return DxePciLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with

+  a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAnd32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (Address, PciRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit

+  value, followed a  bitwise OR with another 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  AndData The value to AND with the PCI configuration register.

+  @param  OrData  The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (Address, (PciRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldRead32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldWrite32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    Value

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldWrite32 (PciRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldOr32 (PciRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 32-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAnd32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAnd32 (PciRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If Address > 0x0FFFFFFF, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciBitFieldAndThenOr32 (

+  IN      UINTN                     Address,

+  IN      UINTN                     StartBit,

+  IN      UINTN                     EndBit,

+  IN      UINT32                    AndData,

+  IN      UINT32                    OrData

+  )

+{

+  return PciWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciReadBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  OUT     VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 (Buffer, PciRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 (Buffer, PciRead32 (StartAddress));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 (Buffer, PciRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If StartAddress > 0x0FFFFFFF, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return Size written to StartAddress.

+

+**/

+UINTN

+EFIAPI

+PciWriteBuffer (

+  IN      UINTN                     StartAddress,

+  IN      UINTN                     Size,

+  IN      VOID                      *Buffer

+  )

+{

+  UINTN                             ReturnValue;

+

+  ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciWrite32 (StartAddress, ReadUnaligned32 (Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/UefiPciLibPciRootBridgeIo.inf b/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/UefiPciLibPciRootBridgeIo.inf
new file mode 100644
index 0000000..b741d1b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/UefiPciLibPciRootBridgeIo.inf
@@ -0,0 +1,57 @@
+## @file

+# PCI Library that layers on top of the PCI Root Bridge I/O Protocol.

+#

+# This library produces the APIs from the PCI Library and implements these APIs

+#  by calling into the PCI Root Bridge I/O Protocol. The PCI Root Bridge I/O Protocol is

+#  typically produced by a chipset specific DXE driver.

+#  This library binds to the first PCI Root Bridge I/O Protocol in the platform. As a result,

+#  it should only be used on platforms that contain a single PCI root bridge.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiPciLibPciRootBridgeIo

+  MODULE_UNI_FILE                = UefiPciLibPciRootBridgeIo.uni

+  FILE_GUID                      = 90EC42CB-B780-4eb8-8E99-C8E3E5F37530

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION

+

+  CONSTRUCTOR                    = PciLibConstructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseLib

+  UefiBootServicesTableLib

+  DebugLib

+

+[Protocols]

+  gEfiPciRootBridgeIoProtocolGuid               ## CONSUMES

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiPciRootBridgeIoProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/UefiPciLibPciRootBridgeIo.uni b/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/UefiPciLibPciRootBridgeIo.uni
new file mode 100644
index 0000000..32df17c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciLibPciRootBridgeIo/UefiPciLibPciRootBridgeIo.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
new file mode 100644
index 0000000..5b286b0
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
@@ -0,0 +1,1487 @@
+/** @file

+  PCI Segment Library implementation using PCI Root Bridge I/O Protocol.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include "PciSegmentLib.h"

+

+//

+// Global variable to record data of PCI Root Bridge I/O Protocol instances

+//

+PCI_ROOT_BRIDGE_DATA   *mPciRootBridgeData     = NULL;

+UINTN                  mNumberOfPciRootBridges = 0;

+

+/**

+  The constructor function caches data of PCI Root Bridge I/O Protocol instances.

+  

+  The constructor function locates PCI Root Bridge I/O protocol instances,

+  and caches the protocol instances, together with their segment numbers and bus ranges.

+  It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PciSegmentLibConstructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  EFI_STATUS                           Status;

+  UINTN                                Index;

+  UINTN                                HandleCount;

+  EFI_HANDLE                           *HandleBuffer;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL      *PciRootBridgeIo; 

+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR    *Descriptors;

+

+  HandleCount     = 0;

+  HandleBuffer    = NULL;

+  PciRootBridgeIo = NULL;

+  Descriptors     = NULL;

+

+  Status = gBS->LocateHandleBuffer (

+                  ByProtocol,

+                  &gEfiPciRootBridgeIoProtocolGuid,

+                  NULL,

+                  &HandleCount,

+                  &HandleBuffer

+                  );

+  ASSERT_EFI_ERROR (Status);

+

+  mNumberOfPciRootBridges = HandleCount;

+

+  mPciRootBridgeData = AllocatePool (HandleCount * sizeof (PCI_ROOT_BRIDGE_DATA));

+  ASSERT (mPciRootBridgeData != NULL);

+

+  //

+  // Traverse all PCI Root Bridge I/O Protocol instances, and record the protocol

+  // instances, together with their segment numbers and bus ranges.

+  //

+  for (Index = 0; Index < HandleCount; Index++) {

+    Status = gBS->HandleProtocol (

+                    HandleBuffer[Index],

+                    &gEfiPciRootBridgeIoProtocolGuid,

+                    (VOID **) &PciRootBridgeIo

+                    );

+    ASSERT_EFI_ERROR (Status);

+

+    mPciRootBridgeData[Index].PciRootBridgeIo = PciRootBridgeIo;

+    mPciRootBridgeData[Index].SegmentNumber   = PciRootBridgeIo->SegmentNumber;

+

+    Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);

+    ASSERT_EFI_ERROR (Status);

+

+    while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {

+      if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {

+        mPciRootBridgeData[Index].MinBusNumber = Descriptors->AddrRangeMin;

+        mPciRootBridgeData[Index].MaxBusNumber = Descriptors->AddrRangeMax;

+        break;

+      }

+      Descriptors++;

+    }

+    ASSERT (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR);

+  }

+

+  FreePool(HandleBuffer);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  The destructor function frees memory allocated by constructor.

+  

+  The destructor function frees memory for data of protocol instances allocated by constructor.

+  It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. 

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+  

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+PciSegmentLibDestructor (

+  IN EFI_HANDLE                ImageHandle,

+  IN EFI_SYSTEM_TABLE          *SystemTable

+  )

+{

+  FreePool (mPciRootBridgeData);

+

+  return EFI_SUCCESS;

+}

+

+/**

+  According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.

+

+  This internal function extracts segment number and bus number data from address, and

+  retrieves the corresponding PCI Root Bridge I/O Protocol instance.

+

+  @param  Address The address that encodes the Segment, PCI Bus, Device, Function and

+                  Register.

+

+  @return The address for PCI Root Bridge I/O Protocol.

+

+**/

+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *

+PciSegmentLibSearchForRootBridge (

+  IN UINT64                    Address

+  )

+{

+  UINTN                              Index;

+  UINT64                             SegmentNumber;

+  UINT64                             BusNumber;

+

+  for (Index = 0; Index < mNumberOfPciRootBridges; Index++) {

+    //

+    // Matches segment number of address with the segment number of protocol instance.

+    //

+    SegmentNumber = BitFieldRead64 (Address, 32, 63);

+    if (SegmentNumber == mPciRootBridgeData[Index].SegmentNumber) {

+      //

+      // Matches the bus number of address with bus number range of protocol instance.

+      //

+      BusNumber = BitFieldRead64 (Address, 20, 27);

+      if (BusNumber >= mPciRootBridgeData[Index].MinBusNumber && BusNumber <= mPciRootBridgeData[Index].MaxBusNumber) {

+        return mPciRootBridgeData[Index].PciRootBridgeIo;

+      }

+    }    

+  }

+  return NULL;

+}

+

+/**

+  Internal worker function to read a PCI configuration register.

+

+  This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.

+  It reads and returns the PCI configuration register specified by Address,

+  the width of data is specified by Width.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   Width of data to read

+

+  @return The value read from the PCI configuration register.

+

+**/

+UINT32

+DxePciSegmentLibPciRootBridgeIoReadWorker (

+  IN  UINT64                                 Address,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width

+  )

+{

+  UINT32                               Data;

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL      *PciRootBridgeIo; 

+

+  PciRootBridgeIo = PciSegmentLibSearchForRootBridge (Address);

+  ASSERT (PciRootBridgeIo != NULL);

+

+  PciRootBridgeIo->Pci.Read (

+                         PciRootBridgeIo,

+                         Width,

+                         PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),

+                         1,

+                         &Data

+                         );

+

+  return Data;

+}

+

+/**

+  Internal worker function to writes a PCI configuration register.

+

+  This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.

+  It writes the PCI configuration register specified by Address with the

+  value specified by Data. The width of data is specifed by Width.

+  Data is returned.

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  @param  Width   Width of data to write

+  @param  Data    The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+DxePciSegmentLibPciRootBridgeIoWriteWorker (

+  IN  UINT64                                 Address,

+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH  Width,

+  IN  UINT32                                 Data

+  )

+{

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL      *PciRootBridgeIo; 

+

+  PciRootBridgeIo = PciSegmentLibSearchForRootBridge (Address);

+  ASSERT (PciRootBridgeIo != NULL);

+

+  PciRootBridgeIo->Pci.Write (

+                         PciRootBridgeIo,

+                         Width,

+                         PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),

+                         1,

+                         &Data

+                         );

+

+  return Data;

+}

+

+/**

+  Register a PCI device so PCI configuration registers may be accessed after 

+  SetVirtualAddressMap().

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address The address that encodes the PCI Bus, Device, Function and

+                  Register.

+  

+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.

+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function 

+                                   after ExitBootServices().

+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device

+                                   at runtime could not be mapped.

+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to

+                                   complete the registration.

+

+**/

+RETURN_STATUS

+EFIAPI

+PciSegmentRegisterForRuntimeAccess (

+  IN UINTN  Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+  return RETURN_UNSUPPORTED;

+}

+

+/**

+  Reads an 8-bit PCI configuration register.

+

+  Reads and returns the 8-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 8-bit PCI configuration register specified by Address.

+

+**/

+UINT8

+EFIAPI

+PciSegmentRead8 (

+  IN UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);

+}

+

+/**

+  Writes an 8-bit PCI configuration register.

+

+  Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentWrite8 (

+  IN UINT64                    Address,

+  IN UINT8                     Value

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);

+

+  return (UINT8) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Value);

+}

+

+/**

+  Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentOr8 (

+  IN UINT64                    Address,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.

+

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAnd8 (

+  IN UINT64                    Address,

+  IN UINT8                     AndData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,

+  followed a  bitwise OR with another 8-bit value.

+  

+  Reads the 8-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the 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 8-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData    The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentAndThenOr8 (

+  IN UINT64                    Address,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in an 8-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldRead8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  8-bit register is returned.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldWrite8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     Value

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 8-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldOr8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 8-bit register.

+

+  Reads the 8-bit PCI configuration register specified by Address, performs a

+  bitwise AND between the read result and the value specified by AndData, and

+  writes the result to the 8-bit PCI configuration register specified by

+  Address. The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are

+  serialized. Extra left bits in AndData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAnd8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  8-bit port.

+

+  Reads the 8-bit PCI configuration register specified by Address, 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 8-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT8

+EFIAPI

+PciSegmentBitFieldAndThenOr8 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT8                     AndData,

+  IN UINT8                     OrData

+  )

+{

+  return PciSegmentWrite8 (

+           Address,

+           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 16-bit PCI configuration register.

+

+  Reads and returns the 16-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 16-bit PCI configuration register specified by Address.

+

+**/

+UINT16

+EFIAPI

+PciSegmentRead16 (

+  IN UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);

+}

+

+/**

+  Writes a 16-bit PCI configuration register.

+

+  Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT16

+EFIAPI

+PciSegmentWrite16 (

+  IN UINT64                    Address,

+  IN UINT16                    Value

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);

+

+  return (UINT16) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);

+}

+

+/**

+  Performs a bitwise OR of a 16-bit PCI configuration register with

+  a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 16-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address The address that encodes the PCI Segment, Bus, Device, Function and

+                  Register.

+  @param  OrData  The value to OR with the PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentOr16 (

+  IN UINT64                    Address,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+  

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAnd16 (

+  IN UINT64                    Address,

+  IN UINT16                    AndData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));

+}

+

+/**

+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,

+  followed a  bitwise OR with another 16-bit value.

+  

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the 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 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData    The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentAndThenOr16 (

+  IN UINT64                    Address,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 16-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to read.

+  @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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldRead16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  16-bit register is returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldWrite16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    Value

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address. 

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldOr16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,

+  and writes the result back to the bit field in the 16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 16-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  Extra left bits in OrData are stripped.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 16-bit boundary, 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  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  StartBit  The ordinal of the least significant bit in the bit field.

+                    The ordinal of the least significant bit in a byte is bit 0.

+  @param  EndBit    The ordinal of the most significant bit in the bit field.

+                    The ordinal of the most significant bit in a byte is bit 7.

+  @param  AndData   The value to AND with the read value from the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAnd16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  16-bit port.

+

+  Reads the 16-bit PCI configuration register specified by Address, 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 16-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register to write.

+  @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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT16

+EFIAPI

+PciSegmentBitFieldAndThenOr16 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT16                    AndData,

+  IN UINT16                    OrData

+  )

+{

+  return PciSegmentWrite16 (

+           Address,

+           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a 32-bit PCI configuration register.

+

+  Reads and returns the 32-bit PCI configuration register specified by Address.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+

+  @return The 32-bit PCI configuration register specified by Address.

+

+**/

+UINT32

+EFIAPI

+PciSegmentRead32 (

+  IN UINT64                    Address

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);

+

+  return DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);

+}

+

+/**

+  Writes a 32-bit PCI configuration register.

+

+  Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.

+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  Value       The value to write.

+

+  @return The parameter of Value.

+

+**/

+UINT32

+EFIAPI

+PciSegmentWrite32 (

+  IN UINT64                    Address,

+  IN UINT32                    Value

+  )

+{

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);

+

+  return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);

+}

+

+/**

+  Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise OR between the read result and the value specified by OrData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentOr32 (

+  IN UINT64                    Address,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.

+

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the read result and the value specified by AndData,

+  and writes the result to the 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAnd32 (

+  IN UINT64                    Address,

+  IN UINT32                    AndData

+  )

+{

+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);

+}

+

+/**

+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,

+  followed a  bitwise OR with another 32-bit value.

+  

+  Reads the 32-bit PCI configuration register specified by Address,

+  performs a bitwise AND between the 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 32-bit PCI configuration register specified by Address.

+  The value written to the PCI configuration register is returned.

+  This function must guarantee that all PCI read and write operations are serialized.

+  

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, then ASSERT().

+

+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.

+  @param  AndData   The value to AND with the PCI configuration register.

+  @param  OrData    The value to OR with the PCI configuration register.

+

+  @return The value written to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentAndThenOr32 (

+  IN UINT64                    Address,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);

+}

+

+/**

+  Reads a bit field of a PCI configuration register.

+

+  Reads the bit field in a 32-bit PCI configuration register. The bit field is

+  specified by the StartBit and the EndBit. The value of the bit field is

+  returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 value of the bit field read from the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldRead32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit

+  )

+{

+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);

+}

+

+/**

+  Writes a bit field to a PCI configuration register.

+

+  Writes Value to the bit field of the PCI configuration register. The bit

+  field is specified by the StartBit and the EndBit. All other bits in the

+  destination PCI configuration register are preserved. The new value of the

+  32-bit register is returned.

+

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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     The new value of the bit field.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldWrite32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    Value

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and

+  writes the result back to the bit field in the 32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, performs a

+  bitwise OR between the read result and the value specified by

+  OrData, and writes the result to the 32-bit PCI configuration register

+  specified by Address. The value written to the PCI configuration register is

+  returned. This function must guarantee that all PCI read and write operations

+  are serialized. Extra left bits in OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldOr32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise

+  AND, and writes the result back to the bit field in the 32-bit register.

+

+  

+  Reads the 32-bit PCI configuration register specified by Address, performs a bitwise

+  AND between the read result and the value specified by AndData, and writes the result

+  to the 32-bit PCI configuration register specified by Address. The value written to

+  the PCI configuration register is returned.  This function must guarantee that all PCI

+  read and write operations are serialized.  Extra left bits in AndData are stripped.

+  If any reserved bits in Address are set, then ASSERT().

+  If Address is not aligned on a 32-bit boundary, 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  Address   The PCI configuration register 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 PCI configuration register.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAnd32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)

+           );

+}

+

+/**

+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a

+  bitwise OR, and writes the result back to the bit field in the

+  32-bit port.

+

+  Reads the 32-bit PCI configuration register specified by Address, 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 32-bit PCI

+  configuration register specified by Address. The value written to the PCI

+  configuration register is returned. This function must guarantee that all PCI

+  read and write operations are serialized. Extra left bits in both AndData and

+  OrData are stripped.

+

+  If any reserved bits in Address are set, 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  Address   The PCI configuration register 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 PCI configuration register.

+  @param  OrData    The value to OR with the result of the AND operation.

+

+  @return The value written back to the PCI configuration register.

+

+**/

+UINT32

+EFIAPI

+PciSegmentBitFieldAndThenOr32 (

+  IN UINT64                    Address,

+  IN UINTN                     StartBit,

+  IN UINTN                     EndBit,

+  IN UINT32                    AndData,

+  IN UINT32                    OrData

+  )

+{

+  return PciSegmentWrite32 (

+           Address,

+           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)

+           );

+}

+

+/**

+  Reads a range of PCI configuration registers into a caller supplied buffer.

+

+  Reads the range of PCI configuration registers specified by StartAddress and

+  Size into the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be read. Size is

+  returned. When possible 32-bit PCI configuration read cycles are used to read

+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit

+  and 16-bit PCI configuration read cycles may be used at the beginning and the

+  end of the range.

+

+  If any reserved bits in StartAddress are set, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer receiving the data read.

+

+  @return Size

+

+**/

+UINTN

+EFIAPI

+PciSegmentReadBuffer (

+  IN  UINT64                   StartAddress,

+  IN  UINTN                    Size,

+  OUT VOID                     *Buffer

+  )

+{

+  UINTN                                ReturnValue;

+

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return Size;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Read a byte if StartAddress is byte aligned

+    //

+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Read a word if StartAddress is word aligned

+    //

+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Read as many double words as possible

+    //

+    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Read the last remaining word if exist

+    //

+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Read the last remaining byte if exist

+    //

+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);

+  }

+

+  return ReturnValue;

+}

+

+/**

+  Copies the data in a caller supplied buffer to a specified range of PCI

+  configuration space.

+

+  Writes the range of PCI configuration registers specified by StartAddress and

+  Size from the buffer specified by Buffer. This function only allows the PCI

+  configuration registers from a single PCI function to be written. Size is

+  returned. When possible 32-bit PCI configuration write cycles are used to

+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,

+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning

+  and the end of the range.

+

+  If any reserved bits in StartAddress are set, then ASSERT().

+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().

+  If Size > 0 and Buffer is NULL, then ASSERT().

+

+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, Device,

+                        Function and Register.

+  @param  Size          The size in bytes of the transfer.

+  @param  Buffer        The pointer to a buffer containing the data to write.

+

+  @return The parameter of Size.

+

+**/

+UINTN

+EFIAPI

+PciSegmentWriteBuffer (

+  IN UINT64                    StartAddress,

+  IN UINTN                     Size,

+  IN VOID                      *Buffer

+  )

+{

+  UINTN                                ReturnValue;

+

+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);

+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);

+

+  if (Size == 0) {

+    return 0;

+  }

+

+  ASSERT (Buffer != NULL);

+

+  //

+  // Save Size for return

+  //

+  ReturnValue = Size;

+

+  if ((StartAddress & BIT0) != 0) {

+    //

+    // Write a byte if StartAddress is byte aligned

+    //

+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);

+    StartAddress += sizeof (UINT8);

+    Size -= sizeof (UINT8);

+    Buffer = (UINT8*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {

+    //

+    // Write a word if StartAddress is word aligned

+    //

+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  while (Size >= sizeof (UINT32)) {

+    //

+    // Write as many double words as possible

+    //

+    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));

+    StartAddress += sizeof (UINT32);

+    Size -= sizeof (UINT32);

+    Buffer = (UINT32*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT16)) {

+    //

+    // Write the last remaining word if exist

+    //

+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));

+    StartAddress += sizeof (UINT16);

+    Size -= sizeof (UINT16);

+    Buffer = (UINT16*)Buffer + 1;

+  }

+

+  if (Size >= sizeof (UINT8)) {

+    //

+    // Write the last remaining byte if exist

+    //

+    PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);

+  }

+

+  return ReturnValue;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.h b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.h
new file mode 100644
index 0000000..7f130fe
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.h
@@ -0,0 +1,59 @@
+/** @file

+  Include file of PciSegmentPciRootBridgeIo Library.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#ifndef __DXE_PCI_SEGMENT_LIB__

+#define __DXE_PCI_SEGMENT_LIB__

+

+#include <PiDxe.h>

+

+#include <Protocol/PciRootBridgeIo.h>

+

+#include <Library/PciSegmentLib.h>

+#include <Library/BaseLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/DebugLib.h>

+

+#include <IndustryStandard/Acpi.h>

+

+typedef struct {

+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *PciRootBridgeIo;

+  UINT32                             SegmentNumber;

+  UINT64                             MinBusNumber;

+  UINT64                             MaxBusNumber;

+} PCI_ROOT_BRIDGE_DATA;

+

+/**

+  Assert the validity of a PCI Segment address.

+  A valid PCI Segment address should not contain 1's in bits 28..31 and 48..63

+

+  @param  A The address to validate.

+  @param  M Additional bits to assert to be zero.

+

+**/

+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \

+  ASSERT (((A) & (0xffff0000f0000000ULL | (M))) == 0)

+

+/**

+  Translate PCI Lib address into format of PCI Root Bridge I/O Protocol

+

+  @param  A  The address that encodes the PCI Bus, Device, Function and

+             Register.

+

+**/

+#define PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS(A) \

+  ((((UINT32)(A) << 4) & 0xff000000) | (((UINT32)(A) >> 4) & 0x00000700) | (((UINT32)(A) << 1) & 0x001f0000) | (LShiftU64((A) & 0xfff, 32)))

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/UefiPciSegmentLibPciRootBridgeIo.inf b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/UefiPciSegmentLibPciRootBridgeIo.inf
new file mode 100644
index 0000000..12f465b
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/UefiPciSegmentLibPciRootBridgeIo.inf
@@ -0,0 +1,60 @@
+## @file

+# PCI Segment Library that layers on top of the PCI Root Bridge I/O Protocol.

+#

+# This library produces the APIs from the PCI Library and implements these APIs

+#  by calling into the PCI Root Bridge I/O Protocols that are present in the platform.

+#  The PCI Root Bridge I/O Protocols are typically produced by a chipset specific DXE driver.

+#  This library binds to all of the PCI Root Bridge I/O Protocols in the platform and handles

+#  the translation from a PCI segment number into a specific PCI Root Bridge I/O Protocol.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiPciSegmentLibPciRootBridgeIo

+  MODULE_UNI_FILE                = UefiPciSegmentLibPciRootBridgeIo.uni

+  FILE_GUID                      = C6068612-B6E0-48a3-BB92-60E4A4F89EDF

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = PciSegmentLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION

+

+  CONSTRUCTOR                    = PciSegmentLibConstructor

+  DESTRUCTOR                     = PciSegmentLibDestructor

+

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  PciSegmentLib.h

+  PciSegmentLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  MemoryAllocationLib

+  BaseLib

+  UefiBootServicesTableLib

+  DebugLib

+

+[Protocols]

+  gEfiPciRootBridgeIoProtocolGuid               ## CONSUMES

+

+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]

+  gEfiPciRootBridgeIoProtocolGuid

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/UefiPciSegmentLibPciRootBridgeIo.uni b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/UefiPciSegmentLibPciRootBridgeIo.uni
new file mode 100644
index 0000000..4c2d45c
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/UefiPciSegmentLibPciRootBridgeIo.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/RuntimeLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/RuntimeLib.c
new file mode 100644
index 0000000..63ae976
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/RuntimeLib.c
@@ -0,0 +1,843 @@
+/** @file

+  UEFI Runtime Library implementation for non IPF processor types.

+

+  This library hides the global variable for the EFI Runtime Services so the

+  caller does not need to deal with the possibility of being called from an

+  OS virtual address space. All pointer values are different for a virtual 

+  mapping than from the normal physical mapping at boot services time.

+

+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.

+

+**/

+

+#include <Uefi.h>

+#include <Library/UefiRuntimeLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Guid/EventGroup.h>

+

+///

+/// Driver Lib Module Globals

+///

+EFI_EVENT              mEfiVirtualNotifyEvent;

+EFI_EVENT              mEfiExitBootServicesEvent;

+BOOLEAN                mEfiGoneVirtual         = FALSE;

+BOOLEAN                mEfiAtRuntime           = FALSE;

+EFI_RUNTIME_SERVICES   *mInternalRT;

+

+/**

+  Set AtRuntime flag as TRUE after ExitBootServices.

+

+  @param[in]  Event   The Event that is being processed.

+  @param[in]  Context The Event Context.

+

+**/

+VOID

+EFIAPI

+RuntimeLibExitBootServicesEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+{

+  mEfiAtRuntime = TRUE;

+}

+

+/**

+  Fixup internal data so that EFI can be call in virtual mode.

+  Call the passed in Child Notify event and convert any pointers in

+  lib to virtual mode.

+

+  @param[in]    Event   The Event that is being processed.

+  @param[in]    Context The Event Context.

+**/

+VOID

+EFIAPI

+RuntimeLibVirtualNotifyEvent (

+  IN EFI_EVENT        Event,

+  IN VOID             *Context

+  )

+{

+  //

+  // Update global for Runtime Services Table and IO

+  //

+  EfiConvertPointer (0, (VOID **) &mInternalRT);

+

+  mEfiGoneVirtual = TRUE;

+}

+

+/**

+  Initialize runtime Driver Lib if it has not yet been initialized.

+  It will ASSERT() if gRT is NULL or gBS is NULL.

+  It will ASSERT() if that operation fails.

+

+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.

+  @param[in]  SystemTable   A pointer to the EFI System Table.

+

+  @return     EFI_STATUS    always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.

+**/

+EFI_STATUS

+EFIAPI

+RuntimeDriverLibConstruct (

+  IN EFI_HANDLE           ImageHandle,

+  IN EFI_SYSTEM_TABLE     *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  ASSERT (gRT != NULL);

+  ASSERT (gBS != NULL);

+

+  mInternalRT = gRT;

+  //

+  // Register SetVirtualAddressMap () notify function

+  //

+  Status = gBS->CreateEventEx (

+                  EVT_NOTIFY_SIGNAL,

+                  TPL_NOTIFY,

+                  RuntimeLibVirtualNotifyEvent,

+                  NULL,

+                  &gEfiEventVirtualAddressChangeGuid,

+                  &mEfiVirtualNotifyEvent

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gBS->CreateEventEx (

+                  EVT_NOTIFY_SIGNAL,

+                  TPL_NOTIFY,

+                  RuntimeLibExitBootServicesEvent,

+                  NULL,

+                  &gEfiEventExitBootServicesGuid,

+                  &mEfiExitBootServicesEvent

+                  );

+

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  If a runtime driver exits with an error, it must call this routine 

+  to free the allocated resource before the exiting.

+  It will ASSERT() if gBS is NULL.

+  It will ASSERT() if that operation fails.

+

+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.

+  @param[in]  SystemTable   A pointer to the EFI System Table.

+

+  @retval     EFI_SUCCESS       The Runtime Driver Lib shutdown successfully.

+  @retval     EFI_UNSUPPORTED   Runtime Driver lib was not initialized.

+**/

+EFI_STATUS

+EFIAPI

+RuntimeDriverLibDeconstruct (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS  Status;

+

+  //

+  // Close SetVirtualAddressMap () notify function

+  //

+  ASSERT (gBS != NULL);

+  Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  Status = gBS->CloseEvent (mEfiExitBootServicesEvent);

+  ASSERT_EFI_ERROR (Status);

+

+  return Status;

+}

+

+/**

+  This function allows the caller to determine if UEFI ExitBootServices() has been called.

+

+  This function returns TRUE after all the EVT_SIGNAL_EXIT_BOOT_SERVICES functions have

+  executed as a result of the OS calling ExitBootServices().  Prior to this time FALSE

+  is returned. This function is used by runtime code to decide it is legal to access

+  services that go away after ExitBootServices().

+

+  @retval  TRUE  The system has finished executing the EVT_SIGNAL_EXIT_BOOT_SERVICES event.

+  @retval  FALSE The system has not finished executing the EVT_SIGNAL_EXIT_BOOT_SERVICES event.

+

+**/

+BOOLEAN

+EFIAPI

+EfiAtRuntime (

+  VOID

+  )

+{

+  return mEfiAtRuntime;

+}

+

+/**

+  This function allows the caller to determine if UEFI SetVirtualAddressMap() has been called. 

+

+  This function returns TRUE after all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE functions have

+  executed as a result of the OS calling SetVirtualAddressMap(). Prior to this time FALSE

+  is returned. This function is used by runtime code to decide it is legal to access services

+  that go away after SetVirtualAddressMap().

+

+  @retval  TRUE  The system has finished executing the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.

+  @retval  FALSE The system has not finished executing the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.

+

+**/

+BOOLEAN

+EFIAPI

+EfiGoneVirtual (

+  VOID

+  )

+{

+  return mEfiGoneVirtual;

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service ResetSystem().

+

+  The ResetSystem()function resets the entire platform, including all processors and devices,and reboots the system.

+  Calling this interface with ResetType of EfiResetCold causes 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 without regard

+  to cycle boundaries. EfiResetCold is tantamount to a system power cycle.

+  Calling this interface with ResetType of EfiResetWarm causes 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.

+  Calling this interface with ResetType of EfiResetShutdown causes the system to enter a power state equivalent to the

+  ACPI G2/S5 or G3 states. If the system does not support this reset type, then when the system is rebooted, it should

+  exhibit the EfiResetCold attributes.

+  The platform may optionally log the parameters from any non-normal reset that occurs.

+  The ResetSystem() function does not return.

+

+  @param  ResetType   The type of reset to perform.

+  @param  ResetStatus The status code for the reset. If the system reset is part of a normal operation, the status code

+                      would be EFI_SUCCESS. If the system reset is due to some type of failure the most appropriate EFI

+                      Status code would be used.

+  @param  DataSizeThe size, in bytes, of ResetData.

+  @param  ResetData   For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown the data buffer starts with a

+                      Null-terminated Unicode 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 then EFI_SUCCESS. This pointer must be a physical

+                      address. For a ResetType of EfiRestUpdate the data buffer also starts with a Null-terminated string

+                      that is followed by a physical VOID * to an EFI_CAPSULE_HEADER.

+

+**/

+VOID

+EFIAPI

+EfiResetSystem (

+  IN EFI_RESET_TYPE               ResetType,

+  IN EFI_STATUS                   ResetStatus,

+  IN UINTN                        DataSize,

+  IN VOID                         *ResetData OPTIONAL

+  )

+{

+  mInternalRT->ResetSystem (ResetType, ResetStatus, DataSize, ResetData);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service GetTime().

+

+  The GetTime() function returns a time that was valid sometime during the call to the function.

+  While the returned EFI_TIME structure contains TimeZone and Daylight savings time information,

+  the actual clock does not maintain these values. The current time zone and daylight saving time

+  information returned by GetTime() are the values that were last set via SetTime().

+  The GetTime() function should take approximately the same amount of time to read the time each

+  time it is called. All reported device capabilities are to be rounded up.

+  During runtime, if a PC-AT CMOS device is present in the platform the caller must synchronize

+  access to the device before calling GetTime().

+

+  @param  Time         A pointer to storage to receive a snapshot of the current time.

+  @param  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 a hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetTime (

+  OUT EFI_TIME                    *Time,

+  OUT EFI_TIME_CAPABILITIES       *Capabilities  OPTIONAL

+  )

+{

+  return mInternalRT->GetTime (Time, Capabilities);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service SetTime().

+

+  The SetTime() function sets the real time clock device to the supplied time, and records the

+  current time zone and daylight savings time information. The SetTime() function is not allowed

+  to loop based on the current time. For example, if the device does not support a hardware reset

+  for the sub-resolution time, the code is not to implement the feature by waiting for the time to

+  wrap.

+  During runtime, if a PC-AT CMOS device is present in the platform the caller must synchronize

+  access to the device before calling SetTime().

+

+  @param  Time  A pointer to the current time. Type EFI_TIME is defined in the GetTime()

+                function description. Full error checking is performed on the different

+                fields of the EFI_TIME structure (refer to the EFI_TIME definition in the

+                GetTime() function description for full details), and EFI_INVALID_PARAMETER

+                is returned if any field is out of range.

+

+  @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 to a hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiSetTime (

+  IN EFI_TIME                   *Time

+  )

+{

+  return mInternalRT->SetTime (Time);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service GetWakeupTime().

+

+  The alarm clock time may be rounded from the set alarm clock time to be within the resolution

+  of the alarm clock device. The resolution of the alarm clock device is defined to be one second.

+  During runtime, if a PC-AT CMOS device is present in the platform the caller must synchronize

+  access to the device before calling GetWakeupTime().

+

+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.

+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.

+  @param  Time     The current alarm setting. Type EFI_TIME is defined in the GetTime()

+                   function description.

+

+  @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.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetWakeupTime (

+  OUT BOOLEAN                     *Enabled,

+  OUT BOOLEAN                     *Pending,

+  OUT EFI_TIME                    *Time

+  )

+{

+  return mInternalRT->GetWakeupTime (Enabled, Pending, Time);

+}

+

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service SetWakeupTime()

+

+  Setting a system wakeup alarm causes the system to wake up or power on at the set time.

+  When the alarm fires, the alarm signal is latched until it is acknowledged by calling SetWakeupTime()

+  to disable the alarm. If the alarm fires before the system is put into a sleeping or off state,

+  since the alarm signal is latched the system will immediately wake up. If the alarm fires while

+  the system is off and there is insufficient power to power on the system, the system is powered

+  on when power is restored.

+

+  @param  Enable  Enable or disable the wakeup alarm.

+  @param  Time    If Enable is TRUE, the time to set the wakeup alarm for. Type EFI_TIME

+                  is defined in the GetTime() function description. 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.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiSetWakeupTime (

+  IN BOOLEAN                      Enable,

+  IN EFI_TIME                     *Time   OPTIONAL

+  )

+{

+  return mInternalRT->SetWakeupTime (Enable, Time);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service GetVariable().

+

+  Each vendor may create and manage its own variables without the risk of name conflicts by

+  using a unique VendorGuid. When a variable is set its Attributes are supplied to indicate

+  how the data variable should be stored and maintained by the system. The attributes affect

+  when the variable may be accessed and volatility of the data. Any attempts to access a variable

+  that does not have the attribute set for runtime access will yield the EFI_NOT_FOUND error.

+  If the Data buffer is too small to hold the contents of the variable, the error EFI_BUFFER_TOO_SMALL

+  is returned and DataSize is set to the required buffer size to obtain the data.

+

+  @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String

+  @param  VendorGuid   Unify identifier for vendor.

+  @param  Attributes   Point to memory location to return the attributes of variable. If the point

+                       is NULL, the parameter would be ignored.

+  @param  DataSize     As input, point to the maximum size of return Data-Buffer.

+                       As output, point to the actual size of the returned Data-Buffer.

+  @param  Data         Point to return Data-Buffer.

+

+  @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. DataSize has

+                                  been updated with the size needed to complete the request.

+  @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.

+**/

+EFI_STATUS

+EFIAPI

+EfiGetVariable (

+  IN      CHAR16                   *VariableName,

+  IN      EFI_GUID                 *VendorGuid,

+  OUT     UINT32                   *Attributes OPTIONAL,

+  IN OUT  UINTN                    *DataSize,

+  OUT     VOID                     *Data

+  )

+{

+  return mInternalRT->GetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service GetNextVariableName().

+

+  GetNextVariableName() is called multiple times to retrieve the VariableName and VendorGuid of

+  all variables currently available in the system. On each call to GetNextVariableName() the

+  previous results are passed into the interface, and on output the interface returns the next

+  variable name data. When the entire variable list has been returned, the error EFI_NOT_FOUND

+  is returned.

+

+  @param  VariableNameSize As input, point to maximum size of variable name.

+                           As output, point to actual size of variable name.

+  @param  VariableName     As input, supplies the last VariableName that was returned by

+                           GetNextVariableName().

+                           As output, returns the name of variable. The name

+                           string is Null-Terminated Unicode string.

+  @param  VendorGuid       As input, supplies the last VendorGuid that was returned by

+                           GetNextVriableName().

+                           As 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.

+                                 VariableNameSize has been updated with the size needed

+                                 to complete the request.

+  @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 name could not be retrieved due to a hardware error.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetNextVariableName (

+  IN OUT UINTN                    *VariableNameSize,

+  IN OUT CHAR16                   *VariableName,

+  IN OUT EFI_GUID                 *VendorGuid

+  )

+{

+  return mInternalRT->GetNextVariableName (VariableNameSize, VariableName, VendorGuid);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service GetNextVariableName()

+

+  Variables are stored by the firmware and may maintain their values across power cycles. Each vendor

+  may create and manage its own variables without the risk of name conflicts by using a unique VendorGuid.

+

+  @param  VariableName The name of the vendor's variable; it's a Null-Terminated 

+                       Unicode String

+  @param  VendorGuid   Unify identifier for vendor.

+  @param  Attributes   Points to a memory location to return the attributes of variable. If the point

+                       is NULL, the parameter would be ignored.

+  @param  DataSize     The size in bytes of Data-Buffer.

+  @param  Data         Points to the content of 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 was supplied, or the

+                                  DataSize exceeds the maximum allowed.

+  @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode 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 saved due to a hardware failure.

+  @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

+                                  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.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiSetVariable (

+  IN CHAR16                       *VariableName,

+  IN EFI_GUID                     *VendorGuid,

+  IN UINT32                       Attributes,

+  IN UINTN                        DataSize,

+  IN VOID                         *Data

+  )

+{

+  return mInternalRT->SetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service GetNextHighMonotonicCount().

+

+  The platform's monotonic counter is comprised of two 32-bit quantities: the high 32 bits and

+  the low 32 bits. During boot service time the low 32-bit value is volatile: it is reset to zero

+  on every system reset and is increased by 1 on every call to GetNextMonotonicCount(). The high

+  32-bit value is nonvolatile and is increased by 1 whenever the system resets or whenever the low

+  32-bit count (returned by GetNextMonoticCount()) overflows.

+

+  @param  HighCount The pointer to returned value.

+

+  @retval  EFI_SUCCESS           The next high monotonic count was returned.

+  @retval  EFI_DEVICE_ERROR      The device is not functioning properly.

+  @retval  EFI_INVALID_PARAMETER HighCount is NULL.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiGetNextHighMonotonicCount (

+  OUT UINT32                      *HighCount

+  )

+{

+  return mInternalRT->GetNextHighMonotonicCount (HighCount);

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service ConvertPointer().  

+

+  The ConvertPointer() function is used by an EFI component during the SetVirtualAddressMap() operation.

+  ConvertPointer()must be called using physical address pointers during the execution of SetVirtualAddressMap().

+

+  @param  DebugDisposition   Supplies type information for the pointer being converted.

+  @param  Address            The pointer to a pointer that is to be fixed to be the

+                             value needed for the new virtual address mapping being

+                             applied.

+

+  @retval  EFI_SUCCESS            The pointer pointed to by Address was modified.

+  @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.

+  @retval  EFI_INVALID_PARAMETER  Address is NULL.

+  @retval  EFI_INVALID_PARAMETER  *Address is NULL and DebugDispositio

+

+**/

+EFI_STATUS

+EFIAPI

+EfiConvertPointer (

+  IN UINTN                  DebugDisposition,

+  IN OUT VOID               **Address

+  )

+{

+  return gRT->ConvertPointer (DebugDisposition, Address);

+}

+

+

+/**

+  Determines the new virtual address that is to be used on subsequent memory accesses.

+

+  For IA32, x64, and EBC, this service is a wrapper for the UEFI Runtime Service

+  ConvertPointer().  See the UEFI Specification for details. 

+  For IPF, this function interprets Address as a pointer to an EFI_PLABEL structure

+  and both the EntryPoint and GP fields of an EFI_PLABEL are converted from physical

+  to virtiual addressing.  Since IPF allows the GP to point to an address outside

+  a PE/COFF image, the physical to virtual offset for the EntryPoint field is used

+  to adjust the GP field.  The UEFI Runtime Service ConvertPointer() is used to convert

+  EntryPoint and the status code for this conversion is always returned.   If the convertion

+  of EntryPoint fails, then neither EntryPoint nor GP are modified.  See the UEFI

+  Specification for details on the UEFI Runtime Service ConvertPointer().

+

+  @param  DebugDisposition   Supplies type information for the pointer being converted.

+  @param  Address            The pointer to a pointer that is to be fixed to be the

+                             value needed for the new virtual address mapping being

+                             applied.

+

+  @return  EFI_STATUS value from EfiConvertPointer().

+

+**/

+EFI_STATUS

+EFIAPI

+EfiConvertFunctionPointer (

+  IN UINTN                DebugDisposition,

+  IN OUT VOID             **Address

+  )

+{

+  return EfiConvertPointer (DebugDisposition, Address);

+}

+

+

+/**

+  Convert the standard Lib double linked list to a virtual mapping.

+

+  This service uses EfiConvertPointer() to walk a double linked list and convert all the link

+  pointers to their virtual mappings. This function is only guaranteed to work during the

+  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event and calling it at other times has undefined results.

+

+  @param  DebugDisposition   Supplies type information for the pointer being converted.

+  @param  ListHead           Head of linked list to convert.

+

+  @retval  EFI_SUCCESS  Success to execute the function.

+  @retval  !EFI_SUCCESS Failed to e3xecute the function.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiConvertList (

+  IN UINTN                DebugDisposition,

+  IN OUT LIST_ENTRY       *ListHead

+  )

+{

+  LIST_ENTRY  *Link;

+  LIST_ENTRY  *NextLink;

+  

+  //

+  // For NULL List, return EFI_SUCCESS

+  //

+  if (ListHead == NULL) {

+    return EFI_SUCCESS;

+  }

+

+  //

+  // Convert all the ForwardLink & BackLink pointers in the list

+  //

+  Link = ListHead;

+  do {

+    NextLink = Link->ForwardLink;

+

+    EfiConvertPointer (

+      Link->ForwardLink == ListHead ? DebugDisposition : 0,

+      (VOID **) &Link->ForwardLink

+      );

+

+    EfiConvertPointer (

+      Link->BackLink == ListHead ? DebugDisposition : 0,

+      (VOID **) &Link->BackLink

+      );

+

+    Link = NextLink;

+  } while (Link != ListHead);

+  return EFI_SUCCESS;

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service SetVirtualAddressMap().

+

+  The SetVirtualAddressMap() function is used by the OS loader. The function can only be called

+  at runtime, and is called by the owner of the system's memory map. I.e., the component which

+  called ExitBootServices(). All events of type EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE must be signaled

+  before SetVirtualAddressMap() returns.

+

+  @param  MemoryMapSize         The size in bytes of VirtualMap.

+  @param  DescriptorSize        The size in bytes of an entry in the VirtualMap.

+  @param  DescriptorVersion     The version of the structure entries in VirtualMap.

+  @param  VirtualMap            An array of memory descriptors which contain new virtual

+                                address mapping information for all runtime ranges. Type

+                                EFI_MEMORY_DESCRIPTOR is defined in the

+                                GetMemoryMap() function description.

+

+  @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.

+**/

+EFI_STATUS

+EFIAPI

+EfiSetVirtualAddressMap (

+  IN UINTN                          MemoryMapSize,

+  IN UINTN                          DescriptorSize,

+  IN UINT32                         DescriptorVersion,

+  IN CONST EFI_MEMORY_DESCRIPTOR    *VirtualMap

+  )

+{

+  return mInternalRT->SetVirtualAddressMap (

+                        MemoryMapSize,

+                        DescriptorSize,

+                        DescriptorVersion,

+                        (EFI_MEMORY_DESCRIPTOR *) VirtualMap

+                        );

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service UpdateCapsule().

+

+  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  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules

+                                being passed into update capsule. Each capsules is assumed to

+                                stored in contiguous virtual memory. The capsules in the

+                                CapsuleHeaderArray must be the same capsules as the

+                                ScatterGatherList. The CapsuleHeaderArray must

+                                have the capsules in the same order as the ScatterGatherList.

+  @param  CapsuleCount          The number of pointers to EFI_CAPSULE_HEADER in

+                                CaspuleHeaderArray.

+  @param  ScatterGatherList     Physical pointer to a set of

+                                EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the

+                                location in physical memory of a set of capsules. See Related

+                                Definitions for an explanation of how more than one capsule is

+                                passed via this interface. The capsules in the

+                                ScatterGatherList must be in the same order as the

+                                CapsuleHeaderArray. This parameter is only referenced if

+                                the capsules are defined to persist across system reset.

+

+  @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 or HeaderSize is NULL.

+  @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  There were insufficient resources to process the capsule.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiUpdateCapsule (

+  IN EFI_CAPSULE_HEADER       **CapsuleHeaderArray,

+  IN UINTN                    CapsuleCount,

+  IN EFI_PHYSICAL_ADDRESS     ScatterGatherList OPTIONAL

+  )

+{

+  return mInternalRT->UpdateCapsule (

+                        CapsuleHeaderArray,

+                        CapsuleCount,

+                        ScatterGatherList

+                        );

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service QueryCapsuleCapabilities().

+

+  The QueryCapsuleCapabilities() function allows a caller to test to see if a capsule or

+  capsules can be updated via UpdateCapsule(). The Flags values in the capsule header and

+  size of the entire capsule is checked.

+  If the caller needs to query for generic capsule capability a fake EFI_CAPSULE_HEADER can be

+  constructed where CapsuleImageSize is equal to HeaderSize that is equal to sizeof

+  (EFI_CAPSULE_HEADER). To determine reset requirements,

+  CAPSULE_FLAGS_PERSIST_ACROSS_RESET should be set in the Flags field of the

+  EFI_CAPSULE_HEADER.

+  The firmware must support any capsule that has the

+  CAPSULE_FLAGS_PERSIST_ACROSS_RESET flag set in EFI_CAPSULE_HEADER. The

+  firmware sets the policy for what capsules are supported that do not have the

+  CAPSULE_FLAGS_PERSIST_ACROSS_RESET flag set.

+

+  @param  CapsuleHeaderArray    Virtual pointer to an array of virtual pointers to the capsules

+                                being passed into update capsule. The capsules are assumed to

+                                stored in contiguous virtual memory.

+  @param  CapsuleCount          The number of pointers to EFI_CAPSULE_HEADER in

+                                CaspuleHeaderArray.

+  @param  MaximumCapsuleSize     On output the maximum size that UpdateCapsule() can

+                                support as an argument to UpdateCapsule() via

+                                CapsuleHeaderArray and ScatterGatherList.

+                                Undefined on input.

+  @param  ResetType             Returns the type of reset required for the capsule update.

+

+  @retval EFI_SUCCESS           A valid answer was returned.

+  @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL.

+  @retval EFI_UNSUPPORTED       The capsule type is not supported on this platform, and

+                                MaximumCapsuleSize and ResetType are undefined.

+  @retval EFI_OUT_OF_RESOURCES  There were insufficient resources to process the query request.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiQueryCapsuleCapabilities (

+  IN  EFI_CAPSULE_HEADER       **CapsuleHeaderArray,

+  IN  UINTN                    CapsuleCount,

+  OUT UINT64                   *MaximumCapsuleSize,

+  OUT EFI_RESET_TYPE           *ResetType

+  )

+{

+  return mInternalRT->QueryCapsuleCapabilities (

+                        CapsuleHeaderArray,

+                        CapsuleCount,

+                        MaximumCapsuleSize,

+                        ResetType

+                        );

+}

+

+

+/**

+  This service is a wrapper for the UEFI Runtime Service QueryVariableInfo().

+

+  The QueryVariableInfo() function allows a caller to obtain the information about the

+  maximum size of the storage space available for the EFI variables, the remaining size of the storage

+  space available for the EFI variables and the maximum size of each individual EFI variable,

+  associated with the attributes specified.

+  The returned MaximumVariableStorageSize, RemainingVariableStorageSize,

+  MaximumVariableSize information may change immediately after the call based on other

+  runtime activities including asynchronous error events. Also, these values associated with different

+  attributes are not additive in nature.

+

+  @param  Attributes            Attributes bitmask to specify the type of variables on

+                                which to return information. Refer to the

+                                GetVariable() function description.

+  @param  MaximumVariableStorageSize

+                                On output the maximum size of the storage space

+                                available for the EFI variables associated with the

+                                attributes specified.

+  @param  RemainingVariableStorageSize

+                                Returns the remaining size of the storage space

+                                available for the EFI variables associated with the

+                                attributes specified..

+  @param  MaximumVariableSize   Returns the maximum size of the individual EFI

+                                variables associated with the attributes specified.

+

+  @retval EFI_SUCCESS           A valid answer was returned.

+  @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.

+  @retval EFI_UNSUPPORTED       EFI_UNSUPPORTED The attribute is not supported on this platform, and the

+                                MaximumVariableStorageSize,

+                                RemainingVariableStorageSize, MaximumVariableSize

+                                are undefined.

+

+**/

+EFI_STATUS

+EFIAPI

+EfiQueryVariableInfo (

+  IN UINT32   Attributes,

+  OUT UINT64  *MaximumVariableStorageSize,

+  OUT UINT64  *RemainingVariableStorageSize,

+  OUT UINT64  *MaximumVariableSize

+  )

+{

+  return mInternalRT->QueryVariableInfo (

+                        Attributes,

+                        MaximumVariableStorageSize,

+                        RemainingVariableStorageSize,

+                        MaximumVariableSize

+                        );

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
new file mode 100644
index 0000000..8f46495
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
@@ -0,0 +1,51 @@
+## @file

+# Instance of UEFI Runtime Library.

+#

+# Instance of UEFI Runtime Library, with hooked EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE and

+#  EVT_SIGNAL_EXIT_BOOT_SERVICES event, to provide runtime services.

+# This instance also supports SAL drivers for better performance.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiRuntimeLib

+  MODULE_UNI_FILE                = UefiRuntimeLib.uni

+  FILE_GUID                      = b1ee6c28-54aa-4d17-b705-3e28ccb27b2e

+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiRuntimeLib|DXE_RUNTIME_DRIVER DXE_SAL_DRIVER

+

+  CONSTRUCTOR                    = RuntimeDriverLibConstruct

+  DESTRUCTOR                     = RuntimeDriverLibDeconstruct

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+

+[Sources]

+  RuntimeLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiBootServicesTableLib

+  UefiRuntimeServicesTableLib

+  DebugLib

+ 

+[Guids]

+  gEfiEventExitBootServicesGuid             ## CONSUMES ## Event

+  gEfiEventVirtualAddressChangeGuid         ## CONSUMES ## Event

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.uni
new file mode 100644
index 0000000..14a5e80
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c
new file mode 100644
index 0000000..29ead01
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c
@@ -0,0 +1,49 @@
+/** @file

+  UEFI Runtime Services Table Library.

+

+  This library instance retrieve EFI_RUNTIME_SERVICES pointer from EFI system table

+  in library's constructor.

+

+  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.

+

+**/

+

+#include <Uefi.h>

+#include <Library/DebugLib.h>

+

+EFI_RUNTIME_SERVICES  *gRT = NULL;

+

+/**

+  The constructor function caches the pointer of Runtime Services Table.

+

+  The constructor function caches the pointer of Runtime Services Table.

+  It will ASSERT() if the pointer of Runtime Services Table is NULL.

+  It will always return EFI_SUCCESS.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiRuntimeServicesTableLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  //

+  // Cache pointer to the EFI Runtime Services Table

+  //

+  gRT = SystemTable->RuntimeServices;

+  ASSERT (gRT != NULL);

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
new file mode 100644
index 0000000..a843436
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
@@ -0,0 +1,41 @@
+## @file

+# UEFI Runtime Services Table Library implementation.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiRuntimeServicesTableLib

+  MODULE_UNI_FILE                = UefiRuntimeServicesTableLib.uni

+  FILE_GUID                      = 19cbbb97-ff61-45ff-8c3f-dfa66dd118c8

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiRuntimeServicesTableLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE

+

+  CONSTRUCTOR                    = UefiRuntimeServicesTableLibConstructor

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  UefiRuntimeServicesTableLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  DebugLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.uni
new file mode 100644
index 0000000..afe0d99
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.c
new file mode 100644
index 0000000..e79c7ce
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.c
@@ -0,0 +1,139 @@
+/** @file

+  SAL Library implementation retrieving the SAL Entry Point from the SAL System Table

+  register in the EFI System Configuration Table.

+

+  Copyright (c) 2007 - 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.

+

+**/

+

+#include <PiDxe.h>

+#include <IndustryStandard/Sal.h>

+

+#include <Library/SalLib.h>

+#include <Library/UefiLib.h>

+#include <Library/DebugLib.h>

+

+#include <Guid/SalSystemTable.h>

+

+EFI_PLABEL       mPlabel;

+SAL_PROC         mSalProcEntry;

+

+/**

+  Makes a SAL procedure call.

+  

+  This is a wrapper function to make a SAL procedure call.  

+  No parameter checking is performed on the 8 input parameters,

+  but there are some common rules that the caller should follow

+  when making a SAL call.  Any address passed to SAL 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.

+  This function is only available on IPF.

+

+  @param  Index       The SAL procedure Index number.

+  @param  Arg2        The 2nd parameter for SAL procedure calls.

+  @param  Arg3        The 3rd parameter for SAL procedure calls.

+  @param  Arg4        The 4th parameter for SAL procedure calls.

+  @param  Arg5        The 5th parameter for SAL procedure calls.

+  @param  Arg6        The 6th parameter for SAL procedure calls.

+  @param  Arg7        The 7th parameter for SAL procedure calls.

+  @param  Arg8        The 8th parameter for SAL procedure calls.

+

+  @return SAL returned registers.

+

+**/

+SAL_RETURN_REGS

+EFIAPI

+SalCall (

+  IN UINT64  Index,

+  IN UINT64  Arg2,

+  IN UINT64  Arg3,

+  IN UINT64  Arg4,

+  IN UINT64  Arg5,

+  IN UINT64  Arg6,

+  IN UINT64  Arg7,

+  IN UINT64  Arg8

+  )

+{

+  //

+  // mSalProcEntry is initialized in library constructor as SAL entry.

+  //

+  return mSalProcEntry(

+           Index,

+           Arg2,

+           Arg3,

+           Arg4,

+           Arg5,

+           Arg6,

+           Arg7,

+           Arg8

+           );

+

+}

+

+/**

+  The constructor function of UEFI SAL Lib.

+

+  The constructor function looks up the SAL System Table in the EFI System Configuration

+  Table. Once the SAL System Table is found, the SAL Entry Point in the SAL System Table

+  will be derived and stored into a global variable for library usage.

+  It will ASSERT() if the SAL System Table cannot be found or the data in the SAL System

+  Table is not the valid data.

+

+  @param  ImageHandle   The firmware allocated handle for the EFI image.

+  @param  SystemTable   A pointer to the EFI System Table.

+

+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiSalLibConstructor (

+  IN EFI_HANDLE        ImageHandle,

+  IN EFI_SYSTEM_TABLE  *SystemTable

+  )

+{

+  EFI_STATUS                     Status;

+  SAL_ST_ENTRY_POINT_DESCRIPTOR  *SalStEntryDes;

+  SAL_SYSTEM_TABLE_HEADER        *SalSystemTable;

+

+  Status = EfiGetSystemConfigurationTable (

+             &gEfiSalSystemTableGuid,

+             (VOID **) &SalSystemTable

+             );

+  ASSERT_EFI_ERROR (Status);

+  ASSERT (SalSystemTable != NULL);

+

+  //

+  // Check the first entry of SAL System Table,

+  // because the SAL entry is in ascending order with the entry type,

+  // the type 0 entry should be the first if exist.

+  //

+  SalStEntryDes = (SAL_ST_ENTRY_POINT_DESCRIPTOR *)(SalSystemTable + 1);

+

+  //

+  // Assure the SAL ENTRY Type is 0

+  //

+  ASSERT (SalStEntryDes->Type == EFI_SAL_ST_ENTRY_POINT);

+

+  mPlabel.EntryPoint = SalStEntryDes->SalProcEntry;

+  mPlabel.GP = SalStEntryDes->SalGlobalDataPointer;

+  //

+  // Make sure the EntryPoint has the valid value

+  //

+  ASSERT ((mPlabel.EntryPoint != 0) && (mPlabel.GP != 0));

+

+  mSalProcEntry = (SAL_PROC)((UINT64)&(mPlabel.EntryPoint));

+

+  return EFI_SUCCESS;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.inf
new file mode 100644
index 0000000..bc25c53
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.inf
@@ -0,0 +1,47 @@
+## @file

+# UEFI Instance of SAL Library Class.

+#

+# This instance of SAL library retrieves the SAL Entry Point from the SAL System Table

+# register in the EFI System Confguration Table.

+#

+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiSalLib

+  MODULE_UNI_FILE                = UefiSalLib.uni

+  FILE_GUID                      = 4ABCFD77-4A33-4089-B003-5F09BCA940A2

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = SalLib|UEFI_DRIVER UEFI_APPLICATION

+

+  CONSTRUCTOR                    = UefiSalLibConstructor

+#

+# The following information is for reference only and not required by the build tools.

+#

+#  VALID_ARCHITECTURES           = IPF

+#

+

+[Sources]

+  UefiSalLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  UefiLib

+  DebugLib

+

+[Guids]

+  gEfiSalSystemTableGuid        ## CONSUMES ## SystemTable

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.uni
new file mode 100644
index 0000000..9ead3d6
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiSalLib/UefiSalLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.c
new file mode 100644
index 0000000..8a073db
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.c
@@ -0,0 +1,1164 @@
+/** @file

+  UEFI SCSI Library implementation

+

+  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         

+  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 <Uefi.h>

+#include <Library/BaseLib.h>

+#include <Library/DebugLib.h>

+#include <Library/UefiScsiLib.h>

+#include <Library/BaseMemoryLib.h>

+  

+#include <IndustryStandard/Scsi.h>

+  

+  

+  //

+  // Scsi Command Length

+  //

+#define EFI_SCSI_OP_LENGTH_SIX      0x6

+#define EFI_SCSI_OP_LENGTH_TEN      0xa

+#define EFI_SCSI_OP_LENGTH_SIXTEEN  0x10

+

+

+

+/**

+  Execute Test Unit Ready SCSI command on a specific SCSI target.

+

+  Executes the Test Unit Ready command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+

+

+  @param[in]     ScsiIo             A pointer to the SCSI I/O Protocol instance

+                                    for the specific SCSI target.

+  @param[in]     Timeout            The timeout in 100 ns units to use for the execution

+                                    of this SCSI Request Packet. A Timeout value of

+                                    zero means that this function will wait indefinitely

+                                    for the SCSI Request Packet to execute. If Timeout

+                                    is greater than zero, then this function will return

+                                    EFI_TIMEOUT if the time required to execute the SCSI

+                                    Request Packet is greater than Timeout.

+  @param[in, out] SenseData         A pointer to sense data that was generated by

+                                    the execution of the SCSI Request Packet. This

+                                    buffer must be allocated by the caller.

+                                    If SenseDataLength is 0, then this parameter is

+                                    optional and may be NULL.

+  @param[in, out] SenseDataLength   On input, a pointer to the length in bytes of

+                                    the SenseData buffer. On output, a pointer to

+                                    the number of bytes written to the SenseData buffer. 

+  @param[out]     HostAdapterStatus The status of the SCSI Host Controller that produces

+                                    the SCSI bus containing the SCSI target specified by

+                                    ScsiIo when the SCSI Request Packet was executed.

+                                    See the EFI SCSI I/O Protocol in the UEFI Specification

+                                    for details on the possible return values.

+  @param[out]     TargetStatus      The status returned by the SCSI target specified

+                                    by ScsiIo when the SCSI Request Packet was executed

+                                    on the SCSI Host Controller. See the EFI SCSI I/O

+                                    Protocol in the UEFI Specification for details on

+                                    the possible return values. 

+

+  @retval EFI_SUCCESS          The command was executed successfully.

+                               See HostAdapterStatus, TargetStatus, SenseDataLength,

+                               and SenseData in that order for additional status

+                               information.

+  @retval EFI_NOT_READY        The SCSI Request Packet could not be sent because

+                               there are too many SCSI Command Packets already

+                               queued. The SCSI Request Packet was not sent, so

+                               no additional status information is available.

+                               The caller may retry again later.

+  @retval EFI_DEVICE_ERROR     A device error occurred while attempting to send

+                               SCSI Request Packet.  See HostAdapterStatus,

+                               TargetStatus, SenseDataLength, and SenseData in that

+                               order for additional status information.

+  @retval EFI_UNSUPPORTED      The command described by the SCSI Request Packet

+                               is not supported by the SCSI initiator(i.e., SCSI

+                               Host Controller). The SCSI Request Packet was not

+                               sent, so no additional status information is available.

+  @retval EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request

+                               Packet to execute.  See HostAdapterStatus, TargetStatus,

+                               SenseDataLength, and SenseData in that order for

+                               additional status information.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiTestUnitReadyCommand (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,  OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_SIX];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = NULL;

+  CommandPacket.InTransferLength= 0;

+  CommandPacket.OutDataBuffer    = NULL;

+  CommandPacket.OutTransferLength= 0;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Test Unit Ready Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_TEST_UNIT_READY;

+  CommandPacket.CdbLength       = (UINT8) EFI_SCSI_OP_LENGTH_SIX;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Inquiry SCSI command on a specific SCSI target.

+

+  Executes the Inquiry command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If InquiryDataLength is NULL, then ASSERT().

+

+  @param[in]      ScsiIo                 A pointer to the SCSI I/O Protocol instance

+                                         for the specific SCSI target.

+  @param[in]      Timeout                The timeout in 100 ns units to use for the

+                                         execution of this SCSI Request Packet. A Timeout

+                                         value of zero means that this function will wait

+                                         indefinitely for the SCSI Request Packet to execute.

+                                         If Timeout is greater than zero, then this function

+                                         will return EFI_TIMEOUT if the time required to

+                                         execute the SCSI Request Packet is greater than Timeout.

+  @param[in, out] SenseData              A pointer to sense data that was generated

+                                         by the execution of the SCSI Request Packet.

+                                         This buffer must be allocated by the caller.

+                                         If SenseDataLength is 0, then this parameter

+                                         is optional and may be NULL.

+  @param[in, out] SenseDataLength        On input, the length in bytes of the SenseData buffer.

+                                         On output, the number of bytes written to the SenseData buffer. 

+  @param[out]     HostAdapterStatus      The status of the SCSI Host Controller that

+                                         produces the SCSI bus containing the SCSI

+                                         target specified by ScsiIo when the SCSI

+                                         Request Packet was executed.  See the EFI

+                                         SCSI I/O Protocol in the UEFI Specification

+                                         for details on the possible return values.

+  @param[out]     TargetStatus           The status returned by the SCSI target specified

+                                         by ScsiIo when the SCSI Request Packet was

+                                         executed on the SCSI Host Controller.

+                                         See the EFI SCSI I/O Protocol in the UEFI

+                                         Specification for details on the possible

+                                         return values. 

+  @param[in, out] InquiryDataBuffer      A pointer to inquiry data that was generated

+                                         by the execution of the SCSI Request Packet.

+                                         This buffer must be allocated by the caller.

+                                         If InquiryDataLength is 0, then this parameter

+                                         is optional and may be NULL. 

+  @param[in, out] InquiryDataLength      On input, a pointer to the length in bytes

+                                         of the InquiryDataBuffer buffer.

+                                         On output, a pointer to the number of bytes

+                                         written to the InquiryDataBuffer buffer.

+  @param[in]      EnableVitalProductData If TRUE, then the supported vital product

+                                         data for the PageCode is returned in InquiryDataBuffer.

+                                         If FALSE, then the standard inquiry data is

+                                         returned in InquiryDataBuffer and PageCode is ignored.

+  @param[in]      PageCode               The page code of the vital product data.

+                                         It's ignored if EnableVitalProductData is FALSE.

+

+  @retval EFI_SUCCESS          The command executed successfully. See HostAdapterStatus,

+                               TargetStatus, SenseDataLength, and SenseData in that order

+                               for additional status information.

+  @retval EFI_BAD_BUFFER_SIZE  The SCSI Request Packet was executed, but the entire

+                               InquiryDataBuffer could not be transferred. The actual

+                               number of bytes transferred is returned in InquiryDataLength.

+  @retval EFI_NOT_READY        The SCSI Request Packet could not be sent because there

+                               are too many SCSI Command Packets already queued.

+                               The SCSI Request Packet was not sent, so no additional

+                               status information is available. The caller may retry again later.

+  @retval EFI_DEVICE_ERROR     A device error occurred while attempting to send SCSI

+                               Request Packet.  See HostAdapterStatus, TargetStatus,

+                               SenseDataLength, and SenseData in that order for additional

+                               status information.

+  @retval EFI_UNSUPPORTED      The command described by the SCSI Request Packet is not

+                               supported by the SCSI initiator(i.e., SCSI  Host Controller).

+                               The SCSI Request Packet was not sent, so no additional

+                               status information is available.

+  @retval EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request

+                               Packet to execute.  See HostAdapterStatus, TargetStatus,

+                               SenseDataLength, and SenseData in that order for

+                               additional status information.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiInquiryCommandEx (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,  OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *InquiryDataBuffer,    OPTIONAL

+  IN OUT UINT32                *InquiryDataLength,

+  IN     BOOLEAN               EnableVitalProductData,

+  IN     UINT8                 PageCode

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_SIX];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (InquiryDataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = InquiryDataBuffer;

+  CommandPacket.InTransferLength= *InquiryDataLength;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+  CommandPacket.Cdb             = Cdb;

+

+  Cdb[0]  = EFI_SCSI_OP_INQUIRY;

+  if (EnableVitalProductData) {

+    Cdb[1] |= 0x01;

+    Cdb[2]  = PageCode;

+  }

+

+  if (*InquiryDataLength > 0xff) {

+    *InquiryDataLength = 0xff;

+  }

+

+  Cdb[4]                      = (UINT8) (*InquiryDataLength);

+  CommandPacket.CdbLength     = (UINT8) EFI_SCSI_OP_LENGTH_SIX;

+  CommandPacket.DataDirection = EFI_SCSI_DATA_IN;

+

+  Status                      = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus          = CommandPacket.HostAdapterStatus;

+  *TargetStatus               = CommandPacket.TargetStatus;

+  *SenseDataLength            = CommandPacket.SenseDataLength;

+  *InquiryDataLength          = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Inquiry SCSI command on a specific SCSI target.

+

+  Executes the Inquiry command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If InquiryDataLength is NULL, then ASSERT().

+

+  @param[in]      ScsiIo                 A pointer to the SCSI I/O Protocol instance

+                                         for the specific SCSI target.

+  @param[in]      Timeout                The timeout in 100 ns units to use for the

+                                         execution of this SCSI Request Packet. A Timeout

+                                         value of zero means that this function will wait

+                                         indefinitely for the SCSI Request Packet to execute.

+                                         If Timeout is greater than zero, then this function

+                                         will return EFI_TIMEOUT if the time required to

+                                         execute the SCSI Request Packet is greater than Timeout.

+  @param[in, out] SenseData              A pointer to sense data that was generated

+                                         by the execution of the SCSI Request Packet.

+                                         This buffer must be allocated by the caller.

+                                         If SenseDataLength is 0, then this parameter

+                                         is optional and may be NULL.

+  @param[in, out] SenseDataLength        On input, the length in bytes of the SenseData buffer.

+                                         On output, the number of bytes written to the SenseData buffer. 

+  @param[out]     HostAdapterStatus      The status of the SCSI Host Controller that

+                                         produces the SCSI bus containing the SCSI

+                                         target specified by ScsiIo when the SCSI

+                                         Request Packet was executed.  See the EFI

+                                         SCSI I/O Protocol in the UEFI Specification

+                                         for details on the possible return values.

+  @param[out]     TargetStatus           The status returned by the SCSI target specified

+                                         by ScsiIo when the SCSI Request Packet was

+                                         executed on the SCSI Host Controller.

+                                         See the EFI SCSI I/O Protocol in the UEFI

+                                         Specification for details on the possible

+                                         return values. 

+  @param[in, out] InquiryDataBuffer      A pointer to inquiry data that was generated

+                                         by the execution of the SCSI Request Packet.

+                                         This buffer must be allocated by the caller.

+                                         If InquiryDataLength is 0, then this parameter

+                                         is optional and may be NULL. 

+  @param[in, out] InquiryDataLength      On input, a pointer to the length in bytes

+                                         of the InquiryDataBuffer buffer.

+                                         On output, a pointer to the number of bytes

+                                         written to the InquiryDataBuffer buffer.

+  @param[in]      EnableVitalProductData If TRUE, then the supported vital product

+                                         data is returned in InquiryDataBuffer.

+                                         If FALSE, then the standard inquiry data is

+                                         returned in InquiryDataBuffer. 

+

+  @retval EFI_SUCCESS          The command executed successfully. See HostAdapterStatus,

+                               TargetStatus, SenseDataLength, and SenseData in that order

+                               for additional status information.

+  @retval EFI_BAD_BUFFER_SIZE  The SCSI Request Packet was executed, but the entire

+                               InquiryDataBuffer could not be transferred. The actual

+                               number of bytes transferred is returned in InquiryDataLength.

+  @retval EFI_NOT_READY        The SCSI Request Packet could not be sent because there

+                               are too many SCSI Command Packets already queued.

+                               The SCSI Request Packet was not sent, so no additional

+                               status information is available. The caller may retry again later.

+  @retval EFI_DEVICE_ERROR     A device error occurred while attempting to send SCSI

+                               Request Packet.  See HostAdapterStatus, TargetStatus,

+                               SenseDataLength, and SenseData in that order for additional

+                               status information.

+  @retval EFI_UNSUPPORTED      The command described by the SCSI Request Packet is not

+                               supported by the SCSI initiator(i.e., SCSI  Host Controller).

+                               The SCSI Request Packet was not sent, so no additional

+                               status information is available.

+  @retval EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request

+                               Packet to execute.  See HostAdapterStatus, TargetStatus,

+                               SenseDataLength, and SenseData in that order for

+                               additional status information.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiInquiryCommand (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,  OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *InquiryDataBuffer,    OPTIONAL

+  IN OUT UINT32                *InquiryDataLength,

+  IN     BOOLEAN               EnableVitalProductData

+  )

+{

+  return ScsiInquiryCommandEx (

+           ScsiIo,

+           Timeout,

+           SenseData,

+           SenseDataLength,

+           HostAdapterStatus,

+           TargetStatus,

+           InquiryDataBuffer,

+           InquiryDataLength,

+           EnableVitalProductData,

+           0

+           );

+}

+

+/**

+  Execute Mode Sense(10) SCSI command on a specific SCSI target.

+

+  Executes the SCSI Mode Sense(10) command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout

+  after Timeout 100 ns units.  The DBDField, PageControl, and PageCode parameters

+  are used to construct the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+

+  @param[in]      ScsiIo             A pointer to the SCSI I/O Protocol instance

+                                     for the specific SCSI target.

+  @param[in]      Timeout            The timeout in 100 ns units to use for the

+                                     execution of this SCSI Request Packet. A Timeout

+                                     value of zero means that this function will wait

+                                     indefinitely for the SCSI Request Packet to execute.

+                                     If Timeout is greater than zero, then this function

+                                     will return EFI_TIMEOUT if the time required to

+                                     execute the SCSI Request Packet is greater than Timeout.

+  @param[in, out]  SenseData         A pointer to sense data that was generated

+                                     by the execution of the SCSI Request Packet.

+                                     This buffer must be allocated by the caller.

+                                     If SenseDataLength is 0, then this parameter

+                                     is optional and may be NULL.

+  @param[in, out]  SenseDataLength   On input, the length in bytes of the SenseData buffer.

+                                     On output, the number of bytes written to the SenseData buffer. 

+  @param[out]     HostAdapterStatus  The status of the SCSI Host Controller that

+                                     produces the SCSI bus containing the SCSI target

+                                     specified by ScsiIo when the SCSI Request Packet

+                                     was executed. See the EFI SCSI I/O Protocol in the

+                                     UEFI Specification for details on the possible

+                                     return values.

+  @param[out]     TargetStatus       The status returned by the SCSI target specified

+                                     by ScsiIo when the SCSI Request Packet was executed

+                                     on the SCSI Host Controller.  See the EFI SCSI

+                                     I/O Protocol in the UEFI Specification for details

+                                     on the possible return values.

+  @param[in, out]  DataBuffer        A pointer to data that was generated by the

+                                     execution of the SCSI Request Packet.  This

+                                     buffer must be allocated by the caller. If

+                                     DataLength is 0, then this parameter is optional

+                                     and may be NULL. 

+  @param[in, out]  DataLength        On input, a pointer to the length in bytes of

+                                     the DataBuffer buffer.  On output, a pointer

+                                     to the number of bytes written to the DataBuffer

+                                     buffer. 

+  @param[in]      DBDField           Specifies the DBD field of the CDB for this SCSI Command.

+  @param[in]      PageControl        Specifies the PC field of the CDB for this SCSI Command. 

+  @param[in]      PageCode           Specifies the Page Control field of the CDB for this SCSI Command. 

+

+  @retval EFI_SUCCESS               The command executed successfully.

+                                    See HostAdapterStatus, TargetStatus, SenseDataLength,

+                                    and SenseData in that order for additional status information.

+  @retval EFI_BAD_BUFFER_SIZE       The SCSI Request Packet was executed, but the

+                                    entire DataBuffer could not be transferred.

+                                    The actual number of bytes transferred is returned

+                                    in DataLength.

+  @retval EFI_NOT_READY             The SCSI Request Packet could not be sent because

+                                    there are too many SCSI Command Packets already queued.

+                                    The SCSI Request Packet was not sent, so no additional

+                                    status information is available.  The caller may retry

+                                    again later.

+  @retval EFI_DEVICE_ERROR          A device error occurred while attempting to send

+                                    SCSI Request Packet.  See HostAdapterStatus, TargetStatus,

+                                    SenseDataLength, and SenseData in that order for

+                                    additional status information.

+  @retval EFI_UNSUPPORTED           The command described by the SCSI Request Packet

+                                    is not supported by the SCSI initiator(i.e., SCSI

+                                    Host Controller). The SCSI Request Packet was not

+                                    sent, so no additional status information is available.

+  @retval EFI_TIMEOUT               A timeout occurred while waiting for the SCSI

+                                    Request Packet to execute.  See HostAdapterStatus,

+                                    TargetStatus, SenseDataLength, and SenseData in that

+                                    order for additional status information.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiModeSense10Command (

+  IN     EFI_SCSI_IO_PROTOCOL    *ScsiIo,

+  IN     UINT64                  Timeout,

+  IN OUT VOID                    *SenseData,  OPTIONAL

+  IN OUT UINT8                   *SenseDataLength,

+     OUT UINT8                   *HostAdapterStatus,

+     OUT UINT8                   *TargetStatus,

+  IN OUT VOID                    *DataBuffer, OPTIONAL

+  IN OUT UINT32                  *DataLength,

+  IN     UINT8                   DBDField,    OPTIONAL

+  IN     UINT8                   PageControl,

+  IN     UINT8                   PageCode

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_TEN];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Mode Sense (10) Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_MODE_SEN10;

+  //

+  // DBDField is in Cdb[1] bit3 of (bit7..0)

+  //

+  Cdb[1]                        = (UINT8) ((DBDField << 3) & 0x08);

+  //

+  // PageControl is in Cdb[2] bit7..6, PageCode is in Cdb[2] bit5..0

+  //

+  Cdb[2]                        = (UINT8) (((PageControl << 6) & 0xc0) | (PageCode & 0x3f));

+  Cdb[7]                        = (UINT8) (*DataLength >> 8);

+  Cdb[8]                        = (UINT8) (*DataLength);

+

+  CommandPacket.CdbLength       = EFI_SCSI_OP_LENGTH_TEN;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Request Sense SCSI command on a specific SCSI target.

+

+  Executes the Request Sense command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after Timeout 100 ns units.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+

+  @param[in]       ScsiIo               A pointer to SCSI IO protocol.

+  @param[in]       Timeout              The length of timeout period.

+  @param[in, out]  SenseData            A pointer to output sense data.

+  @param[in, out]  SenseDataLength      The length of output sense data.

+  @param[out]      HostAdapterStatus    The status of Host Adapter.

+  @param[out]      TargetStatus         The status of the target.

+

+  @retval EFI_SUCCESS                   The command executed successfully.

+  @retval EFI_NOT_READY                 The SCSI Request Packet could not be sent because there are

+                                        too many SCSI Command Packets already queued.

+  @retval EFI_DEVICE_ERROR              A device error occurred while attempting to send SCSI Request Packet.

+  @retval EFI_UNSUPPORTED               The command described by the SCSI Request Packet is not supported by

+                                        the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval EFI_TIMEOUT                   A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiRequestSenseCommand (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,  OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_SIX];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIX);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = SenseData;

+  CommandPacket.SenseData       = NULL;

+  CommandPacket.InTransferLength= *SenseDataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Request Sense Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_REQUEST_SENSE;

+  Cdb[4]                        = (UINT8) (*SenseDataLength);

+

+  CommandPacket.CdbLength       = (UINT8) EFI_SCSI_OP_LENGTH_SIX;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = 0;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = (UINT8) CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Read Capacity SCSI command on a specific SCSI target.

+

+  Executes the SCSI Read Capacity command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after

+  Timeout 100 ns units.  The Pmi parameter is used to construct the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+  @param[in]      ScsiIo               A pointer to SCSI IO protocol.

+  @param[in]      Timeout              The length of timeout period.

+  @param[in, out] SenseData            A pointer to output sense data.

+  @param[in, out] SenseDataLength      The length of output sense data.

+  @param[out]     HostAdapterStatus    The status of Host Adapter.

+  @param[out]     TargetStatus         The status of the target.

+  @param[in, out] DataBuffer           A pointer to a data buffer.

+  @param[in, out] DataLength           The length of data buffer.

+  @param[in]      Pmi                  A partial medium indicator.

+

+  @retval  EFI_SUCCESS           The command executed successfully.

+  @retval  EFI_BAD_BUFFER_SIZE   The SCSI Request Packet was executed, but the entire

+                                 DataBuffer could not be transferred. The actual

+                                 number of bytes transferred is returned in DataLength.

+  @retval  EFI_NOT_READY         The SCSI Request Packet could not be sent because

+                                 there are too many SCSI Command Packets already queued.

+  @retval  EFI_DEVICE_ERROR      A device error occurred while attempting to send SCSI Request Packet.

+  @retval  EFI_UNSUPPORTED       The command described by the SCSI Request Packet

+                                 is not supported by the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval  EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiReadCapacityCommand (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,    OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *DataBuffer,   OPTIONAL

+  IN OUT UINT32                *DataLength,

+  IN     BOOLEAN               Pmi

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_TEN];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Read Capacity Command

+  //

+  Cdb[0]  = EFI_SCSI_OP_READ_CAPACITY;

+  if (!Pmi) {

+    //

+    // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.5 MUST BE ZERO.

+    //

+    ZeroMem ((Cdb + 2), 4);

+  } else {

+    Cdb[8] |= 0x01;

+  }

+

+  CommandPacket.CdbLength       = EFI_SCSI_OP_LENGTH_TEN;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Read Capacity SCSI 16 command on a specific SCSI target.

+

+  Executes the SCSI Read Capacity 16 command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after

+  Timeout 100 ns units.  The Pmi parameter is used to construct the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+  @param[in]      ScsiIo               A pointer to SCSI IO protocol.

+  @param[in]      Timeout              The length of timeout period.

+  @param[in, out] SenseData            A pointer to output sense data.

+  @param[in, out] SenseDataLength      The length of output sense data.

+  @param[out]     HostAdapterStatus    The status of Host Adapter.

+  @param[out]     TargetStatus         The status of the target.

+  @param[in, out] DataBuffer           A pointer to a data buffer.

+  @param[in, out] DataLength           The length of data buffer.

+  @param[in]      Pmi                  Partial medium indicator.

+

+  @retval  EFI_SUCCESS           The command executed successfully.

+  @retval  EFI_BAD_BUFFER_SIZE   The SCSI Request Packet was executed, but the entire

+                                 DataBuffer could not be transferred. The actual

+                                 number of bytes transferred is returned in DataLength.

+  @retval  EFI_NOT_READY         The SCSI Request Packet could not be sent because

+                                 there are too many SCSI Command Packets already queued.

+  @retval  EFI_DEVICE_ERROR      A device error occurred while attempting to send SCSI Request Packet.

+  @retval  EFI_UNSUPPORTED       The command described by the SCSI Request Packet

+                                 is not supported by the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval  EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiReadCapacity16Command (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,  OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *DataBuffer, OPTIONAL

+  IN OUT UINT32                *DataLength,

+  IN     BOOLEAN               Pmi

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[16];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, 16);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Read Capacity Command

+  //

+  Cdb[0]  = EFI_SCSI_OP_READ_CAPACITY16;

+  Cdb[1]  = 0x10;

+  if (!Pmi) {

+    //

+    // Partial medium indicator,if Pmi is FALSE, the Cdb.2 ~ Cdb.9 MUST BE ZERO.

+    //

+    ZeroMem ((Cdb + 2), 8);

+  } else {

+    Cdb[14] |= 0x01;

+  }

+

+  Cdb[13] = 0x20;

+  CommandPacket.CdbLength       = 16;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Read(10) SCSI command on a specific SCSI target.

+

+  Executes the SCSI Read(10) command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout

+  after Timeout 100 ns units.  The StartLba and SectorSize parameters are used to

+  construct the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+

+  @param[in]      ScsiIo               A pointer to SCSI IO protocol.

+  @param[in]      Timeout              The length of timeout period.

+  @param[in, out] SenseData            A pointer to output sense data.

+  @param[in, out] SenseDataLength      The length of output sense data.

+  @param[out]     HostAdapterStatus    The status of Host Adapter.

+  @param[out]     TargetStatus         The status of the target.

+  @param[in, out] DataBuffer           Read 10 command data.

+  @param[in, out] DataLength           The length of data buffer.

+  @param[in]      StartLba             The start address of LBA.

+  @param[in]      SectorSize           The number of contiguous logical blocks of data that shall be transferred.

+

+  @retval  EFI_SUCCESS          The command is executed successfully.

+  @retval  EFI_BAD_BUFFER_SIZE  The SCSI Request Packet was executed, but the entire DataBuffer could

+                                not be transferred. The actual number of bytes transferred is returned in DataLength.

+  @retval  EFI_NOT_READY        The SCSI Request Packet could not be sent because there are too many 

+                                SCSI Command Packets already queued.

+  @retval  EFI_DEVICE_ERROR     A device error occurred while attempting to send SCSI Request Packet.

+  @retval  EFI_UNSUPPORTED      The command described by the SCSI Request Packet is not supported by 

+                                the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval  EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiRead10Command (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,   OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *DataBuffer,  OPTIONAL

+  IN OUT UINT32                *DataLength,

+  IN     UINT32                StartLba,

+  IN     UINT32                SectorSize

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_TEN];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.InDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.InTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Read (10) Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_READ10;

+  WriteUnaligned32 ((UINT32 *)&Cdb[2], SwapBytes32 (StartLba));

+  WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 ((UINT16) SectorSize));

+

+  CommandPacket.CdbLength       = EFI_SCSI_OP_LENGTH_TEN;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Write(10) SCSI command on a specific SCSI target.

+

+  Executes the SCSI Write(10) command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after

+  Timeout 100 ns units.  The StartLba and SectorSize parameters are used to construct

+  the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+  @param[in]      ScsiIo               SCSI IO Protocol to use

+  @param[in]      Timeout              The length of timeout period.

+  @param[in, out] SenseData            A pointer to output sense data.

+  @param[in, out] SenseDataLength      The length of output sense data.

+  @param[out]     HostAdapterStatus    The status of Host Adapter.

+  @param[out]     TargetStatus         The status of the target.

+  @param[in, out] DataBuffer           A pointer to a data buffer.

+  @param[in, out] DataLength           The length of data buffer.

+  @param[in]      StartLba             The start address of LBA.

+  @param[in]      SectorSize           The number of contiguous logical blocks of data that shall be transferred.

+

+  @retval  EFI_SUCCESS          The command executed successfully.

+  @retval  EFI_BAD_BUFFER_SIZE  The SCSI Request Packet was executed, but the entire DataBuffer could

+                                not be transferred. The actual number of bytes transferred is returned in DataLength.

+  @retval  EFI_NOT_READY        The SCSI Request Packet could not be sent because there are too many 

+                                SCSI Command Packets already queued.

+  @retval  EFI_DEVICE_ERROR     A device error occurred while attempting to send SCSI Request Packet.

+  @retval  EFI_UNSUPPORTED      The command described by the SCSI Request Packet is not supported by 

+                                the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval  EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiWrite10Command (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,   OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *DataBuffer,  OPTIONAL

+  IN OUT UINT32                *DataLength,

+  IN     UINT32                StartLba,

+  IN     UINT32                SectorSize

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_TEN];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_TEN);

+

+  CommandPacket.Timeout         = Timeout;

+  CommandPacket.OutDataBuffer    = DataBuffer;

+  CommandPacket.SenseData       = SenseData;

+  CommandPacket.OutTransferLength= *DataLength;

+  CommandPacket.Cdb             = Cdb;

+  //

+  // Fill Cdb for Write (10) Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_WRITE10;

+  WriteUnaligned32 ((UINT32 *)&Cdb[2], SwapBytes32 (StartLba));

+  WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 ((UINT16) SectorSize));

+

+  CommandPacket.CdbLength       = EFI_SCSI_OP_LENGTH_TEN;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_OUT;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.OutTransferLength;

+

+  return Status;

+}

+

+/**

+  Execute Read(16) SCSI command on a specific SCSI target.

+

+  Executes the SCSI Read(16) command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout

+  after Timeout 100 ns units.  The StartLba and SectorSize parameters are used to

+  construct the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+

+  @param[in]      ScsiIo               A pointer to SCSI IO protocol.

+  @param[in]      Timeout              The length of timeout period.

+  @param[in, out] SenseData            A pointer to output sense data.

+  @param[in, out] SenseDataLength      The length of output sense data.

+  @param[out]     HostAdapterStatus    The status of Host Adapter.

+  @param[out]     TargetStatus         The status of the target.

+  @param[in, out] DataBuffer           Read 16 command data.

+  @param[in, out] DataLength           The length of data buffer.

+  @param[in]      StartLba             The start address of LBA.

+  @param[in]      SectorSize           The number of contiguous logical blocks of data that shall be transferred.

+

+  @retval  EFI_SUCCESS          The command executed successfully.

+  @retval  EFI_BAD_BUFFER_SIZE  The SCSI Request Packet was executed, but the entire DataBuffer could

+                                not be transferred. The actual number of bytes transferred is returned in DataLength.

+  @retval  EFI_NOT_READY        The SCSI Request Packet could not be sent because there are too many 

+                                SCSI Command Packets already queued.

+  @retval  EFI_DEVICE_ERROR     A device error occurred while attempting to send SCSI Request Packet.

+  @retval  EFI_UNSUPPORTED      The command described by the SCSI Request Packet is not supported by 

+                                the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval  EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiRead16Command (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,   OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *DataBuffer,  OPTIONAL

+  IN OUT UINT32                *DataLength,

+  IN     UINT64                StartLba,

+  IN     UINT32                SectorSize

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_SIXTEEN];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIXTEEN);

+

+  CommandPacket.Timeout          = Timeout;

+  CommandPacket.InDataBuffer     = DataBuffer;

+  CommandPacket.SenseData        = SenseData;

+  CommandPacket.InTransferLength = *DataLength;

+  CommandPacket.Cdb              = Cdb;

+  //

+  // Fill Cdb for Read (16) Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_READ16;

+  WriteUnaligned64 ((UINT64 *)&Cdb[2], SwapBytes64 (StartLba));

+  WriteUnaligned32 ((UINT32 *)&Cdb[10], SwapBytes32 (SectorSize));

+

+  CommandPacket.CdbLength       = EFI_SCSI_OP_LENGTH_SIXTEEN;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_IN;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.InTransferLength;

+

+  return Status;

+}

+

+

+/**

+  Execute Write(16) SCSI command on a specific SCSI target.

+

+  Executes the SCSI Write(16) command on the SCSI target specified by ScsiIo.

+  If Timeout is zero, then this function waits indefinitely for the command to complete.

+  If Timeout is greater than zero, then the command is executed and will timeout after

+  Timeout 100 ns units.  The StartLba and SectorSize parameters are used to construct

+  the CDB for this SCSI command.

+  If ScsiIo is NULL, then ASSERT().

+  If SenseDataLength is NULL, then ASSERT().

+  If HostAdapterStatus is NULL, then ASSERT().

+  If TargetStatus is NULL, then ASSERT().

+  If DataLength is NULL, then ASSERT().

+

+  @param[in]      ScsiIo               SCSI IO Protocol to use

+  @param[in]      Timeout              The length of timeout period.

+  @param[in, out] SenseData            A pointer to output sense data.

+  @param[in, out] SenseDataLength      The length of output sense data.

+  @param[out]     HostAdapterStatus    The status of Host Adapter.

+  @param[out]     TargetStatus         The status of the target.

+  @param[in, out] DataBuffer           A pointer to a data buffer.

+  @param[in, out] DataLength           The length of data buffer.

+  @param[in]      StartLba             The start address of LBA.

+  @param[in]      SectorSize           The number of contiguous logical blocks of data that shall be transferred.

+

+  @retval  EFI_SUCCESS          The command is executed successfully.

+  @retval  EFI_BAD_BUFFER_SIZE  The SCSI Request Packet was executed, but the entire DataBuffer could

+                                not be transferred. The actual number of bytes transferred is returned in DataLength.

+  @retval  EFI_NOT_READY        The SCSI Request Packet could not be sent because there are too many 

+                                SCSI Command Packets already queued.

+  @retval  EFI_DEVICE_ERROR     A device error occurred while attempting to send SCSI Request Packet.

+  @retval  EFI_UNSUPPORTED      The command described by the SCSI Request Packet is not supported by 

+                                the SCSI initiator(i.e., SCSI  Host Controller)

+  @retval  EFI_TIMEOUT          A timeout occurred while waiting for the SCSI Request Packet to execute.

+

+**/

+EFI_STATUS

+EFIAPI

+ScsiWrite16Command (

+  IN     EFI_SCSI_IO_PROTOCOL  *ScsiIo,

+  IN     UINT64                Timeout,

+  IN OUT VOID                  *SenseData,   OPTIONAL

+  IN OUT UINT8                 *SenseDataLength,

+     OUT UINT8                 *HostAdapterStatus,

+     OUT UINT8                 *TargetStatus,

+  IN OUT VOID                  *DataBuffer,  OPTIONAL

+  IN OUT UINT32                *DataLength,

+  IN     UINT64                StartLba,

+  IN     UINT32                SectorSize

+  )

+{

+  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;

+  EFI_STATUS                      Status;

+  UINT8                           Cdb[EFI_SCSI_OP_LENGTH_SIXTEEN];

+

+  ASSERT (SenseDataLength != NULL);

+  ASSERT (HostAdapterStatus != NULL);

+  ASSERT (TargetStatus != NULL);

+  ASSERT (DataLength != NULL);

+  ASSERT (ScsiIo != NULL);

+

+  ZeroMem (&CommandPacket, sizeof (EFI_SCSI_IO_SCSI_REQUEST_PACKET));

+  ZeroMem (Cdb, EFI_SCSI_OP_LENGTH_SIXTEEN);

+

+  CommandPacket.Timeout           = Timeout;

+  CommandPacket.OutDataBuffer     = DataBuffer;

+  CommandPacket.SenseData         = SenseData;

+  CommandPacket.OutTransferLength = *DataLength;

+  CommandPacket.Cdb               = Cdb;

+  //

+  // Fill Cdb for Write (16) Command

+  //

+  Cdb[0]                        = EFI_SCSI_OP_WRITE16;

+  WriteUnaligned64 ((UINT64 *)&Cdb[2], SwapBytes64 (StartLba));

+  WriteUnaligned32 ((UINT32 *)&Cdb[10], SwapBytes32 (SectorSize));

+

+  CommandPacket.CdbLength       = EFI_SCSI_OP_LENGTH_SIXTEEN;

+  CommandPacket.DataDirection   = EFI_SCSI_DATA_OUT;

+  CommandPacket.SenseDataLength = *SenseDataLength;

+

+  Status                        = ScsiIo->ExecuteScsiCommand (ScsiIo, &CommandPacket, NULL);

+

+  *HostAdapterStatus            = CommandPacket.HostAdapterStatus;

+  *TargetStatus                 = CommandPacket.TargetStatus;

+  *SenseDataLength              = CommandPacket.SenseDataLength;

+  *DataLength                   = CommandPacket.OutTransferLength;

+

+  return Status;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
new file mode 100644
index 0000000..1eb9076
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
@@ -0,0 +1,45 @@
+## @file

+# Uefi Scsi Library Instance.

+#

+# This libarary provides the functions to submit Scsi commands defined

+# in SCSI-2 specification for scsi device.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiScsiLib

+  MODULE_UNI_FILE                = UefiScsiLib.uni

+  FILE_GUID                      = 280E42C3-826E-4573-9772-B74EF1086D95

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiScsiLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  UefiScsiLib.c

+

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+

+[LibraryClasses]

+  BaseMemoryLib

+  DebugLib

+  BaseLib

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.uni
new file mode 100644
index 0000000..03c0ef2
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiScsiLib/UefiScsiLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/Hid.c b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/Hid.c
new file mode 100644
index 0000000..29d4e9d
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/Hid.c
@@ -0,0 +1,488 @@
+/** @file

+

+  The library provides USB HID Class standard and specific requests defined

+  in USB HID Firmware Specification 7 section : Requests.

+  

+  Copyright (c) 2004 - 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.

+

+**/

+

+#include "UefiUsbLibInternal.h"

+

+//  

+//  Hid RequestType Bits specifying characteristics of request.

+//  Valid values are 10100001b (0xa1) or 00100001b (0x21).

+//  The following description:

+//    7 Data transfer direction

+//        0 = Host to device

+//        1 = Device to host

+//    6..5 Type

+//        1 = Class

+//    4..0 Recipient

+//        1 = Interface

+//

+

+/**

+  Get the descriptor of the specified USB HID interface.

+

+  Submit a USB get HID descriptor request for the USB device specified by UsbIo

+  and Interface and return the HID descriptor in HidDescriptor.

+  If UsbIo is NULL, then ASSERT().

+  If HidDescriptor is NULL, then ASSERT().

+

+  @param  UsbIo          A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface      The index of the HID interface on the USB target.

+  @param  HidDescriptor  The pointer to the USB HID descriptor that was retrieved from

+                         the specified USB target and interface. Type EFI_USB_HID_DESCRIPTOR

+                         is defined in the MDE Package Industry Standard include file Usb.h.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetHidDescriptor (

+  IN  EFI_USB_IO_PROTOCOL        *UsbIo,

+  IN  UINT8                      Interface,

+  OUT EFI_USB_HID_DESCRIPTOR     *HidDescriptor

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT(UsbIo != NULL);

+  ASSERT(HidDescriptor != NULL);

+

+  Request.RequestType = USB_HID_GET_DESCRIPTOR_REQ_TYPE;

+  Request.Request     = USB_REQ_GET_DESCRIPTOR;

+  Request.Value       = (UINT16) (USB_DESC_TYPE_HID << 8);

+  Request.Index       = Interface;

+  Request.Length      = (UINT16) sizeof (EFI_USB_HID_DESCRIPTOR);

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    HidDescriptor,

+                    sizeof (EFI_USB_HID_DESCRIPTOR),

+                    &Status

+                    );

+

+  return Result;

+

+}

+

+/**

+  Get the report descriptor of the specified USB HID interface.

+

+  Submit a USB get HID report descriptor request for the USB device specified by

+  UsbIo and Interface and return the report descriptor in DescriptorBuffer.

+  If UsbIo is NULL, then ASSERT().

+  If DescriptorBuffer is NULL, then ASSERT().

+

+  @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface         The index of the report interface on the USB target.

+  @param  DescriptorLength  The size, in bytes, of DescriptorBuffer.

+  @param  DescriptorBuffer  A pointer to the buffer to store the report class descriptor.

+

+  @retval  EFI_SUCCESS           The request executed successfully.

+  @retval  EFI_OUT_OF_RESOURCES  The request could not be completed because the

+                                 buffer specified by DescriptorLength and DescriptorBuffer

+                                 is not large enough to hold the result of the request.

+  @retval  EFI_TIMEOUT           A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR      The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetReportDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Interface,

+  IN  UINT16                  DescriptorLength,

+  OUT UINT8                   *DescriptorBuffer

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (DescriptorBuffer != NULL);

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_GET_DESCRIPTOR_REQ_TYPE;

+  Request.Request     = USB_REQ_GET_DESCRIPTOR;

+  Request.Value       = (UINT16) (USB_DESC_TYPE_REPORT << 8);

+  Request.Index       = Interface;

+  Request.Length      = DescriptorLength;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    DescriptorBuffer,

+                    DescriptorLength,

+                    &Status

+                    );

+

+  return Result;

+

+}

+

+/**

+  Get the HID protocol of the specified USB HID interface.

+

+  Submit a USB get HID protocol request for the USB device specified by UsbIo

+  and Interface and return the protocol retrieved in Protocol.

+  If UsbIo is NULL, then ASSERT().

+  If Protocol is NULL, then ASSERT().

+

+  @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface  The index of the report interface on the USB target.

+  @param  Protocol   A pointer to the protocol for the specified USB target.

+

+  @retval  EFI_SUCCESS       The request executed successfully.

+  @retval  EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR  The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetProtocolRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  OUT UINT8                   *Protocol

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Protocol != NULL);

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_CLASS_GET_REQ_TYPE;

+  Request.Request = EFI_USB_GET_PROTOCOL_REQUEST;

+  Request.Value   = 0;

+  Request.Index   = Interface;

+  Request.Length  = 1;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    Protocol,

+                    sizeof (UINT8),

+                    &Status

+                    );

+

+  return Result;

+}

+

+

+

+/**

+  Set the HID protocol of the specified USB HID interface.

+

+  Submit a USB set HID protocol request for the USB device specified by UsbIo

+  and Interface and set the protocol to the value specified by Protocol.

+  If UsbIo is NULL, then ASSERT().

+

+  @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface  The index of the report interface on the USB target.

+  @param  Protocol   The protocol value to set for the specified USB target.

+

+  @retval  EFI_SUCCESS       The request executed successfully.

+  @retval  EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR  The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetProtocolRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   Protocol

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT (UsbIo != NULL);

+  

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_CLASS_SET_REQ_TYPE;

+  Request.Request = EFI_USB_SET_PROTOCOL_REQUEST;

+  Request.Value   = Protocol;

+  Request.Index   = Interface;

+  Request.Length  = 0;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbNoData,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    NULL,

+                    0,

+                    &Status

+                    );

+  return Result;

+}

+

+

+/**

+  Set the idle rate of the specified USB HID report.

+

+  Submit a USB set HID report idle request for the USB device specified by UsbIo,

+  Interface, and ReportId, and set the idle rate to the value specified by Duration.

+  If UsbIo is NULL, then ASSERT().

+

+  @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface  The index of the report interface on the USB target.

+  @param  ReportId   The identifier of the report to retrieve.

+  @param  Duration   The idle rate to set for the specified USB target.

+

+  @retval  EFI_SUCCESS       The request executed successfully.

+  @retval  EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR  The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetIdleRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   Duration

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT (UsbIo != NULL);

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_CLASS_SET_REQ_TYPE;

+  Request.Request = EFI_USB_SET_IDLE_REQUEST;

+  Request.Value   = (UINT16) ((Duration << 8) | ReportId);

+  Request.Index   = Interface;

+  Request.Length  = 0;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbNoData,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    NULL,

+                    0,

+                    &Status

+                    );

+  return Result;

+}

+

+

+/**

+  Get the idle rate of the specified USB HID report.

+

+  Submit a USB get HID report idle request for the USB device specified by UsbIo,

+  Interface, and ReportId, and return the ide rate in Duration.

+  If UsbIo is NULL, then ASSERT().

+  If Duration is NULL, then ASSERT().

+

+  @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface  The index of the report interface on the USB target.

+  @param  ReportId   The identifier of the report to retrieve.

+  @param  Duration   A pointer to the idle rate retrieved from the specified USB target.

+

+  @retval  EFI_SUCCESS       The request executed successfully.

+  @retval  EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR  The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetIdleRequest (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Interface,

+  IN  UINT8                   ReportId,

+  OUT UINT8                   *Duration

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+  

+  ASSERT (UsbIo != NULL);

+  ASSERT (Duration != NULL);

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_CLASS_GET_REQ_TYPE;

+  Request.Request = EFI_USB_GET_IDLE_REQUEST;

+  Request.Value   = ReportId;

+  Request.Index   = Interface;

+  Request.Length  = 1;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    Duration,

+                    1,

+                    &Status

+                    );

+

+  return Result;

+}

+

+

+

+/**

+  Set the report descriptor of the specified USB HID interface.

+

+  Submit a USB set HID report request for the USB device specified by UsbIo,

+  Interface, ReportId, and ReportType, and set the report descriptor using the

+  buffer specified by ReportLength and Report.

+  If UsbIo is NULL, then ASSERT().

+  If Report is NULL, then ASSERT().

+

+  @param  UsbIo         A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface     The index of the report interface on the USB target.

+  @param  ReportId      The identifier of the report to retrieve.

+  @param  ReportType    The type of report to retrieve.

+  @param  ReportLength  The size, in bytes, of Report.

+  @param  Report        A pointer to the report descriptor buffer to set.

+

+  @retval  EFI_SUCCESS       The request executed successfully.

+  @retval  EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR  The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetReportRequest (

+  IN EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN UINT8                   Interface,

+  IN UINT8                   ReportId,

+  IN UINT8                   ReportType,

+  IN UINT16                  ReportLen,

+  IN UINT8                   *Report

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Report != NULL);

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_CLASS_SET_REQ_TYPE;

+  Request.Request = EFI_USB_SET_REPORT_REQUEST;

+  Request.Value   = (UINT16) ((ReportType << 8) | ReportId);

+  Request.Index   = Interface;

+  Request.Length  = ReportLen;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataOut,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    Report,

+                    ReportLen,

+                    &Status

+                    );

+

+  return Result;

+}

+

+

+/**

+  Get the report descriptor of the specified USB HID interface.

+

+  Submit a USB get HID report request for the USB device specified by UsbIo,

+  Interface, ReportId, and ReportType, and return the report in the buffer

+  specified by Report.

+  If UsbIo is NULL, then ASSERT().

+  If Report is NULL, then ASSERT().

+

+  @param  UsbIo         A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface     The index of the report interface on the USB target.

+  @param  ReportId      The identifier of the report to retrieve.

+  @param  ReportType    The type of report to retrieve.

+  @param  ReportLength  The size, in bytes, of Report.

+  @param  Report        A pointer to the buffer to store the report descriptor.

+

+  @retval  EFI_SUCCESS           The request executed successfully.

+  @retval  EFI_OUT_OF_RESOURCES  The request could not be completed because the

+                                 buffer specified by ReportLength and Report is not

+                                 large enough to hold the result of the request.

+  @retval  EFI_TIMEOUT           A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR      The request failed due to a device error.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetReportRequest (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Interface,

+  IN  UINT8                   ReportId,

+  IN  UINT8                   ReportType,

+  IN  UINT16                  ReportLen,

+  OUT UINT8                   *Report

+  )

+{

+  UINT32                  Status;

+  EFI_STATUS              Result;

+  EFI_USB_DEVICE_REQUEST  Request;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Report != NULL);

+

+  //

+  // Fill Device request packet

+  //

+  Request.RequestType = USB_HID_CLASS_GET_REQ_TYPE;

+  Request.Request = EFI_USB_GET_REPORT_REQUEST;

+  Request.Value   = (UINT16) ((ReportType << 8) | ReportId);

+  Request.Index   = Interface;

+  Request.Length  = ReportLen;

+

+  Result = UsbIo->UsbControlTransfer (

+                    UsbIo,

+                    &Request,

+                    EfiUsbDataIn,

+                    PcdGet32 (PcdUsbTransferTimeoutValue),

+                    Report,

+                    ReportLen,

+                    &Status

+                    );

+

+  return Result;

+}

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
new file mode 100644
index 0000000..33062fd
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
@@ -0,0 +1,48 @@
+## @file

+# Uefi Usb Library instance.

+#

+# This library instance provides most usb APIs to support the Hid requests defined in

+# Usb Hid 1.1 spec and the standard requests defined in Usb 1.1 spec.

+#

+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>

+#

+#  This program and the accompanying materials

+#  are licensed and made available under the terms and conditions of the BSD License

+#  which accompanies this distribution. The full text of the license may be found at

+#  http://opensource.org/licenses/bsd-license.php.

+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+#

+#

+##

+

+[Defines]

+  INF_VERSION                    = 0x00010005

+  BASE_NAME                      = UefiUsbLib

+  MODULE_UNI_FILE                = UefiUsbLib.uni

+  FILE_GUID                      = 87eb5df9-722a-4241-ad7f-370d0b3a56d7

+  MODULE_TYPE                    = UEFI_DRIVER

+  VERSION_STRING                 = 1.0

+  LIBRARY_CLASS                  = UefiUsbLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER

+

+

+#

+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC

+#

+

+[Sources]

+  UefiUsbLibInternal.h

+  Hid.c

+  UsbDxeLib.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+

+[LibraryClasses]

+  DebugLib

+  BaseMemoryLib

+  PcdLib

+

+[Pcd]

+  gEfiMdePkgTokenSpaceGuid.PcdUsbTransferTimeoutValue  ## CONSUMES

+

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLib.uni b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLib.uni
new file mode 100644
index 0000000..6e99cae
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLib.uni
Binary files differ
diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h
new file mode 100644
index 0000000..cbd296e
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UefiUsbLibInternal.h
@@ -0,0 +1,29 @@
+/** @file

+  

+  Common header file shared by all source files.

+

+  This file includes package header files, library classes and protocol, PPI & GUID definitions.

+

+  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_USB_LIB_INTERNAL_H_

+#define _UEFI_USB_LIB_INTERNAL_H_

+

+#include <Uefi.h>

+

+#include <Library/UefiUsbLib.h>

+#include <Library/BaseMemoryLib.h>

+#include <Library/DebugLib.h>

+#include <Library/PcdLib.h>

+

+#include <IndustryStandard/Usb.h>

+

+

+#endif

diff --git a/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UsbDxeLib.c b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
new file mode 100644
index 0000000..b22a829
--- /dev/null
+++ b/uefi/linaro-edk2/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
@@ -0,0 +1,672 @@
+/** @file

+

+  The library provides the USB Standard Device Requests defined 

+  in Usb specification 9.4 section.

+  

+  Copyright (c) 2004 - 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.

+

+**/

+

+#include "UefiUsbLibInternal.h"

+

+

+/**

+  Get the descriptor of the specified USB device.

+

+  Submit a USB get descriptor request for the USB device specified by UsbIo, Value,

+  and Index, and return the descriptor in the buffer specified by Descriptor.

+  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Descriptor is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Value             The device request value.

+  @param  Index             The device request index.

+  @param  DescriptorLength  The size, in bytes, of Descriptor.

+  @param  Descriptor        A pointer to the descriptor buffer to get.

+  @param  Status            A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS           The request executed successfully.

+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed because the

+                                buffer specified by DescriptorLength and Descriptor

+                                is not large enough to hold the result of the request.

+  @retval EFI_TIMEOUT           A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR      The request failed due to a device error. The transfer

+                                status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  IN  UINT16                  Index,

+  IN  UINT16                  DescriptorLength,

+  OUT VOID                    *Descriptor,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Descriptor != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;

+  DevReq.Request      = USB_REQ_GET_DESCRIPTOR;

+  DevReq.Value        = Value;

+  DevReq.Index        = Index;

+  DevReq.Length       = DescriptorLength;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  Descriptor,

+                  DescriptorLength,

+                  Status

+                  );

+}

+

+

+/**

+  Set the descriptor of the specified USB device.

+

+  Submit a USB set descriptor request for the USB device specified by UsbIo,

+  Value, and Index, and set the descriptor using the buffer specified by DesriptorLength

+  and Descriptor.  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Descriptor is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Value             The device request value.

+  @param  Index             The device request index.

+  @param  DescriptorLength  The size, in bytes, of Descriptor.

+  @param  Descriptor        A pointer to the descriptor buffer to set.

+  @param  Status            A pointer to the status of the transfer.

+

+  @retval  EFI_SUCCESS       The request executed successfully.

+  @retval  EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval  EFI_DEVICE_ERROR  The request failed due to a device error.

+                             The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetDescriptor (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Value,

+  IN  UINT16                  Index,

+  IN  UINT16                  DescriptorLength,

+  IN  VOID                    *Descriptor,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Descriptor != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;

+  DevReq.Request      = USB_REQ_SET_DESCRIPTOR;

+  DevReq.Value        = Value;

+  DevReq.Index        = Index;

+  DevReq.Length       = DescriptorLength;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataOut,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  Descriptor,

+                  DescriptorLength,

+                  Status

+                  );

+}

+

+

+/**

+  Get the interface setting of the specified USB device.

+

+  Submit a USB get interface request for the USB device specified by UsbIo,

+  and Interface, and place the result in the buffer specified by AlternateSetting.

+  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If AlternateSetting is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface         The interface index value.

+  @param  AlternateSetting  A pointer to the alternate setting to be retrieved.

+  @param  Status            A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+                            The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetInterface (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Interface,

+  OUT UINT16                  *AlternateSetting,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (AlternateSetting != NULL);

+  ASSERT (Status != NULL);

+

+  *AlternateSetting = 0;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_GET_INTERFACE_REQ_TYPE;

+  DevReq.Request      = USB_REQ_GET_INTERFACE;

+  DevReq.Index        = Interface;

+  DevReq.Length       = 1;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  AlternateSetting,

+                  1,

+                  Status

+                  );

+}

+

+

+/**

+  Set the interface setting of the specified USB device.

+

+  Submit a USB set interface request for the USB device specified by UsbIo, and

+  Interface, and set the alternate setting to the value specified by AlternateSetting.

+  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Interface         The interface index value.

+  @param  AlternateSetting  The alternate setting to be set.

+  @param  Status            A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS  The request executed successfully.

+  @retval EFI_TIMEOUT  A timeout occurred executing the request.

+  @retval EFI_SUCCESS  The request failed due to a device error.

+                       The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetInterface (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  Interface,

+  IN  UINT16                  AlternateSetting,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_INTERFACE_REQ_TYPE;

+  DevReq.Request      = USB_REQ_SET_INTERFACE;

+  DevReq.Value        = AlternateSetting;

+  DevReq.Index        = Interface;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+

+

+/**

+  Get the device configuration.

+

+  Submit a USB get configuration request for the USB device specified by UsbIo

+  and place the result in the buffer specified by ConfigurationValue. The status

+  of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If ConfigurationValue is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo               A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  ConfigurationValue  A pointer to the device configuration to be retrieved.

+  @param  Status              A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS        The request executed successfully.

+  @retval EFI_TIMEOUT        A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR   The request failed due to a device error.

+                             The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetConfiguration (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  OUT UINT16                  *ConfigurationValue,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (ConfigurationValue != NULL);

+  ASSERT (Status != NULL);

+

+  *ConfigurationValue = 0;

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_GET_CONFIGURATION_REQ_TYPE;

+  DevReq.Request      = USB_REQ_GET_CONFIG;

+  DevReq.Length       = 1;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  ConfigurationValue,

+                  1,

+                  Status

+                  );

+}

+

+

+/**

+  Set the device configuration.

+

+  Submit a USB set configuration request for the USB device specified by UsbIo

+  and set the device configuration to the value specified by ConfigurationValue.

+  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo               A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  ConfigurationValue  The device configuration value to be set.

+  @param  Status              A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+                            The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetConfiguration (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT16                  ConfigurationValue,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  DevReq.RequestType  = USB_DEV_SET_CONFIGURATION_REQ_TYPE;

+  DevReq.Request      = USB_REQ_SET_CONFIG;

+  DevReq.Value        = ConfigurationValue;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+

+

+/**

+  Set the specified feature of the specified device.

+

+  Submit a USB set device feature request for the USB device specified by UsbIo,

+  Recipient, and Target to the value specified by Value.  The status of the

+  transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Recipient  The USB data recipient type (i.e. Device, Interface, Endpoint).

+                     Type USB_TYPES_DEFINITION is defined in the MDE Package Industry

+                     Standard include file Usb.h.

+  @param  Value      The value of the feature to be set.

+  @param  Target     The index of the device to be set.

+  @param  Status     A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+                            The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbSetFeature (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  USB_TYPES_DEFINITION    Recipient,

+  IN  UINT16                  Value,

+  IN  UINT16                  Target,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  switch (Recipient) {

+

+  case USB_TARGET_DEVICE:

+    DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_D;

+    break;

+

+  case USB_TARGET_INTERFACE:

+    DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_I;

+    break;

+

+  case USB_TARGET_ENDPOINT:

+    DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_E;

+    break;

+

+  default:

+    break;

+  }

+  //

+  // Fill device request, see USB1.1 spec

+  //

+  DevReq.Request  = USB_REQ_SET_FEATURE;

+  DevReq.Value    = Value;

+  DevReq.Index    = Target;

+

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+

+

+/**

+  Clear the specified feature of the specified device.

+

+  Submit a USB clear device feature request for the USB device specified by UsbIo,

+  Recipient, and Target to the value specified by Value.  The status of the transfer

+  is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Recipient  The USB data recipient type (i.e. Device, Interface, Endpoint).

+                     Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard

+                     include file Usb.h.

+  @param  Value      The value of the feature to be cleared.

+  @param  Target     The index of the device to be cleared.

+  @param  Status     A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+                            The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbClearFeature (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  USB_TYPES_DEFINITION    Recipient,

+  IN  UINT16                  Value,

+  IN  UINT16                  Target,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Status != NULL);

+

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  switch (Recipient) {

+

+  case USB_TARGET_DEVICE:

+    DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;

+    break;

+

+  case USB_TARGET_INTERFACE:

+    DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;

+    break;

+

+  case USB_TARGET_ENDPOINT:

+    DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;

+    break;

+

+  default:

+    break;

+  }

+  //

+  // Fill device request, see USB1.1 spec

+  //

+  DevReq.Request  = USB_REQ_CLEAR_FEATURE;

+  DevReq.Value    = Value;

+  DevReq.Index    = Target;

+

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbNoData,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  NULL,

+                  0,

+                  Status

+                  );

+}

+

+

+/**

+  Get the status of the specified device.

+

+  Submit a USB device get status request for the USB device specified by UsbIo,

+  Recipient, and Target and place the result in the buffer specified by DeviceStatus.

+  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If DeviceStatus is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo         A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Recipient     The USB data recipient type (i.e. Device, Interface, Endpoint).

+                        Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard

+                        include file Usb.h.

+  @param  Target        The index of the device to be get the status of.

+  @param  DeviceStatus  A pointer to the device status to be retrieved.

+  @param  Status        A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+                            The transfer status is returned in Status.

+

+**/

+EFI_STATUS

+EFIAPI

+UsbGetStatus (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  USB_TYPES_DEFINITION    Recipient,

+  IN  UINT16                  Target,

+  OUT UINT16                  *DeviceStatus,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_USB_DEVICE_REQUEST  DevReq;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (DeviceStatus != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));

+

+  switch (Recipient) {

+

+  case USB_TARGET_DEVICE:

+    DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_D;

+    break;

+

+  case USB_TARGET_INTERFACE:

+    DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_I;

+    break;

+

+  case USB_TARGET_ENDPOINT:

+    DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_E;

+    break;

+

+  default:

+    break;

+  }

+  //

+  // Fill device request, see USB1.1 spec

+  //

+  DevReq.Request  = USB_REQ_GET_STATUS;

+  DevReq.Value    = 0;

+  DevReq.Index    = Target;

+  DevReq.Length   = 2;

+

+  return UsbIo->UsbControlTransfer (

+                  UsbIo,

+                  &DevReq,

+                  EfiUsbDataIn,

+                  PcdGet32 (PcdUsbTransferTimeoutValue),

+                  DeviceStatus,

+                  2,

+                  Status

+                  );

+}

+

+

+/**

+  Clear halt feature of the specified usb endpoint.

+

+  Retrieve the USB endpoint descriptor specified by UsbIo and EndPoint.

+  If the USB endpoint descriptor can not be retrieved, then return EFI_NOT_FOUND.

+  If the endpoint descriptor is found, then clear the halt feature of this USB endpoint.

+  The status of the transfer is returned in Status.

+  If UsbIo is NULL, then ASSERT().

+  If Status is NULL, then ASSERT().

+

+  @param  UsbIo     A pointer to the USB I/O Protocol instance for the specific USB target.

+  @param  Endpoint  The endpoint address.

+  @param  Status    A pointer to the status of the transfer.

+

+  @retval EFI_SUCCESS       The request executed successfully.

+  @retval EFI_TIMEOUT       A timeout occurred executing the request.

+  @retval EFI_DEVICE_ERROR  The request failed due to a device error.

+                            The transfer status is returned in Status.

+  @retval EFI_NOT_FOUND     The specified USB endpoint descriptor can not be found

+

+**/

+EFI_STATUS

+EFIAPI

+UsbClearEndpointHalt (

+  IN  EFI_USB_IO_PROTOCOL     *UsbIo,

+  IN  UINT8                   Endpoint,

+  OUT UINT32                  *Status

+  )

+{

+  EFI_STATUS                    Result;

+  EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;

+  EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;

+  UINT8                         Index;

+

+  ASSERT (UsbIo != NULL);

+  ASSERT (Status != NULL);

+

+  ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));

+  //

+  // First seach the endpoint descriptor for that endpoint addr

+  //

+  Result = UsbIo->UsbGetInterfaceDescriptor (

+                    UsbIo,

+                    &InterfaceDescriptor

+                    );

+  if (EFI_ERROR (Result)) {

+    return Result;

+  }

+

+  for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {

+    Result = UsbIo->UsbGetEndpointDescriptor (

+                      UsbIo,

+                      Index,

+                      &EndpointDescriptor

+                      );

+    if (EFI_ERROR (Result)) {

+      continue;

+    }

+

+    if (EndpointDescriptor.EndpointAddress == Endpoint) {

+      break;

+    }

+  }

+

+  if (Index == InterfaceDescriptor.NumEndpoints) {

+    //

+    // No such endpoint

+    //

+    return EFI_NOT_FOUND;

+  }

+

+  Result = UsbClearFeature (

+            UsbIo,

+            USB_TARGET_ENDPOINT,

+            USB_FEATURE_ENDPOINT_HALT,

+            EndpointDescriptor.EndpointAddress,

+            Status

+            );

+

+  return Result;

+}