Index: /trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf	(revision 107873)
+++ /trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf	(revision 107874)
@@ -50,3 +50,4 @@
   DebugLib
   BaseLib
+  IoLib # VBox: Added
 
Index: /trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseMemoryLib/CopyMem.c
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseMemoryLib/CopyMem.c	(revision 107873)
+++ /trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseMemoryLib/CopyMem.c	(revision 107874)
@@ -14,7 +14,6 @@
 #include "MemLibInternals.h"
 
-#if defined(VBOX) && defined(_MSC_VER)
-# pragma optimize("", off)
-#endif
+#include <Library/IoLib.h>
+
 
 /**
@@ -54,5 +53,11 @@
       Source64      = (CONST UINT64 *)SourceBuffer;
       while (Length >= 8) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(Destination64++) = *(Source64++);
+#else
+        MmioWrite64(Destination64, MmioRead64(Source64));
+        Destination64++;
+        Source64++;
+#endif
         Length            -= 8;
       }
@@ -62,5 +67,11 @@
       Source8      = (CONST UINT8 *)Source64;
       while (Length-- != 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(Destination8++) = *(Source8++);
+#else
+        MmioWrite8(Destination8, MmioRead8(Source8));
+        Destination8++;
+        Source8++;
+#endif
       }
     } else if (SourceBuffer < DestinationBuffer) {
@@ -78,5 +89,11 @@
 
         while (Alignment-- != 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
           *(--Destination8) = *(--Source8);
+#else
+          Destination8--;
+          Source8--;
+          MmioWrite8(Destination8, MmioRead8(Source8));
+#endif
           --Length;
         }
@@ -87,5 +104,11 @@
 
       while (Length > 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(--Destination64) = *(--Source64);
+#else
+        Destination64--;
+        Source64--;
+        MmioWrite64(Destination64, MmioRead64(Source64));
+#endif
         Length            -= 8;
       }
@@ -96,5 +119,11 @@
       Source32      = (CONST UINT32 *)SourceBuffer;
       while (Length >= 4) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(Destination32++) = *(Source32++);
+#else
+        MmioWrite32(Destination32, MmioRead32(Source32));
+        Destination32++;
+        Source32++;
+#endif
         Length            -= 4;
       }
@@ -104,5 +133,11 @@
       Source8      = (CONST UINT8 *)Source32;
       while (Length-- != 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(Destination8++) = *(Source8++);
+#else
+        MmioWrite8(Destination8, MmioRead8(Source8));
+        Destination8++;
+        Source8++;
+#endif
       }
     } else if (SourceBuffer < DestinationBuffer) {
@@ -120,5 +155,11 @@
 
         while (Alignment-- != 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
           *(--Destination8) = *(--Source8);
+#else
+          Destination8--;
+          Source8--;
+          MmioWrite8(Destination8, MmioRead8(Source8));
+#endif
           --Length;
         }
@@ -129,5 +170,11 @@
 
       while (Length > 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(--Destination32) = *(--Source32);
+#else
+        Destination32--;
+        Source32--;
+        MmioWrite32(Destination32, MmioRead32(Source32));
+#endif
         Length            -= 4;
       }
@@ -138,5 +185,11 @@
       Source8      = (CONST UINT8 *)SourceBuffer;
       while (Length-- != 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(Destination8++) = *(Source8++);
+#else
+        MmioWrite8(Destination8, MmioRead8(Source8));
+        Destination8++;
+        Source8++;
+#endif
       }
     } else if (SourceBuffer < DestinationBuffer) {
@@ -144,5 +197,11 @@
       Source8      = (CONST UINT8 *)SourceBuffer + (Length - 1);
       while (Length-- != 0) {
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
         *(Destination8--) = *(Source8--);
+#else
+        MmioWrite8(Destination8, MmioRead8(Source8));
+        Destination8--;
+        Source8--;
+#endif
       }
     }
@@ -151,6 +210,2 @@
   return DestinationBuffer;
 }
-
-#if defined(VBOX) && defined(_MSC_VER)
-# pragma optimize("", on)
-#endif
Index: /trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c
===================================================================
--- /trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c	(revision 107873)
+++ /trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/VirtNorFlashDxe/VirtNorFlashFvb.c	(revision 107874)
@@ -173,4 +173,28 @@
 }
 
+#if defined(VBOX) && defined(MDE_CPU_AARCH64)
+static UINT16 NorFlashCalculateSum16 (
+  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 += MmioRead16((volatile UINT16 *)(Buffer + Count));
+  }
+
+  return Sum;
+}
+#endif
+
 /**
   Check the integrity of firmware volume header.
@@ -228,5 +252,9 @@
 
   // Verify the header checksum
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64)
   Checksum = CalculateSum16 ((UINT16 *)FwVolHeader, FwVolHeader->HeaderLength);
+#else
+  Checksum = NorFlashCalculateSum16 ((UINT16 *)FwVolHeader, FwVolHeader->HeaderLength);
+#endif
   if (Checksum != 0) {
     DEBUG ((
@@ -383,4 +411,5 @@
     }
 
+#if !defined(VBOX) || !defined(MDE_CPU_AARCH64) /* MSVC/clang generate instructions on arm64 in debug builds not supported by IEM right now. */
     DEBUG ((
       DEBUG_VERBOSE,
@@ -394,4 +423,5 @@
       VarState
       ));
+#endif
 
     VarPadding = (4 - (VarEnd & 3)) & 3;
