]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseMemoryLib/CopyMem.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseMemoryLib / CopyMem.c
index df5258c93ee15cae363cf3516f47da6f9cce51ce..55e8616c98cb62b87b2378d48b8f8e8fb47bd3a4 100644 (file)
@@ -1,35 +1,27 @@
 /** @file\r
-  Implementation of the EfiCopyMem routine. This function is broken\r
-  out into its own source file so that it can be excluded from a\r
-  build for a particular platform easily if an optimized version\r
-  is desired.\r
+  Implementation of the InternalMemCopyMem routine. This function is broken\r
+  out into its own source file so that it can be excluded from a build for a\r
+  particular platform easily if an optimized version is desired.\r
 \r
-  Copyright (c) 2006, Intel Corporation<BR>\r
-  All rights reserved. This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>\r
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
 \r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-  Module Name:  EfiCopyMem.c\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-//\r
-// Include common header file for this module.\r
-//\r
-#include "CommonHeader.h"\r
+\r
+\r
 \r
 #include "MemLibInternals.h"\r
 \r
 /**\r
   Copy Length bytes from Source to Destination.\r
 \r
-  @param  Destination Target of copy\r
-  @param  Source Place to copy from\r
-  @param  Length Number of bytes to copy\r
+  @param  DestinationBuffer The target of the copy request.\r
+  @param  SourceBuffer      The place to copy from.\r
+  @param  Length            The number of bytes to copy.\r
 \r
   @return Destination\r
 \r
@@ -37,8 +29,8 @@
 VOID *\r
 EFIAPI\r
 InternalMemCopyMem (\r
-  OUT     VOID                      *Destination,\r
-  IN      CONST VOID                *Source,\r
+  OUT     VOID                      *DestinationBuffer,\r
+  IN      CONST VOID                *SourceBuffer,\r
   IN      UINTN                     Length\r
   )\r
 {\r
@@ -49,19 +41,108 @@ InternalMemCopyMem (
   //\r
   volatile UINT8                    *Destination8;\r
   CONST UINT8                       *Source8;\r
+  volatile UINT32                   *Destination32;\r
+  CONST UINT32                      *Source32;\r
+  volatile UINT64                   *Destination64;\r
+  CONST UINT64                      *Source64;\r
+  UINTN                             Alignment;\r
+\r
+  if ((((UINTN)DestinationBuffer & 0x7) == 0) && (((UINTN)SourceBuffer & 0x7) == 0) && (Length >= 8)) {\r
+    if (SourceBuffer > DestinationBuffer) {\r
+      Destination64 = (UINT64*)DestinationBuffer;\r
+      Source64 = (CONST UINT64*)SourceBuffer;\r
+      while (Length >= 8) {\r
+        *(Destination64++) = *(Source64++);\r
+        Length -= 8;\r
+      }\r
+\r
+      // Finish if there are still some bytes to copy\r
+      Destination8 = (UINT8*)Destination64;\r
+      Source8 = (CONST UINT8*)Source64;\r
+      while (Length-- != 0) {\r
+        *(Destination8++) = *(Source8++);\r
+      }\r
+    } else if (SourceBuffer < DestinationBuffer) {\r
+      Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);\r
+      Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);\r
+\r
+      // Destination64 and Source64 were aligned on a 64-bit boundary\r
+      // but if length is not a multiple of 8 bytes then they won't be\r
+      // anymore.\r
+\r
+      Alignment = Length & 0x7;\r
+      if (Alignment != 0) {\r
+        Destination8 = (UINT8*)Destination64;\r
+        Source8 = (CONST UINT8*)Source64;\r
+\r
+        while (Alignment-- != 0) {\r
+          *(--Destination8) = *(--Source8);\r
+          --Length;\r
+        }\r
+        Destination64 = (UINT64*)Destination8;\r
+        Source64 = (CONST UINT64*)Source8;\r
+      }\r
+\r
+      while (Length > 0) {\r
+        *(--Destination64) = *(--Source64);\r
+        Length -= 8;\r
+      }\r
+    }\r
+  } else if ((((UINTN)DestinationBuffer & 0x3) == 0) && (((UINTN)SourceBuffer & 0x3) == 0) && (Length >= 4)) {\r
+    if (SourceBuffer > DestinationBuffer) {\r
+      Destination32 = (UINT32*)DestinationBuffer;\r
+      Source32 = (CONST UINT32*)SourceBuffer;\r
+      while (Length >= 4) {\r
+        *(Destination32++) = *(Source32++);\r
+        Length -= 4;\r
+      }\r
+\r
+      // Finish if there are still some bytes to copy\r
+      Destination8 = (UINT8*)Destination32;\r
+      Source8 = (CONST UINT8*)Source32;\r
+      while (Length-- != 0) {\r
+        *(Destination8++) = *(Source8++);\r
+      }\r
+    } else if (SourceBuffer < DestinationBuffer) {\r
+      Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);\r
+      Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);\r
+\r
+      // Destination32 and Source32 were aligned on a 32-bit boundary\r
+      // but if length is not a multiple of 4 bytes then they won't be\r
+      // anymore.\r
+\r
+      Alignment = Length & 0x3;\r
+      if (Alignment != 0) {\r
+        Destination8 = (UINT8*)Destination32;\r
+        Source8 = (CONST UINT8*)Source32;\r
+\r
+        while (Alignment-- != 0) {\r
+          *(--Destination8) = *(--Source8);\r
+          --Length;\r
+        }\r
+        Destination32 = (UINT32*)Destination8;\r
+        Source32 = (CONST UINT32*)Source8;\r
+      }\r
 \r
-  if (Source > Destination) {\r
-    Destination8 = (UINT8*)Destination;\r
-    Source8 = (CONST UINT8*)Source;\r
-    while (Length-- != 0) {\r
-      *(Destination8++) = *(Source8++);\r
+      while (Length > 0) {\r
+        *(--Destination32) = *(--Source32);\r
+        Length -= 4;\r
+      }\r
     }\r
-  } else if (Source < Destination) {\r
-    Destination8 = (UINT8*)Destination + Length;\r
-    Source8 = (CONST UINT8*)Source + Length;\r
-    while (Length-- != 0) {\r
-      *(--Destination8) = *(--Source8);\r
+  } else {\r
+    if (SourceBuffer > DestinationBuffer) {\r
+      Destination8 = (UINT8*)DestinationBuffer;\r
+      Source8 = (CONST UINT8*)SourceBuffer;\r
+      while (Length-- != 0) {\r
+        *(Destination8++) = *(Source8++);\r
+      }\r
+    } else if (SourceBuffer < DestinationBuffer) {\r
+      Destination8 = (UINT8*)DestinationBuffer + (Length - 1);\r
+      Source8 = (CONST UINT8*)SourceBuffer + (Length - 1);\r
+      while (Length-- != 0) {\r
+        *(Destination8--) = *(Source8--);\r
+      }\r
     }\r
   }\r
-  return Destination;\r
+  return DestinationBuffer;\r
 }\r