From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.20; helo=mga02.intel.com; envelope-from=liming.gao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 395E92112944E for ; Sun, 10 Jun 2018 22:42:42 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Jun 2018 22:42:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,500,1520924400"; d="scan'208";a="47993555" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by orsmga007.jf.intel.com with ESMTP; 10 Jun 2018 22:42:42 -0700 Received: from fmsmsx121.amr.corp.intel.com (10.18.125.36) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 10 Jun 2018 22:42:42 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx121.amr.corp.intel.com (10.18.125.36) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 10 Jun 2018 22:42:41 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.87]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.70]) with mapi id 14.03.0319.002; Mon, 11 Jun 2018 13:42:39 +0800 From: "Gao, Liming" To: Ard Biesheuvel , "edk2-devel@lists.01.org" CC: "leif.lindholm@linaro.org" , "lersek@redhat.com" , "Kinney, Michael D" Thread-Topic: [PATCH v2 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM Thread-Index: AQHUAOYvhyswouc9vkSQGIgUaf63oKRai94g Date: Mon, 11 Jun 2018 05:42:38 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E29550C@SHSMSX104.ccr.corp.intel.com> References: <20180610180921.11269-1-ard.biesheuvel@linaro.org> In-Reply-To: <20180610180921.11269-1-ard.biesheuvel@linaro.org> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v2 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jun 2018 05:42:44 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Ard: The function MmioRead8Internal() .. MmioWrite64Internal() miss the functi= on header comments. Please add them.=20 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 >; Kinney, Michael D ; >Ard Biesheuvel >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=3D01010101 R01=3D00000008 R02=3D00000048 R03=3D08000820 > R04=3D00000120 R05=3D7faaa0e0 R06=3D7faaa0dc R07=3D7faaa0e8 > R08=3D7faaa0ec R09=3D7faaa088 R10=3D000000ff R11=3D00000080 > R12=3Dff000000 R13=3D7fccfe08 R14=3D7faa835f R15=3D7faa887c > PSR=3D800001f3 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 >--- > 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 th= is >+# 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 va= lue >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 MMI= O >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 MMI= O >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 MMI= O >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 MMI= O >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 th= is >+; 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 val= ue 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 v= alue >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 v= alue >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 v= alue >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 th= is >+# 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 va= lue >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 MMI= O >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 MMI= O >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 MMI= O >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 MMI= O >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 th= is >+; 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 val= ue 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 v= alue >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 v= alue >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 v= alue >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.i= nf >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.
>+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved. >+# Copyright (c) 2017, AMD Incorporated. All rights reserved.
>+# Copyright (c) 2018, Linaro, Ltd. 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 th= is >+# 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 =3D 0x0001001A >+ BASE_NAME =3D BaseIoLibIntrinsicArmVirt >+ MODULE_UNI_FILE =3D BaseIoLibIntrinsicArmVirt.uni >+ FILE_GUID =3D 217102b4-b465-4a1d-a2de-93dd385ec480 >+ MODULE_TYPE =3D BASE >+ VERSION_STRING =3D 1.0 >+ LIBRARY_CLASS =3D IoLib >+ >+# >+# VALID_ARCHITECTURES =3D 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.u= ni >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. >+// Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<= BR> >+// Copyright (c) 2017, AMD Incorporated. All rights reserved.
>+// Copyright (c) 2018, Linaro, Ltd. 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. >+// >+// **/ >+ >+ >+#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.
>+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
>+ Copyright (c) 2017, AMD Incorporated. All rights reserved.
>+ Copyright (c) 2018, Linaro, Ltd. 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 thi= s >+ 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 ret= urned. >+ 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 w= rite >+ 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 r= eturned. >+ 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 b= y >Value >+ and returns Value. This function must guarantee that all I/O read and w= rite >+ 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 r= eturned. >+ 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 b= y >Value >+ and returns Value. This function must guarantee that all I/O read and w= rite >+ 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 r= eturned. >+ 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 b= y >Value >+ and returns Value. This function must guarantee that all I/O read and w= rite >+ 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 ar= e >+ 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 ar= e >+ 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 ar= e >+ 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 valu= e 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 va= lue >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) =3D=3D 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) =3D=3D 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 va= lue >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) =3D=3D 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) =3D=3D 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 va= lue >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) =3D=3D 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) =3D=3D 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