From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=liming.gao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (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 343B221197B20 for ; Mon, 11 Jun 2018 08:51:58 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Jun 2018 08:51:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,502,1520924400"; d="scan'208";a="231665257" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by orsmga005.jf.intel.com with ESMTP; 11 Jun 2018 08:51:57 -0700 Received: from fmsmsx154.amr.corp.intel.com (10.18.116.70) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 11 Jun 2018 08:51:57 -0700 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by FMSMSX154.amr.corp.intel.com (10.18.116.70) with Microsoft SMTP Server (TLS) id 14.3.319.2; Mon, 11 Jun 2018 08:51:55 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.87]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.82]) with mapi id 14.03.0319.002; Mon, 11 Jun 2018 23:51:54 +0800 From: "Gao, Liming" To: Ard Biesheuvel , "edk2-devel@lists.01.org" CC: "Kinney, Michael D" , "lersek@redhat.com" , "leif.lindholm@linaro.org" Thread-Topic: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibIntrinsic safe for ArmVirt/KVM Thread-Index: AQHUAVWEcOdzC7S2xEuGcnHvK39Pe6RbNYlQ Date: Mon, 11 Jun 2018 15:51:53 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E29592C@SHSMSX104.ccr.corp.intel.com> References: <20180611072553.30050-1-ard.biesheuvel@linaro.org> In-Reply-To: <20180611072553.30050-1-ard.biesheuvel@linaro.org> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ctpclassification: CTP_NT x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZDA4NDgwZGMtMWNjNy00ODAzLTkyZGEtNmIzYmVlZDQ5N2FiIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiWjE5clpaYnZYaGRyM1pZXC9QQm1rZE9xd0pZcE5ZK0N0ZDdOeUxETkRZbnVNeXhua2JqQnVlRlFidnczdm1RdEYifQ== dlp-product: dlpe-windows dlp-version: 11.0.200.100 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v3 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 15:51:58 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Liming Gao > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ar= d Biesheuvel > Sent: Monday, June 11, 2018 3:26 PM > To: edk2-devel@lists.01.org > Cc: Kinney, Michael D ; lersek@redhat.com; Ga= o, Liming ; > leif.lindholm@linaro.org; Ard Biesheuvel > Subject: [edk2] [PATCH v3 1/2] MdePkg/BaseIoLibIntrinsic: make BaseIoLibI= ntrinsic safe for ArmVirt/KVM >=20 > 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 >=20 > 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 >=20 > and KVM produces a warning such as the following in the kernel log >=20 > kvm [17646]: load/store instruction decoding not implemented >=20 > 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. >=20 > 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. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > 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 >=20 > 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(+) >=20 > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/ArmVirtMmio.S b/Md= ePkg/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 ava= ilable > +# under the terms and conditions of the BSD License which accompanies t= his > +# 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 v= alue 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 s= pecified > +// by Value and returns Value. This function must guarantee that all MM= IO 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 MM= IO 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 MM= IO 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 MM= IO 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 ava= ilable > +; under the terms and conditions of the BSD License which accompanies t= his > +; 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 va= lue 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 sp= ecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 s= pecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 s= pecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 s= pecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 ava= ilable > +# under the terms and conditions of the BSD License which accompanies t= his > +# 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 v= alue 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 s= pecified > +// by Value and returns Value. This function must guarantee that all MM= IO 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 MM= IO 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 MM= IO 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 MM= IO 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/MdeP= kg/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 ava= ilable > +; under the terms and conditions of the BSD License which accompanies t= his > +; 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 va= lue 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 sp= ecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 s= pecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 s= pecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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 s= pecified > +; by Value and returns Value. This function must guarantee that all MMI= O 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. > +# 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 ava= ilable > +# under the terms and conditions of the BSD License which accompanies t= his > +# 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-93dd385ec48= 0 > + 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.= 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.=
> +// 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 a= vailable > +// 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" BASI= S, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS O= R 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 tha= t uses assembler routines to perform MMIO > accesses, to prevent link time code generation under LTO from emitting in= structions that KVM on ARM cannot deal with." > + > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArmVirt.c b/MdePkg/Li= brary/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.
> + 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 avai= lable > + 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 I= MPLIED. > + > +**/ > + > +#include "BaseIoLibIntrinsicInternal.h" > + > +/** > + 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. > + > + @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 spe= cified > + 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 v= alue 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 sp= ecified > + 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 v= alue 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 sp= ecified > + 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 v= alue 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 sp= ecified > + 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 re= turned. > + This function must guarantee that all I/O read 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 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 b= y 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 ar= e > + 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 ar= e > + 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 ar= e > + 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 ar= e > + 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 a= re > + 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 ar= e > + 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 a= re > + 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 ar= e > + 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 a= re > + 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 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. > + > +**/ > +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 spe= cified > + 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 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. > + > +**/ > +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 sp= ecified > + 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 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. > + > +**/ > +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 sp= ecified > + 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 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. > + > +**/ > +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 sp= ecified > + 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 >=20 > [Components.ARM, Components.AARCH64] > + MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf > MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf >=20 > [BuildOptions] > -- > 2.17.1 >=20 > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel