From patchwork Tue Jun 5 07:30:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 137699 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp630499lji; Tue, 5 Jun 2018 00:30:15 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI5uYQxni2SPMpZLxbyn1dsNF2ZWb6jewnHBDlRFNn2dkuFhIztAbstjXCs0hf6ECVAoOfY X-Received: by 2002:a62:f407:: with SMTP id r7-v6mr14989497pff.47.1528183814973; Tue, 05 Jun 2018 00:30:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528183814; cv=none; d=google.com; s=arc-20160816; b=E9cr3YwwzBruR8YGVjshdsSOlSPPaTF84nVkXmkoldPkkLwujYcHOg86RNW02DriBR 5A/KpGCdW1B6XlopcfvEj6jbr3wvzNF7DSfIM0QSILl659RcFlAn8Y2UKkw4jtAZb7+F p2K4Fagy2XEfTzM61Vq7m66iaU+p28yhK7r+669HWmxho+RjmQi1VrC3fA++0nj7aZuu lkWgAkLiak7Xt+SJ+ktdHKFWTL5rl4WiMBIEZlsGKOUf34K+2S3/N7AYQdBzr/ieMw99 OJjh1bR5xzqm7nesKC5Rc8aTDiBgCZ55KLZXKWDYWHo8YJlLXIdUTbqrDE//Rh5A9NKT xr4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=XmUaGxjQWQ/6pROaZvmhIToKem4szIv3Yh5O+LteKgE=; b=dZUAB4XMud1vpntofSomOZ93B1ynm0m0kAqWOdBb/P6RJaknDodEQ2eXH+DBFzGr5S lHOVgjakuiVeKBbvYsTCyxakZrEvzYH9hAmiWnOw2H2l95vrdrK3zoeqMJKl5ARRHYGR by3i83LxqKmwdT0HZ6wsULZ06FfZAnwhGcuDAkX1jznWETSO3EgEbTNScvoE0i/WXvpU mCRGdPNLkCOGrlL9ku4SNMPvEtMMAjYr2kHqNrGHYLYkXd7KaSLmCyQ7VzCPQvvlhxWj MSmV2+uzVlbKTD3695vYXaf5dRah2RTvcjXgtYOMFgXol6s5yJmook6jZBIJEm49pAHZ ENog== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=RuIcrigf; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id v7-v6si20407389pgb.23.2018.06.05.00.30.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Jun 2018 00:30:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=RuIcrigf; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 597332113DA13; Tue, 5 Jun 2018 00:30:14 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c0c::243; helo=mail-wr0-x243.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wr0-x243.google.com (mail-wr0-x243.google.com [IPv6:2a00:1450:400c:c0c::243]) (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 C0AE32112DF45 for ; Tue, 5 Jun 2018 00:30:12 -0700 (PDT) Received: by mail-wr0-x243.google.com with SMTP id h10-v6so1184226wrq.8 for ; Tue, 05 Jun 2018 00:30:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=aW6ooECkFheEJouHlfDsw9uBXrphxOsoXE3H4xuv1Fg=; b=RuIcrigfkBuZsa2/MTyG6Kt9zz4hz8pk0o6ER2fQfPXg5JnIp2UZTgiJOdGCG87YPS 15lirNoiQo0jypgg0rsUS0WwbBATZvXUq2iVz44RnQUwZWVf3v7y34gShUW85xlxw+jS 7p/gDfdfhk7KPhXP6vLg/SWZVtUER5Ffe8NT4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=aW6ooECkFheEJouHlfDsw9uBXrphxOsoXE3H4xuv1Fg=; b=gdIcYMQBxQoKAkJqJPd0/l/66fSIwYAW4tmV1wHBEitOl3qM/kxKuU4vxG8ezEsybx J3R1xi14JXfVWL0sKhL5tHmh/om9Z/fhsy6PJGtE+C8n+fg93bkdE6tu5AMW1gJDaFH8 Q5b7QczHGeYF4Pt7/MTmhQXI4wEHHnu6AFiqCyNDO5sKnsuKsnYDY1wiQ51mLKKCoouC bE147mkvtjqS1zQsIXrH3cDzyhjCH/QPywIoSg32+rnq0D6ZQhi0j7KF7xFYuL1NYjJ0 7LrMoD0Bya407+Ul9MBWLZ5AaH64kJ+CLNfktWoEUrWoZQHY+CeeUihz1yr8Jn9Cwltf BtNA== X-Gm-Message-State: ALKqPwevtYVIycxO+7nZRSwUBjPaj9LK/xUrqXxO0pcHVlbP6wUYSAT/ HhU2stcFS4ci42GX6RtJqUvKAj0QzIU= X-Received: by 2002:adf:8bdb:: with SMTP id w27-v6mr18978243wra.169.1528183810399; Tue, 05 Jun 2018 00:30:10 -0700 (PDT) Received: from dogfood.home ([2a01:cb1d:112:6f00:7d39:116e:c1f9:7269]) by smtp.gmail.com with ESMTPSA id x5-v6sm14760312wrr.3.2018.06.05.00.30.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Jun 2018 00:30:08 -0700 (PDT) From: Ard Biesheuvel To: edk2-devel@lists.01.org Date: Tue, 5 Jun 2018 09:30:04 +0200 Message-Id: <20180605073004.8632-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.0 Subject: [edk2] [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: , Cc: michael.d.kinney@intel.com, lersek@redhat.com, liming.gao@intel.com, leif.lindholm@linaro.org, Ard Biesheuvel MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" 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. 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(-) -- 2.17.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Acked-by: Laszlo Ersek 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