From: "Gao, Liming" <liming.gao@intel.com>
To: Laszlo Ersek <lersek@redhat.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"leif.lindholm@linaro.org" <leif.lindholm@linaro.org>
Subject: Re: [PATCH] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM
Date: Fri, 8 Jun 2018 16:38:48 +0000 [thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E294E1F@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <d84f3b7b-2de1-a29f-021d-5b69d329c1db@redhat.com>
Laszlo:
I get your point. I am OK to add this library instance in MdePkg for code sharing.
Ard:
Have you plan to make this library instance pass VS2017 tool chain?
Thanks
Liming
> -----Original Message-----
> From: Laszlo Ersek [mailto:lersek@redhat.com]
> Sent: Friday, June 8, 2018 12:56 AM
> To: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Gao, Liming <liming.gao@intel.com>
> Cc: edk2-devel@lists.01.org; leif.lindholm@linaro.org; Kinney, Michael D <michael.d.kinney@intel.com>
> Subject: Re: [PATCH] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM
>
> On 06/07/18 17:09, Ard Biesheuvel wrote:
> > On 7 June 2018 at 17:08, Gao, Liming <liming.gao@intel.com> wrote:
> >> Ard:
> >> If this library instance is specific to ARM emulator with KVM, how about add it into ArmVirtPkg?
> >>
> >
> > Laszlo, do you want to take this question?
>
> Certainly.
>
> Liming, in commit b6d11d7c4678, we added "BaseIoLibIntrinsicSev.inf" to
> "MdePkg/Library/BaseIoLibIntrinsic", with some custom Ia32 and X64 NASM
> files, but mostly reusing the large existent files ("IoLibMmioBuffer.c",
> "IoHighLevel.c" etc).
>
> That library instance (and the NASM customizations) target AMD SEV; that
> is, when the code runs in a virtual machine for which AMD Secure
> Encrypted Virtualization is enabled. The NASM code uses CPUID to
> dynamically determine whether it runs in a SEV guest, or in a normal
> guest, and in the former case, it avoids using the REP prefix in the
> IoFifo routines (it uses open-coded LOOPs).
>
> The "BaseIoLibIntrinsicSev.inf" instance is only ever used in OvmfPkg
> (it only makes sense in virtual machines), but the consensus back then
> was to add the lib instance to MdePkg.
>
>
> This time, Ard has already implemented (and posted) the IoLib instance
> that we need for ARM KVM such that it lands under ArmVirtPkg -- however,
> that library instance duplicates a huge amount of code, un-changed, from
> "BaseIoLibIntrinsic" (such as "IoLibMmioBuffer.c", "IoHighLevel.c"). I
> suggested that Ard instead post the new library instance as a new INF
> file (plus some assembly files) for BaseIoLibIntrinsic itself, because:
> (a) this way we avoid code duplication, and (b) that's exactly what we
> did -- for another virtualization-only use case -- in commit
> b6d11d7c4678 earlier.
>
> If you'd like us to add the code to ArmVirtPkg, I don't think that's the
> right or consequent action, but technically, we can simply fall back to
> the ArmVirtPkg patches that Ard already wrote and posted.
>
> Thanks,
> Laszlo
>
> >>> -----Original Message-----
> >>> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> >>> Sent: Thursday, June 7, 2018 6:47 PM
> >>> To: edk2-devel@lists.01.org
> >>> Cc: lersek@redhat.com; leif.lindholm@linaro.org; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D
> >>> <michael.d.kinney@intel.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >>> Subject: [PATCH] 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>
> >>> ---
> >>> ArmVirtPkg/ArmVirt.dsc.inc | 2 +-
> >>> MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S | 164 +++++
> >>> MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S | 161 +++++
> >>> MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm | 165 +++++
> >>> MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf | 50 ++
> >>> MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c | 641 ++++++++++++++++++++
> >>> 6 files changed, 1182 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> >>> index 766e4f598a07..7464ac70ed1b 100644
> >>> --- a/ArmVirtPkg/ArmVirt.dsc.inc
> >>> +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> >>> @@ -41,7 +41,7 @@ [LibraryClasses.common]
> >>> PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> >>> PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> >>> PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> >>> - IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> >>> + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
> >>> UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
> >>> CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> >>>
> >>> 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/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..5a1dc87ed2bd
> >>> --- /dev/null
> >>> +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
> >>> @@ -0,0 +1,50 @@
> >>> +## @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
> >>> + 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
> >>> +
> >>> +[Packages]
> >>> + MdePkg/MdePkg.dec
> >>> +
> >>> +[LibraryClasses]
> >>> + DebugLib
> >>> + BaseLib
> >>> 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;
> >>> +}
> >>> --
> >>> 2.17.0
> >>
next prev parent reply other threads:[~2018-06-08 16:38 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-07 10:46 [PATCH] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM Ard Biesheuvel
2018-06-07 15:08 ` Gao, Liming
2018-06-07 15:09 ` Ard Biesheuvel
2018-06-07 16:56 ` Laszlo Ersek
2018-06-08 16:38 ` Gao, Liming [this message]
2018-06-10 17:51 ` Ard Biesheuvel
2018-06-07 16:07 ` Leif Lindholm
2018-06-07 17:14 ` Laszlo Ersek
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=4A89E2EF3DFEDB4C8BFDE51014F606A14E294E1F@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