From patchwork Wed Feb 21 15:25:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leif Lindholm X-Patchwork-Id: 129081 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp746491ljc; Wed, 21 Feb 2018 07:25:33 -0800 (PST) X-Google-Smtp-Source: AH8x2261kpyjFirSoHEjnKOBI4CJTINrufolaPQ692drL8y1jgiavpBv3SxNYIUJCatdHhSwT9Ik X-Received: by 2002:a17:902:a5c5:: with SMTP id t5-v6mr3596448plq.160.1519226733743; Wed, 21 Feb 2018 07:25:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519226733; cv=none; d=google.com; s=arc-20160816; b=uLNeKFmQBCQ3Sb65UGDz0+Hr8+y1G5ES/VyLfQb45arKVy1Oi5ik6mTqvGIq7gR3Cm prQZJX6dnWsQflMBKfun+m6nwKR5eWgt0v6e7HeS+fmmwT6zoebr8o93crU2/szliJCc 6oJ0uIs1onK+uXGLPLL0aGzZ/6+5/L3dO4itNWeynp9irzKGlRP5qGLwq+EeRtZAGO3h ljgdzcslUUiNtsvrq1/xRKoxieKKpb+o4MMLy5jCRKDYhJmafTAbqMT2wQ80EiES4PxD qkMenzhejcT+yh3vBkZpdMNiqvgWbuNFUQ67KyLd4kU54uCMH7oS8thgz2JTSWWR3EeY HQbA== 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=1P11ZtVudspolcx/ShwvfTXm2oiQjd7p9JrxL35lifk=; b=N+qC0bxfbEvfuAAMLUxBye8tC64VeV2p9V21pmDqvcnOkfH+AlR4daqx5szHingbG8 EBsnC4j6Ka9wnbPVq2MgUcXBwyPWoSAKVTDGshAHPEPt2w52vu/qAKz1NVh3kSGR8bqf Wrt0FLYOpKQ4JIk+OPsV0Eb7yWhw3NtAqir+7mPJwslD/5XaKHv/jT2I5vX5tziLlmjq q5mz+LVHyinwG7BLkOCk6JHOqmaJctBEM5NokFZ3ns3un95n16uFxo9dBOwIIqNnArwE VedVfguYhLcTXg/dZzjGF9gRPNyTyV05Gwijgo89fAPy2igjxdD57ru72NFx6f7Cvz4I +p0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DFQOCFfl; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 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. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id j9si43250pgc.72.2018.02.21.07.25.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 07:25:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DFQOCFfl; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 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 4EE0B220F33DA; Wed, 21 Feb 2018 07:19:33 -0800 (PST) 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=leif.lindholm@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 EC046223C1783 for ; Wed, 21 Feb 2018 07:19:30 -0800 (PST) Received: by mail-wr0-x243.google.com with SMTP id z12so5580156wrg.4 for ; Wed, 21 Feb 2018 07:25:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=pZ/wS4QbYs8l4hfNEL3vfMSMTPurwtyDaSA8RAED7t0=; b=DFQOCFfliao3VCDYWIrT4K3XwiZ0DSFR3BVsjCAU2yqeWO44Cz6bvbxMkUM7cukamN FTi8mJcPOaSqrqwfsMkJZyCzk6fbxsK8jaHp2uEOiw6BLhqeyGNDrPuI7h/+Jh3uJCRF 497Dc0K1HHGuWc0a0SH1+8TLfi9tHBEA5Qtmw= 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=pZ/wS4QbYs8l4hfNEL3vfMSMTPurwtyDaSA8RAED7t0=; b=Cv8+v6r6ItcRrMTpMgEybUhGxk+qWfOG5LvsF96dcwwJSh0nugnOcdg4EIAmTdMVLJ ahoKRHAPcmpjpdSIuTzqPQXaV4rD1yOIFDNR6p0wAkQMWTGdLWXEWDGtMuxfwURu1fcW Rlu1lYpSF8kvDdw0rrvXbgfb6RrVlNwKs6ZfMYFEXwc3wir+Rx7AiFkdVylVgjzV7RAX Ek5cJ8dAhUWw1EX5z16YF5osJABmAyDCHixqMX/15erFBvkY0qlAPcGRocIapFemnBK6 7RIsXjT/hGCouxb42wfSp8K4yOMrxj3BN7Gz5H55N+rqdlD0kEGrQ950F/R0QIAdIv4X mVTw== X-Gm-Message-State: APf1xPCCn96NAiuDxRp4F8EypzqtwunyxYzvxcArRZYiGuax94h5ROUk 4qVmMeUwv+Ts9aMFqEacVZW5EjN0Kbo= X-Received: by 10.28.11.147 with SMTP id 141mr2312112wml.138.1519226727484; Wed, 21 Feb 2018 07:25:27 -0800 (PST) Received: from vanye.hemma.eciton.net (cpc92316-cmbg19-2-0-cust118.5-4.cable.virginm.net. [82.12.0.119]) by smtp.gmail.com with ESMTPSA id e5sm28055972wre.51.2018.02.21.07.25.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2018 07:25:26 -0800 (PST) From: Leif Lindholm To: edk2-devel@lists.01.org Date: Wed, 21 Feb 2018 15:25:25 +0000 Message-Id: <20180221152525.23449-1-leif.lindholm@linaro.org> X-Mailer: git-send-email 2.11.0 Subject: [edk2] [RFC PATCH] MdePkg: add byte-swapping MMIO BaseIoLibSwap X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ard.biesheuvel@linaro.org, Liming Gao , Michael D Kinney MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" When performing MMIO to a destination of the opposite endianness to the executing processor, this library provides automatic byte order reversal on inputs and outputs. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Leif Lindholm --- As promised in the dark and distant past: https://www.mail-archive.com/edk2-devel@lists.01.org/msg33447.html This starts out as a clone of MdePkg/Include/Library/IoLib.h, implementing simple wrappers that depend on an IoLib instance to perform any actual accesses. Comments are mostly nonsense, since they've not been changed from their originals in IoLib.h. If people feel this library is a sensible approach, I'll fix that up before I send a v1. I have explicitly excluded: - non-MMIO accesses (could you really end up with mixed endianness in such a system?) - bitfields (would either require duplicating code or merging this all into the BaseIoLibIntrinsic module, which is already a bit on the bloated side) - buffers operations (let's avoid those until we find we need them) MdePkg/Include/Library/IoLibSwap.h | 395 ++++++++++++++++++++ MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.inf | 44 +++ MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.uni | 23 ++ MdePkg/Library/BaseIoLibSwap/IoLibSwap.c | 491 +++++++++++++++++++++++++ MdePkg/MdePkg.dec | 3 + MdePkg/MdePkg.dsc | 1 + 6 files changed, 957 insertions(+) create mode 100644 MdePkg/Include/Library/IoLibSwap.h create mode 100644 MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.inf create mode 100644 MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.uni create mode 100644 MdePkg/Library/BaseIoLibSwap/IoLibSwap.c -- 2.11.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/MdePkg/Include/Library/IoLibSwap.h b/MdePkg/Include/Library/IoLibSwap.h new file mode 100644 index 0000000000..f13c8d86e7 --- /dev/null +++ b/MdePkg/Include/Library/IoLibSwap.h @@ -0,0 +1,395 @@ +/** @file + Provide byte-swapping services to access MMIO registers. + +Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+Copyright (c) 2018, Linaro ltd. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies 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 __IO_LIB_SWAP_H__ +#define __IO_LIB_SWAP_H__ + +/** + 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +SwapMmioRead16 ( + IN UINTN Address + ); + +/** + Writes a 16-bit MMIO register. + + Writes the 16-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT16 +EFIAPI +SwapMmioWrite16 ( + IN UINTN Address, + IN UINT16 Value + ); + +/** + Reads a 16-bit MMIO register, performs a bitwise OR, and writes the + result back to the 16-bit MMIO register. + + Reads the 16-bit MMIO register specified by Address, performs a bitwise + OR between the read result and the value specified by OrData, and + writes the result to the 16-bit MMIO register specified by Address. The value + written to the MMIO register 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param OrData The value to OR with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT16 +EFIAPI +SwapMmioOr16 ( + IN UINTN Address, + IN UINT16 OrData + ); + +/** + Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result + back to the 16-bit MMIO register. + + Reads the 16-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, and writes the + result to the 16-bit MMIO register specified by Address. The value written to + the MMIO register 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT16 +EFIAPI +SwapMmioAnd16 ( + IN UINTN Address, + IN UINT16 AndData + ); + +/** + Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 16-bit MMIO register. + + Reads the 16-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, performs a + bitwise OR between the result of the AND operation and the value specified by + OrData, and writes the result to the 16-bit MMIO register specified by + Address. The value written to the MMIO register 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MMIO register. + +**/ +UINT16 +EFIAPI +SwapMmioAndThenOr16 ( + IN UINTN Address, + IN UINT16 AndData, + IN UINT16 OrData + ); + +/** + 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +SwapMmioRead32 ( + IN UINTN Address + ); + +/** + Writes a 32-bit MMIO register. + + Writes the 32-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT32 +EFIAPI +SwapMmioWrite32 ( + IN UINTN Address, + IN UINT32 Value + ); + +/** + Reads a 32-bit MMIO register, performs a bitwise OR, and writes the + result back to the 32-bit MMIO register. + + Reads the 32-bit MMIO register specified by Address, performs a bitwise + OR between the read result and the value specified by OrData, and + writes the result to the 32-bit MMIO register specified by Address. The value + written to the MMIO register 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param OrData The value to OR with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT32 +EFIAPI +SwapMmioOr32 ( + IN UINTN Address, + IN UINT32 OrData + ); + +/** + Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result + back to the 32-bit MMIO register. + + Reads the 32-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, and writes the + result to the 32-bit MMIO register specified by Address. The value written to + the MMIO register 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT32 +EFIAPI +SwapMmioAnd32 ( + IN UINTN Address, + IN UINT32 AndData + ); + +/** + Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 32-bit MMIO register. + + Reads the 32-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, performs a + bitwise OR between the result of the AND operation and the value specified by + OrData, and writes the result to the 32-bit MMIO register specified by + Address. The value written to the MMIO register 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MMIO register. + +**/ +UINT32 +EFIAPI +SwapMmioAndThenOr32 ( + IN UINTN Address, + IN UINT32 AndData, + IN UINT32 OrData + ); + +/** + 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +SwapMmioRead64 ( + IN UINTN Address + ); + +/** + Writes a 64-bit MMIO register. + + Writes the 64-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioWrite64 ( + IN UINTN Address, + IN UINT64 Value + ); + +/** + Reads a 64-bit MMIO register, performs a bitwise OR, and writes the + result back to the 64-bit MMIO register. + + Reads the 64-bit MMIO register specified by Address, performs a bitwise + OR between the read result and the value specified by OrData, and + writes the result to the 64-bit MMIO register specified by Address. The value + written to the MMIO register 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param OrData The value to OR with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioOr64 ( + IN UINTN Address, + IN UINT64 OrData + ); + +/** + Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result + back to the 64-bit MMIO register. + + Reads the 64-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, and writes the + result to the 64-bit MMIO register specified by Address. The value written to + the MMIO register 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioAnd64 ( + IN UINTN Address, + IN UINT64 AndData + ); + +/** + Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 64-bit MMIO register. + + Reads the 64-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, performs a + bitwise OR between the result of the AND operation and the value specified by + OrData, and writes the result to the 64-bit MMIO register specified by + Address. The value written to the MMIO register 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioAndThenOr64 ( + IN UINTN Address, + IN UINT64 AndData, + IN UINT64 OrData + ); + +#endif + diff --git a/MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.inf b/MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.inf new file mode 100644 index 0000000000..59d774dc97 --- /dev/null +++ b/MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.inf @@ -0,0 +1,44 @@ +## @file +# Byte swapping I/O Library. +# +# Byte swapping I/O Library for all architectures. Only MMIO supported. I/O +# accesses take place through the normal IoLib, but values read and written +# are byte-reversed to interact with peripherals of non-native endianness. +# +# 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.
+# +# 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. +# +## + +[Defines] + INF_VERSION = 0x0001001a + BASE_NAME = BaseIoLibSwap + MODULE_UNI_FILE = BaseIoLibSwap.uni + FILE_GUID = 073c3fbd-ff0d-41b6-a209-1e42fd2a3bab + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = IoLibSwap + + +# +# VALID_ARCHITECTURES = IA32 X64 EBC IPF ARM AARCH64 +# + +[Sources] + IoLibSwap.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib +# DebugLib + IoLib diff --git a/MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.uni b/MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.uni new file mode 100644 index 0000000000..e35b4abef7 --- /dev/null +++ b/MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.uni @@ -0,0 +1,23 @@ +// /** @file +// Byte swapping I/O Library. +// +// Byte swapping I/O Library for all architectures. Only MMIO supported. I/O +// accesses take place through the normal IoLib, but values read and written +// are byte-reversed to interact with peripherals of non-native endianness. +// +// Copyright (c) 2018, Linaro ltd. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php. +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Byte swapping I/O Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Byte swapping I/O Library for all architectures. Only MMIO supported. I/O accesses take place through the normal IoLib, but values read and written are byte-reversed to interact with peripherals of non-native endianness." + diff --git a/MdePkg/Library/BaseIoLibSwap/IoLibSwap.c b/MdePkg/Library/BaseIoLibSwap/IoLibSwap.c new file mode 100644 index 0000000000..6eb675de20 --- /dev/null +++ b/MdePkg/Library/BaseIoLibSwap/IoLibSwap.c @@ -0,0 +1,491 @@ +/** @file + Provide byte-swapping services to access MMIO registers. + +Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+Copyright (c) 2018, Linaro ltd. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies 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. + +**/ + +#include +#include + +/** + 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT16 +EFIAPI +SwapMmioRead16 ( + IN UINTN Address + ) +{ + return SwapBytes16 (MmioRead16 (Address)); +} + +/** + Writes a 16-bit MMIO register. + + Writes the 16-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 16-bit MMIO register operations are not supported, then ASSERT(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT16 +EFIAPI +SwapMmioWrite16 ( + IN UINTN Address, + IN UINT16 Value + ) +{ + (VOID) MmioWrite16 (Address, SwapBytes16 (Value)); + + return Value; +} + +/** + Reads a 16-bit MMIO register, performs a bitwise OR, and writes the + result back to the 16-bit MMIO register. + + Reads the 16-bit MMIO register specified by Address, performs a bitwise + OR between the read result and the value specified by OrData, and + writes the result to the 16-bit MMIO register specified by Address. The value + written to the MMIO register 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param OrData The value to OR with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT16 +EFIAPI +SwapMmioOr16 ( + IN UINTN Address, + IN UINT16 OrData + ) +{ + UINT16 Value; + + Value = SwapMmioRead16 (Address); + Value |= OrData; + + return SwapMmioWrite16 (Address, Value); +} + +/** + Reads a 16-bit MMIO register, performs a bitwise AND, and writes the result + back to the 16-bit MMIO register. + + Reads the 16-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, and writes the + result to the 16-bit MMIO register specified by Address. The value written to + the MMIO register 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT16 +EFIAPI +SwapMmioAnd16 ( + IN UINTN Address, + IN UINT16 AndData + ) +{ + UINT16 Value; + + Value = SwapMmioRead16 (Address); + Value &= AndData; + + return SwapMmioWrite16 (Address, Value); +} + +/** + Reads a 16-bit MMIO register, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 16-bit MMIO register. + + Reads the 16-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, performs a + bitwise OR between the result of the AND operation and the value specified by + OrData, and writes the result to the 16-bit MMIO register specified by + Address. The value written to the MMIO register 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(). + If Address is not aligned on a 16-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MMIO register. + +**/ +UINT16 +EFIAPI +SwapMmioAndThenOr16 ( + IN UINTN Address, + IN UINT16 AndData, + IN UINT16 OrData + ) +{ + UINT16 Value; + + Value = SwapMmioRead16 (Address); + Value &= AndData; + Value |= OrData; + + return SwapMmioWrite16 (Address, 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +SwapMmioRead32 ( + IN UINTN Address + ) +{ + return SwapBytes32 (MmioRead32 (Address)); +} + +/** + Writes a 32-bit MMIO register. + + Writes the 32-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 32-bit MMIO register operations are not supported, then ASSERT(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + + @return Value. + +**/ +UINT32 +EFIAPI +SwapMmioWrite32 ( + IN UINTN Address, + IN UINT32 Value + ) +{ + (VOID) MmioWrite32 (Address, SwapBytes32 (Value)); + + return Value; +} + +/** + Reads a 32-bit MMIO register, performs a bitwise OR, and writes the + result back to the 32-bit MMIO register. + + Reads the 32-bit MMIO register specified by Address, performs a bitwise + OR between the read result and the value specified by OrData, and + writes the result to the 32-bit MMIO register specified by Address. The value + written to the MMIO register 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param OrData The value to OR with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT32 +EFIAPI +SwapMmioOr32 ( + IN UINTN Address, + IN UINT32 OrData + ) +{ + UINT32 Value; + + Value = SwapMmioRead32 (Address); + Value |= OrData; + + return SwapMmioWrite32 (Address, Value); +} + +/** + Reads a 32-bit MMIO register, performs a bitwise AND, and writes the result + back to the 32-bit MMIO register. + + Reads the 32-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, and writes the + result to the 32-bit MMIO register specified by Address. The value written to + the MMIO register 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT32 +EFIAPI +SwapMmioAnd32 ( + IN UINTN Address, + IN UINT32 AndData + ) +{ + UINT32 Value; + + Value = SwapMmioRead32 (Address); + Value &= AndData; + + return SwapMmioWrite32 (Address, Value); +} + +/** + Reads a 32-bit MMIO register, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 32-bit MMIO register. + + Reads the 32-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, performs a + bitwise OR between the result of the AND operation and the value specified by + OrData, and writes the result to the 32-bit MMIO register specified by + Address. The value written to the MMIO register 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(). + If Address is not aligned on a 32-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MMIO register. + +**/ +UINT32 +EFIAPI +SwapMmioAndThenOr32 ( + IN UINTN Address, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + UINT32 Value; + + Value = SwapMmioRead32 (Address); + Value &= AndData; + Value |= OrData; + + return SwapMmioWrite32 (Address, 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to read. + + @return The value read. + +**/ +UINT64 +EFIAPI +SwapMmioRead64 ( + IN UINTN Address + ) +{ + return SwapBytes64 (MmioRead64 (Address)); +} + +/** + Writes a 64-bit MMIO register. + + Writes the 64-bit MMIO register specified by Address with the value specified + by Value and returns Value. This function must guarantee that all MMIO read + and write operations are serialized. + + If 64-bit MMIO register operations are not supported, then ASSERT(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param Value The value to write to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioWrite64 ( + IN UINTN Address, + IN UINT64 Value + ) +{ + (VOID) MmioWrite64 (Address, SwapBytes64 (Value)); + + return Value; +} + +/** + Reads a 64-bit MMIO register, performs a bitwise OR, and writes the + result back to the 64-bit MMIO register. + + Reads the 64-bit MMIO register specified by Address, performs a bitwise + OR between the read result and the value specified by OrData, and + writes the result to the 64-bit MMIO register specified by Address. The value + written to the MMIO register 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param OrData The value to OR with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioOr64 ( + IN UINTN Address, + IN UINT64 OrData + ) +{ + UINT64 Value; + + Value = SwapMmioRead64 (Address); + Value |= OrData; + + return SwapMmioWrite64 (Address, Value); +} + +/** + Reads a 64-bit MMIO register, performs a bitwise AND, and writes the result + back to the 64-bit MMIO register. + + Reads the 64-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, and writes the + result to the 64-bit MMIO register specified by Address. The value written to + the MMIO register 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + + @return The value written back to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioAnd64 ( + IN UINTN Address, + IN UINT64 AndData + ) +{ + UINT64 Value; + + Value = SwapMmioRead64 (Address); + Value &= AndData; + + return SwapMmioWrite64 (Address, Value); +} + +/** + Reads a 64-bit MMIO register, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 64-bit MMIO register. + + Reads the 64-bit MMIO register specified by Address, performs a bitwise AND + between the read result and the value specified by AndData, performs a + bitwise OR between the result of the AND operation and the value specified by + OrData, and writes the result to the 64-bit MMIO register specified by + Address. The value written to the MMIO register 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(). + If Address is not aligned on a 64-bit boundary, then ASSERT(). + + @param Address The MMIO register to write. + @param AndData The value to AND with the read value from the MMIO register. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MMIO register. + +**/ +UINT64 +EFIAPI +SwapMmioAndThenOr64 ( + IN UINTN Address, + IN UINT64 AndData, + IN UINT64 OrData + ) +{ + UINT64 Value; + + Value = SwapMmioRead64 (Address); + Value &= AndData; + Value |= OrData; + + return SwapMmioWrite64 (Address, Value); +} diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 0e64f22f4a..98016f47e9 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -160,6 +160,9 @@ [LibraryClasses] ## @libraryclass Provide services to access I/O Ports and MMIO registers. IoLib|Include/Library/IoLib.h + ## @libraryclass Provide byte-swapping services to access MMIO registers. + IoLibSwap|Include/Library/IoLibSwap.h + ## @libraryclass Provide services to create, get and update HSTI table in AIP protocol. HstiLib|Include/Library/HstiLib.h diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 60efd722e9..a2f2696394 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -60,6 +60,7 @@ [Components] MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + MdePkg/Library/BaseIoLibSwap/BaseIoLibSwap.inf MdePkg/Library/BaseLib/BaseLib.inf MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf