From: Laszlo Ersek <lersek@redhat.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>, edk2-devel@lists.01.org
Cc: leif.lindholm@linaro.org, liming.gao@intel.com,
michael.d.kinney@intel.com
Subject: Re: [RFC PATCH] MdePkg/BaseIoLibIntrinsic ARM AARCH64: avoid C code for MMIO access
Date: Tue, 5 Jun 2018 10:42:26 +0200 [thread overview]
Message-ID: <13e35e1d-dc05-2c0c-13a3-c7a6c350d563@redhat.com> (raw)
In-Reply-To: <20180605073004.8632-1-ard.biesheuvel@linaro.org>
On 06/05/18 09:30, 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.
I think I slightly disagree with the wording here. Using
volatile-qualified pointers (implying compiler barriers), possibly
combined with CPU barriers (wrapped into C functions), seems valid in
both practice and on the ISO C level. "volatile" does not guarantee
atomicity, but an IoLib instance can still assume that, if it is tied to
a specific toolchain, and the toolchain guarantees atomicity. Anyway:
>
> 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 <ard.biesheuvel@linaro.org>
> ---
> 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.
edk2 code (and developers!) are generally conscious about this issue,
and call the IoLib APIs carefully. Thus, I believe that, with this
patch, we can address the problem in edk2 "for good" -- we can trust
that all such accesses will go through a few "choke points", and we can
add the work-arounds to the "choke points". (This is exactly what I
believe we aren't certain about with regard to the Linux kernel.)
Therefore I welcome the patch! I just think the commit message should
name the KVM workaround as the primary reason. The C code is not wrong
(knowing the compiler), and the generated assembly is also not wrong on
the bare metal.
I don't insist though that you update the commit message; I prefer
working code to documentation that's polished to my taste. :)
Acked-by: Laszlo Ersek <lersek@redhat.com>
Thank you!
Laszlo
>
> 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.<BR>
> +
> + This program and the accompanying materials are licensed and made available
> + under the terms and conditions of the BSD License which accompanies this
> + distribution. The full text of the license may be found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#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
>
next prev parent reply other threads:[~2018-06-05 8:42 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-05 7:30 [RFC PATCH] MdePkg/BaseIoLibIntrinsic ARM AARCH64: avoid C code for MMIO access Ard Biesheuvel
2018-06-05 8:39 ` Leif Lindholm
2018-06-05 10:48 ` Ard Biesheuvel
2018-06-05 8:42 ` Laszlo Ersek [this message]
2018-06-05 8:55 ` Bhupesh Sharma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=13e35e1d-dc05-2c0c-13a3-c7a6c350d563@redhat.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox