public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Gao, Liming" <liming.gao@intel.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: "leif.lindholm@linaro.org" <leif.lindholm@linaro.org>,
	"lersek@redhat.com" <lersek@redhat.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [PATCH v2 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM
Date: Mon, 11 Jun 2018 05:42:38 +0000	[thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E29550C@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20180610180921.11269-1-ard.biesheuvel@linaro.org>

Ard:
  The function MmioRead8Internal() .. MmioWrite64Internal() miss the function header comments. Please add them. 

Thanks
Liming
>-----Original Message-----
>From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
>Sent: Monday, June 11, 2018 2:09 AM
>To: edk2-devel@lists.01.org
>Cc: leif.lindholm@linaro.org; lersek@redhat.com; Gao, Liming
><liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>;
>Ard Biesheuvel <ard.biesheuvel@linaro.org>
>Subject: [PATCH v2 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic
>safe for ArmVirt/KVM
>
>KVM on ARM refuses to decode load/store instructions used to perform
>I/O to emulated devices, and instead relies on the exception syndrome
>information to describe the operand register, access size, etc.
>This is only possible for instructions that have a single input/output
>register (as opposed to ones that increment the offset register, or
>load/store pair instructions, etc). Otherwise, QEMU crashes with the
>following error
>
>  error: kvm run failed Function not implemented
>  R00=01010101 R01=00000008 R02=00000048 R03=08000820
>  R04=00000120 R05=7faaa0e0 R06=7faaa0dc R07=7faaa0e8
>  R08=7faaa0ec R09=7faaa088 R10=000000ff R11=00000080
>  R12=ff000000 R13=7fccfe08 R14=7faa835f R15=7faa887c
>  PSR=800001f3 N--- T svc32
>  QEMU: Terminated
>
>and KVM produces a warning such as the following in the kernel log
>
>  kvm [17646]: load/store instruction decoding not implemented
>
>The IoLib implementation provided by MdePkg/Library/BaseIoLibIntrinsic
>is based on C code, and when LTO is in effect, the MMIO accesses could
>be merged with, e.g., manipulations of the loop counter, producing
>opcodes that KVM does not support for emulated MMIO.
>
>So let's add a special ArmVirt flavor of this library that implements
>that actual load/store operations in assembler, ensuring that the
>instructions involved can be emulated by KVM.
>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>---
> MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S         | 164 +++++
> MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm       | 165
>+++++
> MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S             | 161 +++++
> MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm           | 165 +++++
> MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf |  52 ++
> MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni |  23 +
> MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c                | 641
>++++++++++++++++++++
> MdePkg/MdePkg.dsc                                               |   1 +
> 8 files changed, 1372 insertions(+)
>
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S
>b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S
>new file mode 100644
>index 000000000000..47be68a3e783
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S
>@@ -0,0 +1,164 @@
>+#
>+#  Copyright (c) 2014-2018, Linaro Limited. 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
>+.align 3
>+
>+GCC_ASM_EXPORT(MmioRead8Internal)
>+GCC_ASM_EXPORT(MmioWrite8Internal)
>+GCC_ASM_EXPORT(MmioRead16Internal)
>+GCC_ASM_EXPORT(MmioWrite16Internal)
>+GCC_ASM_EXPORT(MmioRead32Internal)
>+GCC_ASM_EXPORT(MmioWrite32Internal)
>+GCC_ASM_EXPORT(MmioRead64Internal)
>+GCC_ASM_EXPORT(MmioWrite64Internal)
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead8Internal):
>+  ldrb    w0, [x0]
>+  dmb     ld
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite8Internal):
>+  dmb     st
>+  strb    w1, [x0]
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead16Internal):
>+  ldrh    w0, [x0]
>+  dmb     ld
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite16Internal):
>+  dmb     st
>+  strh    w1, [x0]
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead32Internal):
>+  ldr     w0, [x0]
>+  dmb     ld
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite32Internal):
>+  dmb     st
>+  str     w1, [x0]
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead64Internal):
>+  ldr     x0, [x0]
>+  dmb     ld
>+  ret
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite64Internal):
>+  dmb     st
>+  str     x1, [x0]
>+  ret
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm
>b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm
>new file mode 100644
>index 000000000000..0a3d9fc9c94a
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm
>@@ -0,0 +1,165 @@
>+;
>+;  Copyright (c) 2014-2018, Linaro Limited. 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.
>+;
>+
>+
>+AREA IoLibMmio, CODE, READONLY
>+
>+EXPORT MmioRead8Internal
>+EXPORT MmioWrite8Internal
>+EXPORT MmioRead16Internal
>+EXPORT MmioWrite16Internal
>+EXPORT MmioRead32Internal
>+EXPORT MmioWrite32Internal
>+EXPORT MmioRead64Internal
>+EXPORT MmioWrite64Internal
>+
>+;
>+;  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.
>+;
>+MmioRead8Internal
>+  ldrb    w0, [x0]
>+  dmb     ld
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioWrite8Internal
>+  dmb     st
>+  strb    w1, [x0]
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioRead16Internal
>+  ldrh    w0, [x0]
>+  dmb     ld
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioWrite16Internal
>+  dmb     st
>+  strh    w1, [x0]
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioRead32Internal
>+  ldr     w0, [x0]
>+  dmb     ld
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioWrite32Internal
>+  dmb     st
>+  str     w1, [x0]
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioRead64Internal
>+  ldr    x0, [x0]
>+  dmb    ld
>+  ret
>+
>+;
>+;  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.
>+;
>+MmioWrite64Internal
>+  dmb     st
>+  str     x1, [x0]
>+  ret
>+
>+  END
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S
>b/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S
>new file mode 100644
>index 000000000000..438805ca7c24
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S
>@@ -0,0 +1,161 @@
>+#
>+#  Copyright (c) 2014-2018, Linaro Limited. 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.
>+#
>+#
>+
>+GCC_ASM_EXPORT(MmioRead8Internal)
>+GCC_ASM_EXPORT(MmioWrite8Internal)
>+GCC_ASM_EXPORT(MmioRead16Internal)
>+GCC_ASM_EXPORT(MmioWrite16Internal)
>+GCC_ASM_EXPORT(MmioRead32Internal)
>+GCC_ASM_EXPORT(MmioWrite32Internal)
>+GCC_ASM_EXPORT(MmioRead64Internal)
>+GCC_ASM_EXPORT(MmioWrite64Internal)
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead8Internal):
>+  ldrb    r0, [r0]
>+  dmb
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite8Internal):
>+  dmb     st
>+  strb    r1, [r0]
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead16Internal):
>+  ldrh    r0, [r0]
>+  dmb
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite16Internal):
>+  dmb     st
>+  strh    r1, [r0]
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead32Internal):
>+  ldr     r0, [r0]
>+  dmb
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite32Internal):
>+  dmb     st
>+  str     r1, [r0]
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioRead64Internal):
>+  ldrd    r0, r1, [r0]
>+  dmb
>+  bx      lr
>+
>+//
>+//  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.
>+//
>+ASM_PFX(MmioWrite64Internal):
>+  dmb     st
>+  strd    r2, r3, [r0]
>+  bx      lr
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm
>b/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm
>new file mode 100644
>index 000000000000..82add82f800a
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm
>@@ -0,0 +1,165 @@
>+;
>+;  Copyright (c) 2014-2018, Linaro Limited. 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.
>+;
>+
>+
>+AREA IoLibMmio, CODE, READONLY
>+
>+EXPORT MmioRead8Internal
>+EXPORT MmioWrite8Internal
>+EXPORT MmioRead16Internal
>+EXPORT MmioWrite16Internal
>+EXPORT MmioRead32Internal
>+EXPORT MmioWrite32Internal
>+EXPORT MmioRead64Internal
>+EXPORT MmioWrite64Internal
>+
>+;
>+;  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.
>+;
>+MmioRead8Internal
>+  ldrb    r0, [r0]
>+  dmb
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioWrite8Internal
>+  dmb     st
>+  strb    r1, [r0]
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioRead16Internal
>+  ldrh    r0, [r0]
>+  dmb
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioWrite16Internal
>+  dmb     st
>+  strh    r1, [r0]
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioRead32Internal
>+  ldr     r0, [r0]
>+  dmb
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioWrite32Internal
>+  dmb     st
>+  str     r1, [r0]
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioRead64Internal
>+  ldrd    r0, r1, [r0]
>+  dmb
>+  bx      lr
>+
>+;
>+;  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.
>+;
>+MmioWrite64Internal
>+  dmb     st
>+  strd    r2, r3, [r0]
>+  bx      lr
>+
>+  END
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
>b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
>new file mode 100644
>index 000000000000..1e39ad533fac
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
>@@ -0,0 +1,52 @@
>+## @file
>+#  Instance of I/O Library using KVM/ARM safe assembler routines
>+#
>+#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
>+#  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
>+#  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
>+#  Copyright (c) 2018, Linaro, 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                    = 0x0001001A
>+  BASE_NAME                      = BaseIoLibIntrinsicArmVirt
>+  MODULE_UNI_FILE                = BaseIoLibIntrinsicArmVirt.uni
>+  FILE_GUID                      = 217102b4-b465-4a1d-a2de-93dd385ec480
>+  MODULE_TYPE                    = BASE
>+  VERSION_STRING                 = 1.0
>+  LIBRARY_CLASS                  = IoLib
>+
>+#
>+#  VALID_ARCHITECTURES           = ARM AARCH64
>+#
>+
>+[Sources]
>+  IoLibMmioBuffer.c
>+  BaseIoLibIntrinsicInternal.h
>+  IoHighLevel.c
>+
>+[Sources.ARM]
>+  IoLibArmVirt.c
>+  Arm/ArmVirtMmio.S       | GCC
>+  Arm/ArmVirtMmio.asm     | RVCT
>+
>+[Sources.AARCH64]
>+  IoLibArmVirt.c
>+  AArch64/ArmVirtMmio.S   | GCC
>+  AArch64/ArmVirtMmio.asm | MSFT
>+
>+[Packages]
>+  MdePkg/MdePkg.dec
>+
>+[LibraryClasses]
>+  DebugLib
>+  BaseLib
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni
>b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni
>new file mode 100644
>index 000000000000..a1109c520453
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni
>@@ -0,0 +1,23 @@
>+// /** @file
>+//   Instance of I/O Library using KVM/ARM safe assembler routines
>+//
>+//   Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
>+//   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
>+//   Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
>+//   Copyright (c) 2018, Linaro, 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.
>+//
>+// **/
>+
>+
>+#string STR_MODULE_ABSTRACT             #language en-US "Instance of I/O
>Library using KVM/ARM safe assembler routines"
>+
>+#string STR_MODULE_DESCRIPTION          #language en-US "I/O Library that
>uses assembler routines to perform MMIO accesses, to prevent link time
>code generation under LTO from emitting instructions that KVM on ARM
>cannot deal with."
>+
>diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c
>b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c
>new file mode 100644
>index 000000000000..154d583246ac
>--- /dev/null
>+++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c
>@@ -0,0 +1,641 @@
>+/** @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>
>+  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
>+  Copyright (c) 2018, Linaro, 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 "BaseIoLibIntrinsicInternal.h"
>+
>+UINT8
>+EFIAPI
>+MmioRead8Internal (
>+  IN      UINTN                     Address
>+  );
>+
>+VOID
>+EFIAPI
>+MmioWrite8Internal (
>+  IN      UINTN                     Address,
>+  IN      UINT8                     Value
>+  );
>+
>+UINT16
>+EFIAPI
>+MmioRead16Internal (
>+  IN      UINTN                     Address
>+  );
>+
>+VOID
>+EFIAPI
>+MmioWrite16Internal (
>+  IN      UINTN                     Address,
>+  IN      UINT16                    Value
>+  );
>+
>+UINT32
>+EFIAPI
>+MmioRead32Internal (
>+  IN      UINTN                     Address
>+  );
>+
>+VOID
>+EFIAPI
>+MmioWrite32Internal (
>+  IN      UINTN                     Address,
>+  IN      UINT32                    Value
>+  );
>+
>+UINT64
>+EFIAPI
>+MmioRead64Internal (
>+  IN      UINTN                     Address
>+  );
>+
>+VOID
>+EFIAPI
>+MmioWrite64Internal (
>+  IN      UINTN                     Address,
>+  IN      UINT64                    Value
>+  );
>+
>+/**
>+  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 I/O port fifo into a block of memory.
>+
>+  Reads the 8-bit I/O fifo port specified by Port.
>+  The port is read Count times, and the read data is
>+  stored in the provided Buffer.
>+
>+  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.
>+  @param  Count   The number of times to read I/O port.
>+  @param  Buffer  The buffer to store the read data into.
>+
>+**/
>+VOID
>+EFIAPI
>+IoReadFifo8 (
>+  IN      UINTN                     Port,
>+  IN      UINTN                     Count,
>+  OUT     VOID                      *Buffer
>+  )
>+{
>+  ASSERT (FALSE);
>+}
>+
>+/**
>+  Writes a block of memory into an 8-bit I/O port fifo.
>+
>+  Writes the 8-bit I/O fifo port specified by Port.
>+  The port is written Count times, and the write data is
>+  retrieved from the provided Buffer.
>+
>+  This function must guarantee that all I/O write 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  Count   The number of times to write I/O port.
>+  @param  Buffer  The buffer to retrieve the write data from.
>+
>+**/
>+VOID
>+EFIAPI
>+IoWriteFifo8 (
>+  IN      UINTN                     Port,
>+  IN      UINTN                     Count,
>+  IN      VOID                      *Buffer
>+  )
>+{
>+  ASSERT (FALSE);
>+}
>+
>+/**
>+  Reads a 16-bit I/O port fifo into a block of memory.
>+
>+  Reads the 16-bit I/O fifo port specified by Port.
>+  The port is read Count times, and the read data is
>+  stored in the provided Buffer.
>+
>+  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.
>+  @param  Count   The number of times to read I/O port.
>+  @param  Buffer  The buffer to store the read data into.
>+
>+**/
>+VOID
>+EFIAPI
>+IoReadFifo16 (
>+  IN      UINTN                     Port,
>+  IN      UINTN                     Count,
>+  OUT     VOID                      *Buffer
>+  )
>+{
>+  ASSERT (FALSE);
>+}
>+
>+/**
>+  Writes a block of memory into a 16-bit I/O port fifo.
>+
>+  Writes the 16-bit I/O fifo port specified by Port.
>+  The port is written Count times, and the write data is
>+  retrieved from the provided Buffer.
>+
>+  This function must guarantee that all I/O write 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  Count   The number of times to write I/O port.
>+  @param  Buffer  The buffer to retrieve the write data from.
>+
>+**/
>+VOID
>+EFIAPI
>+IoWriteFifo16 (
>+  IN      UINTN                     Port,
>+  IN      UINTN                     Count,
>+  IN      VOID                      *Buffer
>+  )
>+{
>+  ASSERT (FALSE);
>+}
>+
>+/**
>+  Reads a 32-bit I/O port fifo into a block of memory.
>+
>+  Reads the 32-bit I/O fifo port specified by Port.
>+  The port is read Count times, and the read data is
>+  stored in the provided Buffer.
>+
>+  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.
>+  @param  Count   The number of times to read I/O port.
>+  @param  Buffer  The buffer to store the read data into.
>+
>+**/
>+VOID
>+EFIAPI
>+IoReadFifo32 (
>+  IN      UINTN                     Port,
>+  IN      UINTN                     Count,
>+  OUT     VOID                      *Buffer
>+  )
>+{
>+  ASSERT (FALSE);
>+}
>+
>+/**
>+  Writes a block of memory into a 32-bit I/O port fifo.
>+
>+  Writes the 32-bit I/O fifo port specified by Port.
>+  The port is written Count times, and the write data is
>+  retrieved from the provided Buffer.
>+
>+  This function must guarantee that all I/O write 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  Count   The number of times to write I/O port.
>+  @param  Buffer  The buffer to retrieve the write data from.
>+
>+**/
>+VOID
>+EFIAPI
>+IoWriteFifo32 (
>+  IN      UINTN                     Port,
>+  IN      UINTN                     Count,
>+  IN      VOID                      *Buffer
>+  )
>+{
>+  ASSERT (FALSE);
>+}
>+
>+/**
>+  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 MmioRead8Internal (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.
>+
>+**/
>+UINT8
>+EFIAPI
>+MmioWrite8 (
>+  IN      UINTN                     Address,
>+  IN      UINT8                     Value
>+  )
>+{
>+  MmioWrite8Internal (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
>+  )
>+{
>+  ASSERT ((Address & 1) == 0);
>+
>+  return MmioRead16Internal (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().
>+
>+  @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);
>+
>+  MmioWrite16Internal (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
>+  )
>+{
>+  ASSERT ((Address & 3) == 0);
>+
>+  return MmioRead32Internal (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().
>+
>+  @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);
>+
>+  MmioWrite32Internal (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
>+  )
>+{
>+  ASSERT ((Address & 7) == 0);
>+
>+  return MmioRead64Internal (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().
>+
>+  @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);
>+
>+  MmioWrite64Internal (Address, Value);
>+  return Value;
>+}
>diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
>index 60efd722e9d7..cf20bc3a1fcf 100644
>--- a/MdePkg/MdePkg.dsc
>+++ b/MdePkg/MdePkg.dsc
>@@ -186,6 +186,7 @@ [Components.EBC]
>   MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
>
> [Components.ARM, Components.AARCH64]
>+  MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
>   MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
>
> [BuildOptions]
>--
>2.17.1



  parent reply	other threads:[~2018-06-11  5:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-10 18:09 [PATCH v2 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM Ard Biesheuvel
2018-06-10 18:09 ` [PATCH v2 2/2] ArmVirtPkg: switch to KVM safe IoLib implementation Ard Biesheuvel
2018-06-11  5:42 ` Gao, Liming [this message]
2018-06-11  7:06   ` [PATCH v2 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A89E2EF3DFEDB4C8BFDE51014F606A14E29550C@SHSMSX104.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox