To address these issues this patch introduces
BaseMemoryLibMmio library which provides an
implementation of Base memory library that
uses aligned MMIO accesses.
Signed-off-by: Sami Mujawar <sami.muja...@arm.com>
---
MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.inf | 50 ++++
MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.uni | 15 +
MdePkg/Library/BaseMemoryLibMmio/CompareMemWrapper.c | 62 ++++
MdePkg/Library/BaseMemoryLibMmio/CopyMem.c | 149 ++++++++++
MdePkg/Library/BaseMemoryLibMmio/CopyMemWrapper.c | 59 ++++
MdePkg/Library/BaseMemoryLibMmio/IsZeroBufferWrapper.c | 50 ++++
MdePkg/Library/BaseMemoryLibMmio/MemLibGeneric.c | 304
++++++++++++++++++++
MdePkg/Library/BaseMemoryLibMmio/MemLibGuid.c | 143 +++++++++
MdePkg/Library/BaseMemoryLibMmio/MemLibInternals.h | 248 ++++++++++++++++
MdePkg/Library/BaseMemoryLibMmio/ScanMem16Wrapper.c | 63 ++++
MdePkg/Library/BaseMemoryLibMmio/ScanMem32Wrapper.c | 62 ++++
MdePkg/Library/BaseMemoryLibMmio/ScanMem64Wrapper.c | 63 ++++
MdePkg/Library/BaseMemoryLibMmio/ScanMem8Wrapper.c | 95 ++++++
MdePkg/Library/BaseMemoryLibMmio/SetMem.c | 83 ++++++
MdePkg/Library/BaseMemoryLibMmio/SetMem16Wrapper.c | 60 ++++
MdePkg/Library/BaseMemoryLibMmio/SetMem32Wrapper.c | 60 ++++
MdePkg/Library/BaseMemoryLibMmio/SetMem64Wrapper.c | 60 ++++
MdePkg/Library/BaseMemoryLibMmio/SetMemWrapper.c | 87 ++++++
MdePkg/Library/BaseMemoryLibMmio/ZeroMemWrapper.c | 52 ++++
19 files changed, 1765 insertions(+)
diff --git a/MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.inf
b/MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.inf
new file mode 100644
index
0000000000000000000000000000000000000000..3a61cb985a242a4ce7a2446c4efb9b78fb1d7b5d
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.inf
@@ -0,0 +1,50 @@
+## @file
+# Instance of Base Memory Library using Mmio operations.
+#
+#
+# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = BaseMemoryLibMmio
+ MODULE_UNI_FILE = BaseMemoryLibMmio.uni
+ FILE_GUID = 5724063D-9855-4B3A-8DEE-1F80ED07E096
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BaseMemoryLib
+
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+
+[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
+ IsZeroBufferWrapper.c
+ MemLibGeneric.c
+ MemLibGuid.c
+ CopyMem.c
+ MemLibInternals.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+ IoLib
+
diff --git a/MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.uni
b/MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.uni
new file mode 100644
index
0000000000000000000000000000000000000000..3dc99103e9a673902abcefe824d5cf5c19b258b8
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/BaseMemoryLibMmio.uni
@@ -0,0 +1,15 @@
+// /** @file
+// Instance of Base Memory Library using Mmio operations.
+//
+//
+// Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Instance of Base Memory
Library using Mmio operations"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Base Memory Library using
Mmio operations"
+
diff --git a/MdePkg/Library/BaseMemoryLibMmio/CompareMemWrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/CompareMemWrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..63e0e3ea583cb242a9242f483e8c952e48122e77
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/CompareMemWrapper.c
@@ -0,0 +1,62 @@
+/** @file
+ CompareMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/CopyMem.c
b/MdePkg/Library/BaseMemoryLibMmio/CopyMem.c
new file mode 100644
index
0000000000000000000000000000000000000000..84a207bf0f8a537b0832b5c4c9f6735122ee7851
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/CopyMem.c
@@ -0,0 +1,149 @@
+/** @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 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 2020, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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;
+ volatile UINT32 *Destination32;
+ CONST UINT32 *Source32;
+ volatile UINT64 *Destination64;
+ CONST UINT64 *Source64;
+ UINTN Alignment;
+
+ if ((((UINTN)DestinationBuffer & 0x7) == 0) &&
+ (((UINTN)SourceBuffer & 0x7) == 0) &&
+ (Length >= 8)) {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination64 = (UINT64*)DestinationBuffer;
+ Source64 = (CONST UINT64*)SourceBuffer;
+ while (Length >= 8) {
+ MmioWrite64 ((UINTN)Destination64++, MmioRead64 ((UINTN)Source64++));
+ Length -= 8;
+ }
+
+ // Finish if there are still some bytes to copy
+ Destination8 = (UINT8*)Destination64;
+ Source8 = (CONST UINT8*)Source64;
+ while (Length-- != 0) {
+ MmioWrite8 ((UINTN)Destination8++, MmioRead8 ((UINTN)Source8++));
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);
+ Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);
+
+ // Destination64 and Source64 were aligned on a 64-bit boundary
+ // but if length is not a multiple of 8 bytes then they won't be
+ // anymore.
+
+ Alignment = Length & 0x7;
+ if (Alignment != 0) {
+ Destination8 = (UINT8*)Destination64;
+ Source8 = (CONST UINT8*)Source64;
+
+ while (Alignment-- != 0) {
+ MmioWrite8 ((UINTN)--Destination8, MmioRead8 ((UINTN)--Source8));
+ --Length;
+ }
+ Destination64 = (UINT64*)Destination8;
+ Source64 = (CONST UINT64*)Source8;
+ }
+
+ while (Length > 0) {
+ MmioWrite64 ((UINTN)--Destination64, MmioRead64 ((UINTN)--Source64));
+ Length -= 8;
+ }
+ }
+ } else if ((((UINTN)DestinationBuffer & 0x3) == 0) &&
+ (((UINTN)SourceBuffer & 0x3) == 0) &&
+ (Length >= 4)) {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination32 = (UINT32*)DestinationBuffer;
+ Source32 = (CONST UINT32*)SourceBuffer;
+ while (Length >= 4) {
+ MmioWrite32 ((UINTN)Destination32++, MmioRead32 ((UINTN)Source32++));
+ Length -= 4;
+ }
+
+ // Finish if there are still some bytes to copy
+ Destination8 = (UINT8*)Destination32;
+ Source8 = (CONST UINT8*)Source32;
+ while (Length-- != 0) {
+ MmioWrite8 ((UINTN)Destination8++, MmioRead8 ((UINTN)Source8++));
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);
+ Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);
+
+ // Destination32 and Source32 were aligned on a 32-bit boundary
+ // but if length is not a multiple of 4 bytes then they won't be
+ // anymore.
+
+ Alignment = Length & 0x3;
+ if (Alignment != 0) {
+ Destination8 = (UINT8*)Destination32;
+ Source8 = (CONST UINT8*)Source32;
+
+ while (Alignment-- != 0) {
+ MmioWrite8 ((UINTN)--Destination8, MmioRead8 ((UINTN)--Source8));
+ --Length;
+ }
+ Destination32 = (UINT32*)Destination8;
+ Source32 = (CONST UINT32*)Source8;
+ }
+
+ while (Length > 0) {
+ MmioWrite32 ((UINTN)--Destination32, MmioRead32 ((UINTN)--Source32));
+ Length -= 4;
+ }
+ }
+ } else {
+ if (SourceBuffer > DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer;
+ Source8 = (CONST UINT8*)SourceBuffer;
+ while (Length-- != 0) {
+ MmioWrite8 ((UINTN)Destination8++, MmioRead8 ((UINTN)Source8++));
+ }
+ } else if (SourceBuffer < DestinationBuffer) {
+ Destination8 = (UINT8*)DestinationBuffer + (Length - 1);
+ Source8 = (CONST UINT8*)SourceBuffer + (Length - 1);
+ while (Length-- != 0) {
+ MmioWrite8 ((UINTN)Destination8--, MmioRead8 ((UINTN)Source8--));
+ }
+ }
+ }
+ return DestinationBuffer;
+}
diff --git a/MdePkg/Library/BaseMemoryLibMmio/CopyMemWrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/CopyMemWrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..d557bbb8904c2b07c644261290a62be6fc831c08
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/CopyMemWrapper.c
@@ -0,0 +1,59 @@
+/** @file
+ CopyMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/IsZeroBufferWrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/IsZeroBufferWrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..9c3133c668c434839b0d9bf105bc7265eeb76a5b
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/IsZeroBufferWrapper.c
@@ -0,0 +1,50 @@
+/** @file
+ Implementation of IsZeroBuffer function.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Checks if the contents of a buffer are all zeros.
+
+ This function checks whether the contents of a buffer are all zeros. If the
+ contents are all zeros, return TRUE. Otherwise, return FALSE.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ @param Buffer The pointer to the buffer to be checked.
+ @param Length The size of the buffer (in bytes) to be checked.
+
+ @retval TRUE Contents of the buffer are all zeros.
+ @retval FALSE Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroBuffer (
+ IN CONST VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ ASSERT (!(Buffer == NULL && Length > 0));
+ ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN)Buffer));
+ return InternalMemIsZeroBuffer (Buffer, Length);
+}
diff --git a/MdePkg/Library/BaseMemoryLibMmio/MemLibGeneric.c
b/MdePkg/Library/BaseMemoryLibMmio/MemLibGeneric.c
new file mode 100644
index
0000000000000000000000000000000000000000..1c65b674230795e956c9d22f2b9c151c41839706
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/MemLibGeneric.c
@@ -0,0 +1,304 @@
+/** @file
+ Architecture Independent Base Memory Library Implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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
+ )
+{
+ volatile UINT16 *Destination16;
+
+ Destination16 = (UINT16*)Buffer;
+ while (Length > 0) {
+ MmioWrite16 ((UINTN)--Destination16, Value);
+ Length -= 2;
+ }
+
+ 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
+ )
+{
+ volatile UINT32 *Destination32;
+
+ Destination32 = (UINT32*)Buffer;
+ while (Length > 0) {
+ MmioWrite32 ((UINTN)--Destination32, Value);
+ Length -= 4;
+ }
+ 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
+ )
+{
+ volatile UINT64 *Destination64;
+
+ Destination64 = (UINT64*)Buffer;
+ while (Length > 0) {
+ MmioWrite64 ((UINTN)--Destination64, Value);
+ Length -= 8;
+ }
+ 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) &&
+ (MmioRead8 ((UINTN)DestinationBuffer) ==
+ MmioRead8 ((UINTN)SourceBuffer))) {
+ DestinationBuffer = (INT8*)DestinationBuffer + 1;
+ SourceBuffer = (INT8*)SourceBuffer + 1;
+ }
+ return (INTN)MmioRead8 ((UINTN)DestinationBuffer) -
+ (INTN)MmioRead8 ((UINTN)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 (MmioRead8 ((UINTN)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 (MmioRead16 ((UINTN)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 (MmioRead32 ((UINTN)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 (MmioRead64 ((UINTN)Pointer) == Value) {
+ return Pointer;
+ }
+ ++Pointer;
+ } while (--Length != 0);
+ return NULL;
+}
+
+/**
+ Checks whether the contents of a buffer are all zeros.
+
+ @param Buffer The pointer to the buffer to be checked.
+ @param Length The size of the buffer (in bytes) to be checked.
+
+ @retval TRUE Contents of the buffer are all zeros.
+ @retval FALSE Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+InternalMemIsZeroBuffer (
+ IN CONST VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ CONST UINT8 *BufferData;
+ UINTN Index;
+
+ BufferData = Buffer;
+ for (Index = 0; Index < Length; Index++) {
+ if (MmioRead8 ((UINTN)(BufferData + Index)) != 0) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
diff --git a/MdePkg/Library/BaseMemoryLibMmio/MemLibGuid.c
b/MdePkg/Library/BaseMemoryLibMmio/MemLibGuid.c
new file mode 100644
index
0000000000000000000000000000000000000000..ce69e431309f4447a4e99251a86b5182123e5b97
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/MemLibGuid.c
@@ -0,0 +1,143 @@
+/** @file
+ Implementation of GUID functions.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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
+ )
+{
+ return InternalMemCopyMem (DestinationGuid, SourceGuid, sizeof (GUID));
+}
+
+/**
+ 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
+ )
+{
+ return (0 == InternalMemCompareMem (Guid1, Guid2, sizeof (GUID)));
+}
+
+/**
+ 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;
+}
+
+/**
+ Checks if the given GUID is a zero GUID.
+
+ This function checks whether the given GUID is a zero GUID. If the GUID is
+ identical to a zero GUID then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Guid is NULL, then ASSERT().
+
+ @param Guid The pointer to a 128 bit GUID.
+
+ @retval TRUE Guid is a zero GUID.
+ @retval FALSE Guid is not a zero GUID.
+
+**/
+BOOLEAN
+EFIAPI
+IsZeroGuid (
+ IN CONST GUID *Guid
+ )
+{
+ return InternalMemIsZeroBuffer (Guid, sizeof (GUID));
+}
diff --git a/MdePkg/Library/BaseMemoryLibMmio/MemLibInternals.h
b/MdePkg/Library/BaseMemoryLibMmio/MemLibInternals.h
new file mode 100644
index
0000000000000000000000000000000000000000..dc28a9078a8a707af8a83517d3756c6126093079
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/MemLibInternals.h
@@ -0,0 +1,248 @@
+/** @file
+ Declaration of internal functions for Base Memory Library.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __MEM_LIB_INTERNALS__
+#define __MEM_LIB_INTERNALS__
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.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
+ );
+
+/**
+ Checks whether the contents of a buffer are all zeros.
+
+ @param Buffer The pointer to the buffer to be checked.
+ @param Length The size of the buffer (in bytes) to be checked.
+
+ @retval TRUE Contents of the buffer are all zeros.
+ @retval FALSE Contents of the buffer are not all zeros.
+
+**/
+BOOLEAN
+EFIAPI
+InternalMemIsZeroBuffer (
+ IN CONST VOID *Buffer,
+ IN UINTN Length
+ );
+
+#endif
diff --git a/MdePkg/Library/BaseMemoryLibMmio/ScanMem16Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/ScanMem16Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..ad9330b9938df9995a597dbabc1aa2744aa0d8c1
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/ScanMem16Wrapper.c
@@ -0,0 +1,63 @@
+/** @file
+ ScanMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/ScanMem32Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/ScanMem32Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..84675697d12016f92c46c08c65aca647288a8b99
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/ScanMem32Wrapper.c
@@ -0,0 +1,62 @@
+/** @file
+ ScanMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/ScanMem64Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/ScanMem64Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..df749dce457827fe070bad8b7c6071aae29ebb02
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/ScanMem64Wrapper.c
@@ -0,0 +1,63 @@
+/** @file
+ ScanMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/ScanMem8Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/ScanMem8Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..170981017dbe31cf5e0c3dabf26a4fea33f7a7d7
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/ScanMem8Wrapper.c
@@ -0,0 +1,95 @@
+/** @file
+ ScanMem8() and ScanMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/SetMem.c
b/MdePkg/Library/BaseMemoryLibMmio/SetMem.c
new file mode 100644
index
0000000000000000000000000000000000000000..40255670c6f26eb72a82568f035720fc6fe75546
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/SetMem.c
@@ -0,0 +1,83 @@
+/** @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.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 2020, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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 *Pointer8;
+ volatile UINT32 *Pointer32;
+ volatile UINT64 *Pointer64;
+ UINT32 Value32;
+ UINT64 Value64;
+
+ if ((((UINTN)Buffer & 0x7) == 0) && (Length >= 8)) {
+ // Generate the 64bit value
+ Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
+ Value64 = LShiftU64 (Value32, 32) | Value32;
+
+ Pointer64 = (UINT64*)Buffer;
+ while (Length >= 8) {
+ MmioWrite64 ((UINTN)Pointer64++, Value64);
+ Length -= 8;
+ }
+
+ // Finish with bytes if needed
+ Pointer8 = (UINT8*)Pointer64;
+ } else if ((((UINTN)Buffer & 0x3) == 0) && (Length >= 4)) {
+ // Generate the 32bit value
+ Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
+
+ Pointer32 = (UINT32*)Buffer;
+ while (Length >= 4) {
+ MmioWrite32 ((UINTN)Pointer32++, Value32);
+ Length -= 4;
+ }
+
+ // Finish with bytes if needed
+ Pointer8 = (UINT8*)Pointer32;
+ } else {
+ Pointer8 = (UINT8*)Buffer;
+ }
+ while (Length-- > 0) {
+ MmioWrite8 ((UINTN)Pointer8++, Value);
+ }
+ return Buffer;
+}
diff --git a/MdePkg/Library/BaseMemoryLibMmio/SetMem16Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/SetMem16Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..be785c5eb696ef6b913bf7bc0081a5f414c6f141
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/SetMem16Wrapper.c
@@ -0,0 +1,60 @@
+/** @file
+ SetMem16() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/SetMem32Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/SetMem32Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..622c6eddccc88e846921782efc29e40f816ae499
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/SetMem32Wrapper.c
@@ -0,0 +1,60 @@
+/** @file
+ SetMem32() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/SetMem64Wrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/SetMem64Wrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..7653eed85cd633be5aea439cf4ab62958dd62c47
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/SetMem64Wrapper.c
@@ -0,0 +1,60 @@
+/** @file
+ SetMem64() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/SetMemWrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/SetMemWrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..96dd956686d15b4b4cb25157d764849043d1b57b
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/SetMemWrapper.c
@@ -0,0 +1,87 @@
+/** @file
+ SetMem() and SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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/MdePkg/Library/BaseMemoryLibMmio/ZeroMemWrapper.c
b/MdePkg/Library/BaseMemoryLibMmio/ZeroMemWrapper.c
new file mode 100644
index
0000000000000000000000000000000000000000..55246d121c6820d371af463792614c1d73676e6f
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmio/ZeroMemWrapper.c
@@ -0,0 +1,52 @@
+/** @file
+ ZeroMem() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmio
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#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
+ )
+{
+ if (Length == 0) {
+ return Buffer;
+ }
+
+ ASSERT (Buffer != NULL);
+ ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
+ return InternalMemZeroMem (Buffer, Length);
+}