From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::244; helo=mail-wm0-x244.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x244.google.com (mail-wm0-x244.google.com [IPv6:2a00:1450:400c:c09::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A807421173C7E for ; Tue, 5 Jun 2018 01:39:58 -0700 (PDT) Received: by mail-wm0-x244.google.com with SMTP id j15-v6so3440246wme.0 for ; Tue, 05 Jun 2018 01:39:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=7MjKtvaX5y8i8+WAYaUrbIquh/KDE0Z5KxR8eI23sW8=; b=FMeU427fbQ/fMer9yvURNOBaQ1cQCyK/9YM7dPnh2LtMfWcU5hYJNjde487vUGaJxo hIPLnkbEEPnh32cKj9dWhdlKNhupvocFAT1X7m98Wc9J5lSjGdo0lPEWPTcuuAQ5+OJg mAJocsHmJaYujOnwtuaXCWQArw2KifRAaOCTw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=7MjKtvaX5y8i8+WAYaUrbIquh/KDE0Z5KxR8eI23sW8=; b=DB+QGwKCJnMYqxWNDER/pWT5HOron3xVzuCpc9nj3ifwVmFqIxfZQ7ZM19uiBSKaaC q5nrW5FHveIj37EGJtj+haGX3MuUD0YtJ6bOepxLb2dypCrWMD0lP9WdEHVwhcUBT+EP 4yHbZofY/e567Jyal3tp8EI1k6NVM9HawSrgQb0FRkgVUYYGlSdQL30LMXs1Q7cMzFaC rzQmQxM74ybHd/4xqKytC36cSt//CRuvvWiAJBmL0EkzA4YwH2kOcGP+4bh5UXtcYRTS oH44uMLsT8vLQBSSr9rmwuBCx3T5n1QvBaDBWYvcQDrlpcZN47D+9n5guWYr1mRj2kZf 9zjQ== X-Gm-Message-State: ALKqPweajnCIaIk36kOitmICSqWmHVq/n1pRXQ3NtzZaGrBeqFGwamw0 qMO9E59xvJ7f6RX8vlIOXddJhg== X-Google-Smtp-Source: ADUXVKL1UH2iJmv84Iz6uKnzwNKJYIYv79NDmeXi9PKFhy7blz3hYF0sPB8kmEjhNQInxyJ1g5F+UA== X-Received: by 2002:a1c:e0c6:: with SMTP id x189-v6mr11983939wmg.52.1528187996668; Tue, 05 Jun 2018 01:39:56 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id d9-v6sm41396594wrn.71.2018.06.05.01.39.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 05 Jun 2018 01:39:55 -0700 (PDT) Date: Tue, 5 Jun 2018 09:39:53 +0100 From: Leif Lindholm To: Ard Biesheuvel Cc: edk2-devel@lists.01.org, lersek@redhat.com, liming.gao@intel.com, michael.d.kinney@intel.com Message-ID: <20180605083953.xp6brdmduypx7ble@bivouac.eciton.net> References: <20180605073004.8632-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 In-Reply-To: <20180605073004.8632-1-ard.biesheuvel@linaro.org> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [RFC PATCH] MdePkg/BaseIoLibIntrinsic ARM AARCH64: avoid C code for MMIO access 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: Tue, 05 Jun 2018 08:39:59 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Jun 05, 2018 at 09:30:04AM +0200, Ard Biesheuvel wrote: > Even though MMIO shares the address space with ordinary memory, the > accesses involved are *not* ordinary memory accesses, and so it is > a bad idea to let the compiler generate them using pointer dereferences. > > Instead, introduce a set of internal accessors implemented in assembler, > and call those from the various Mmio[Read|Write]XX () implementations. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > Open coding the MMIO accesses is a good idea in general, but it also works > around an issue that affects EDK2 running under KVM on ARM or AARCH64, where > LTO code generation results in MMIO accesses involving instructions that cannot > be emulated by the hypervisor. I think there are arguments for and against this solution instead of disabling LTO. My main argument against this version is that it makes a re-unification of the (needlessly) different pure C implementations more tedious/questionable. It _is_ possible that the introduction of LTO makes the described semantics of the functions currently incorrect for ARM*, at which point the above reservation is irrelevant. However, the DSBs seem like a bit of a sledge hammer - all that's being mandated is serialization? Why would DMB not suffice? And if we make that change ... I would sort of prefer to see the barriers added as a separate patch, with a clear commit message - because that is not just part of the refactoring. / Leif > MdePkg/Library/BaseIoLibIntrinsic/AArch64/IoLibMmio.S | 164 ++++++++++++++++++ > MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.S | 164 ++++++++++++++++++ > MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.asm | 165 ++++++++++++++++++ > MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | 9 +- > MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c | 36 ++-- > MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.h | 179 ++++++++++++++++++++ > 6 files changed, 692 insertions(+), 25 deletions(-) > > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/AArch64/IoLibMmio.S b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/IoLibMmio.S > new file mode 100644 > index 000000000000..ac96df602f7a > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/AArch64/IoLibMmio.S > @@ -0,0 +1,164 @@ > +# > +# Copyright (c) 2014-2018, Linaro Limited. All rights reserved. > +# > +# This program and the accompanying materials are licensed and made available > +# under the terms and conditions of the BSD License which accompanies this > +# distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +# > +# > + > +.text > +.align 3 > + > +GCC_ASM_EXPORT(MmioRead8Internal) > +GCC_ASM_EXPORT(MmioWrite8Internal) > +GCC_ASM_EXPORT(MmioRead16Internal) > +GCC_ASM_EXPORT(MmioWrite16Internal) > +GCC_ASM_EXPORT(MmioRead32Internal) > +GCC_ASM_EXPORT(MmioWrite32Internal) > +GCC_ASM_EXPORT(MmioRead64Internal) > +GCC_ASM_EXPORT(MmioWrite64Internal) > + > +// > +// Reads an 8-bit MMIO register. > +// > +// Reads the 8-bit MMIO register specified by Address. The 8-bit read value is > +// returned. This function must guarantee that all MMIO read and write > +// operations are serialized. > +// > +// If 8-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to read. > +// > +// @return The value read. > +// > +ASM_PFX(MmioRead8Internal): > + ldrb w0, [x0] > + dsb ld > + ret > + > +// > +// Writes an 8-bit MMIO register. > +// > +// Writes the 8-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 8-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite8Internal): > + dsb 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] > + dsb ld > + ret > + > +// > +// Writes a 16-bit MMIO register. > +// > +// Writes the 16-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 16-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite16Internal): > + dsb 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] > + dsb ld > + ret > + > +// > +// Writes a 32-bit MMIO register. > +// > +// Writes the 32-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 32-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite32Internal): > + dsb 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] > + dsb ld > + ret > + > +// > +// Writes a 64-bit MMIO register. > +// > +// Writes the 64-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 64-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite64Internal): > + dsb st > + str x1, [x0] > + ret > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.S b/MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.S > new file mode 100644 > index 000000000000..09791951b2fd > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.S > @@ -0,0 +1,164 @@ > +# > +# Copyright (c) 2014-2018, Linaro Limited. All rights reserved. > +# > +# This program and the accompanying materials are licensed and made available > +# under the terms and conditions of the BSD License which accompanies this > +# distribution. The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +# > +# > + > +.text > +.align 3 > + > +GCC_ASM_EXPORT(MmioRead8Internal) > +GCC_ASM_EXPORT(MmioWrite8Internal) > +GCC_ASM_EXPORT(MmioRead16Internal) > +GCC_ASM_EXPORT(MmioWrite16Internal) > +GCC_ASM_EXPORT(MmioRead32Internal) > +GCC_ASM_EXPORT(MmioWrite32Internal) > +GCC_ASM_EXPORT(MmioRead64Internal) > +GCC_ASM_EXPORT(MmioWrite64Internal) > + > +// > +// Reads an 8-bit MMIO register. > +// > +// Reads the 8-bit MMIO register specified by Address. The 8-bit read value is > +// returned. This function must guarantee that all MMIO read and write > +// operations are serialized. > +// > +// If 8-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to read. > +// > +// @return The value read. > +// > +ASM_PFX(MmioRead8Internal): > + ldrb r0, [r0] > + dsb > + bx lr > + > +// > +// Writes an 8-bit MMIO register. > +// > +// Writes the 8-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 8-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite8Internal): > + dsb 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] > + dsb > + bx lr > + > +// > +// Writes a 16-bit MMIO register. > +// > +// Writes the 16-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 16-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite16Internal): > + dsb 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] > + dsb > + bx lr > + > +// > +// Writes a 32-bit MMIO register. > +// > +// Writes the 32-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 32-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite32Internal): > + dsb 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] > + dsb > + bx lr > + > +// > +// Writes a 64-bit MMIO register. > +// > +// Writes the 64-bit MMIO register specified by Address with the value specified > +// by Value and returns Value. This function must guarantee that all MMIO read > +// and write operations are serialized. > +// > +// If 64-bit MMIO register operations are not supported, then ASSERT(). > +// > +// @param Address The MMIO register to write. > +// @param Value The value to write to the MMIO register. > +// > +ASM_PFX(MmioWrite64Internal): > + dsb st > + strd r2, r3, [r0] > + bx lr > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.asm b/MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.asm > new file mode 100644 > index 000000000000..59a92962cb21 > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/Arm/IoLibMmio.asm > @@ -0,0 +1,165 @@ > +; > +; Copyright (c) 2014-2018, Linaro Limited. All rights reserved. > +; > +; This program and the accompanying materials are licensed and made available > +; under the terms and conditions of the BSD License which accompanies this > +; distribution. The full text of the license may be found at > +; http:;opensource.org/licenses/bsd-license.php > +; > +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > +; > + > + > +AREA IoLibMmio, CODE, READONLY > + > +EXPORT MmioRead8Internal > +EXPORT MmioWrite8Internal > +EXPORT MmioRead16Internal > +EXPORT MmioWrite16Internal > +EXPORT MmioRead32Internal > +EXPORT MmioWrite32Internal > +EXPORT MmioRead64Internal > +EXPORT MmioWrite64Internal > + > +; > +; Reads an 8-bit MMIO register. > +; > +; Reads the 8-bit MMIO register specified by Address. The 8-bit read value is > +; returned. This function must guarantee that all MMIO read and write > +; operations are serialized. > +; > +; If 8-bit MMIO register operations are not supported, then ASSERT(). > +; > +; @param Address The MMIO register to read. > +; > +; @return The value read. > +; > +MmioRead8Internal > + ldrb r0, [r0] > + dsb > + 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 > + dsb st > + strb r1, [r0] > + bx lr > + > +; > +; Reads a 16-bit MMIO register. > +; > +; Reads the 16-bit MMIO register specified by Address. The 16-bit read value is > +; returned. This function must guarantee that all MMIO read and write > +; operations are serialized. > +; > +; If 16-bit MMIO register operations are not supported, then ASSERT(). > +; > +; @param Address The MMIO register to read. > +; > +; @return The value read. > +; > +MmioRead16Internal > + ldrh r0, [r0] > + dsb > + 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 > + dsb st > + strh r1, [r0] > + bx lr > + > +; > +; Reads a 32-bit MMIO register. > +; > +; Reads the 32-bit MMIO register specified by Address. The 32-bit read value is > +; returned. This function must guarantee that all MMIO read and write > +; operations are serialized. > +; > +; If 32-bit MMIO register operations are not supported, then ASSERT(). > +; > +; @param Address The MMIO register to read. > +; > +; @return The value read. > +; > +MmioRead32Internal > + ldr r0, [r0] > + dsb > + 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 > + dsb st > + str r1, [r0] > + bx lr > + > +; > +; Reads a 64-bit MMIO register. > +; > +; Reads the 64-bit MMIO register specified by Address. The 64-bit read value is > +; returned. This function must guarantee that all MMIO read and write > +; operations are serialized. > +; > +; If 64-bit MMIO register operations are not supported, then ASSERT(). > +; > +; @param Address The MMIO register to read. > +; > +; @return The value read. > +; > +MmioRead64Internal > + ldrd r0, r1, [r0] > + dsb > + 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 > + dsb st > + strd r2, r3, [r0] > + bx lr > + > + END > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf > index 8844b1ce4c2b..22813098e97a 100644 > --- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf > +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf > @@ -61,11 +61,16 @@ [Sources.EBC] > [Sources.IPF] > IoLibIpf.c > > -[Sources.ARM] > +[Sources.ARM, Sources.AARCH64] > IoLibArm.c > + IoLibArm.h > + > +[Sources.ARM] > + Arm/IoLibMmio.S | GCC > + Arm/IoLibMmio.asm | RVCT > > [Sources.AARCH64] > - IoLibArm.c > + AArch64/IoLibMmio.S > > [Packages] > MdePkg/MdePkg.dec > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c > index 5ce12ca56ae2..449bc5ebbf85 100644 > --- a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c > +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.c > @@ -20,6 +20,7 @@ > // Include common header file for this module. > // > #include "BaseIoLibIntrinsicInternal.h" > +#include "IoLibArm.h" > > /** > Reads an 8-bit I/O port. > @@ -411,10 +412,7 @@ MmioRead8 ( > IN UINTN Address > ) > { > - UINT8 Value; > - > - Value = *(volatile UINT8*)Address; > - return Value; > + return MmioRead8Internal (Address); > } > > /** > @@ -437,7 +435,7 @@ MmioWrite8 ( > IN UINT8 Value > ) > { > - *(volatile UINT8*)Address = Value; > + MmioWrite8Internal (Address, Value); > return Value; > } > > @@ -461,11 +459,7 @@ MmioRead16 ( > IN UINTN Address > ) > { > - UINT16 Value; > - > - ASSERT ((Address & 1) == 0); > - Value = *(volatile UINT16*)Address; > - return Value; > + return MmioRead16Internal (Address); > } > > /** > @@ -489,7 +483,8 @@ MmioWrite16 ( > ) > { > ASSERT ((Address & 1) == 0); > - *(volatile UINT16*)Address = Value; > + > + MmioWrite16Internal (Address, Value); > return Value; > } > > @@ -513,11 +508,7 @@ MmioRead32 ( > IN UINTN Address > ) > { > - UINT32 Value; > - > - ASSERT ((Address & 3) == 0); > - Value = *(volatile UINT32*)Address; > - return Value; > + return MmioRead32Internal (Address); > } > > /** > @@ -541,7 +532,8 @@ MmioWrite32 ( > ) > { > ASSERT ((Address & 3) == 0); > - *(volatile UINT32*)Address = Value; > + > + MmioWrite32Internal (Address, Value); > return Value; > } > > @@ -565,11 +557,9 @@ MmioRead64 ( > IN UINTN Address > ) > { > - UINT64 Value; > - > ASSERT ((Address & 7) == 0); > - Value = *(volatile UINT64*)Address; > - return Value; > + > + return MmioRead64Internal (Address); > } > > /** > @@ -593,7 +583,7 @@ MmioWrite64 ( > ) > { > ASSERT ((Address & 7) == 0); > - *(volatile UINT64*)Address = Value; > + > + MmioWrite64Internal (Address, Value); > return Value; > } > - > diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.h b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.h > new file mode 100644 > index 000000000000..6c63d0b5545b > --- /dev/null > +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibArm.h > @@ -0,0 +1,179 @@ > +/** @file > + Internal MMIO routines implemented in ARM assembler > + > + 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. > + > +**/ > + > +#ifndef __BASEIOLIBINTRINSIC_IOLIBARM_H_ > +#define __BASEIOLIBINTRINSIC_IOLIBARM_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. > + > + If 8-bit MMIO register operations are not supported, then ASSERT(). > + > + @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. 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. > + > +**/ > +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. > + > + If 16-bit MMIO register operations are not supported, then ASSERT(). > + > + @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. 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. > + > +**/ > +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. > + > + If 32-bit MMIO register operations are not supported, then ASSERT(). > + > + @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. 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. > + > +**/ > +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. > + > + If 64-bit MMIO register operations are not supported, then ASSERT(). > + > + @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. 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. > + > +**/ > +VOID > +EFIAPI > +MmioWrite64Internal ( > + IN UINTN Address, > + IN UINT64 Value > + ); > + > +#endif > -- > 2.17.0 >