Reviewed-by: Liming Gao <liming....@intel.com>
> -----Original Message----- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Ard > Biesheuvel > Sent: Monday, June 11, 2018 3:26 PM > To: edk2-devel@lists.01.org > Cc: Kinney, Michael D <michael.d.kin...@intel.com>; ler...@redhat.com; Gao, > Liming <liming....@intel.com>; > leif.lindh...@linaro.org; Ard Biesheuvel <ard.biesheu...@linaro.org> > Subject: [edk2] [PATCH v3 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.biesheu...@linaro.org> > --- > v3: add missing prototype comments in IoLibArmVirt.c > remove mention of ASSERT () from description of internal asm routines > v2: add missing .uni file > split off ArmVirtPkg change > add VS2017 version of AArch64 asm file > add reference to MdePkg.dsc > > MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S | 148 ++++ > MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm | 149 ++++ > MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S | 145 ++++ > MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm | 149 ++++ > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf | 52 ++ > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.uni | 23 + > MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c | 733 > ++++++++++++++++++++ > MdePkg/MdePkg.dsc | 1 + > 8 files changed, 1400 insertions(+) > > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S > b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S > new file mode 100644 > index 000000000000..85f59324270c > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S > @@ -0,0 +1,148 @@ > +# > +# 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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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..bd235a5dd441 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.asm > @@ -0,0 +1,149 @@ > +; > +; 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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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..1e91e87fb887 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.S > @@ -0,0 +1,145 @@ > +# > +# 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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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. > +// > +// @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..cff99b86a99c > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/Arm/ArmVirtMmio.asm > @@ -0,0 +1,149 @@ > +; > +; 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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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. > +; > +; @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..1a1b77967d55 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c > @@ -0,0 +1,733 @@ > +/** @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" > + > +/** > + 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. > + > + @param Address The MMIO register to read. > + > + @return The value read. > + > +**/ > +UINT8 > +EFIAPI > +MmioRead8Internal ( > + IN UINTN 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. > + > + @param Address The MMIO register to write. > + @param Value The value to write to the MMIO register. > + > +**/ > +VOID > +EFIAPI > +MmioWrite8Internal ( > + IN UINTN Address, > + IN UINT8 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. > + > + @param Address The MMIO register to read. > + > + @return The value read. > + > +**/ > +UINT16 > +EFIAPI > +MmioRead16Internal ( > + IN UINTN 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. > + > + @param Address The MMIO register to write. > + @param Value The value to write to the MMIO register. > + > +**/ > +VOID > +EFIAPI > +MmioWrite16Internal ( > + IN UINTN Address, > + IN UINT16 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. > + > + @param Address The MMIO register to read. > + > + @return The value read. > + > +**/ > +UINT32 > +EFIAPI > +MmioRead32Internal ( > + IN UINTN 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. > + > + @param Address The MMIO register to write. > + @param Value The value to write to the MMIO register. > + > +**/ > +VOID > +EFIAPI > +MmioWrite32Internal ( > + IN UINTN Address, > + IN UINT32 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. > + > + @param Address The MMIO register to read. > + > + @return The value read. > + > +**/ > +UINT64 > +EFIAPI > +MmioRead64Internal ( > + IN UINTN 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. > + > + @param Address The MMIO register to write. > + @param Value The value to write to the MMIO register. > + > +**/ > +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 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel