From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-x244.google.com (mail-pg0-x244.google.com [IPv6:2607:f8b0:400e:c05::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id F333221DFA901 for ; Sun, 2 Apr 2017 15:45:12 -0700 (PDT) Received: by mail-pg0-x244.google.com with SMTP id 79so25712832pgf.0 for ; Sun, 02 Apr 2017 15:45:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=philjordan-eu.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=9mEkj7Qbqad00+9Avdrq14wzDWhYEgTVxlvR4gnuPtM=; b=gIokupe43JDkvSIX06s4/RO986+mvD4lWgs0DRZoeAphWv9XYjmh3v6p3CXgxEXp0D iVa7REJJQD3nBxeY9Qit/9sj0J1Na+Eio39TGEzlk6Mi6/DVIGgxD2IBs7LvrtxhYq5Z qOE35DEeY/DO1sMEhqJPJeBm3szd7vZqybFzaUxUG05ySfbscgWN7OZIekmF6Legw3qe aYirnc7cg08q0lz+CFsjlyCQHfAf9BH4tTda/8dmSLdzVh04xe0ma6ArHK3KASntNLvi PsdhlTW4vVANUqrY9OSzIPEMQ6cm2iVLsO0d6DAJ7X3iOD9xBcvQ+/I3dFAFnhWBft3F VI0A== 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:in-reply-to :references; bh=9mEkj7Qbqad00+9Avdrq14wzDWhYEgTVxlvR4gnuPtM=; b=pNreEoGMJftJksXTE6+osYarqwgTPGl5V4+5ZIEzBU+1j4o5wRLSiyjTzQPv7BeqhF JQu8bzBdfi1PY6QAUMnqxtpNhDBjaIOhq58Tm7Mh9fmWnP8np6EIEkUgEKafhane+4VT P+/SaRQ7K6DGPDlkdfrQEyXkZv4WWPH2JJru0AJLCwoBitYstueZZSBS0EvQnHhERXyf 6/EhvloeJ7luelkof7k6w0qJXGlOoCZKldD0bt2S4TDkJxIlS+TGdWVLmF1ysOqVpKyV 2wt2zOY3K04Jbvvt7mPVrr17QZpR4FNq6C6i3IzxGYIcMU08jV79yadtsuJfs2iZKBoj uhkw== X-Gm-Message-State: AFeK/H2RgGZNgQ7YDmp8BWxKIx/Yvj85IXzFFT2k1E28fjVGYLnv+rFZTyqBsQLtxjj8DA== X-Received: by 10.99.122.22 with SMTP id v22mr15099668pgc.226.1491173112413; Sun, 02 Apr 2017 15:45:12 -0700 (PDT) Received: from localhost.localdomain ([210.246.60.121]) by smtp.gmail.com with ESMTPSA id l127sm21891336pga.7.2017.04.02.15.45.09 (version=TLS1 cipher=AES128-SHA bits=128/128); Sun, 02 Apr 2017 15:45:11 -0700 (PDT) From: Phil Dennis-Jordan To: edk2-devel@lists.01.org Cc: Phil Dennis-Jordan , Jordan Justen , Laszlo Ersek Date: Mon, 3 Apr 2017 10:44:56 +1200 Message-Id: <1491173097-37305-3-git-send-email-lists@philjordan.eu> X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1491173097-37305-1-git-send-email-lists@philjordan.eu> References: <1491173097-37305-1-git-send-email-lists@philjordan.eu> Subject: [PATCH v2 2/3] OvmfPkg/QemuVideoDxe: Helper functions for unaligned port I/O. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Apr 2017 22:45:13 -0000 From: Phil Dennis-Jordan The VMWare SVGA2 display device implemented by Qemu (-vga vmware) uses an I/O-type BAR which is laid out such that some register offsets are not aligned to the read/write width with which they are expected to be accessed. (The register value port has an offset of 1 and requires 32 bit wide read/write access.) The EFI_PCI_IO_PROTOCOL's Pci.Read/Pci.Write functions do not support such unaligned I/O. Before a driver for this device can be added to QemuVideoDxe, helper functions for unaligned I/O are therefore required. This adds the functions UnalignedIoWrite32 and UnalignedIoRead32, based on IoLib's IoWrite32 and Read32, for the Ia32 and X64 architectures. Port I/O requires inline assembly, so implementations are provided for the GCC, ICC, and Microsoft compiler families. Such I/O is not possible on other architectures, a dummy (ASSERT()ing) implementation is therefore provided to satisfy the linker. Cc: Jordan Justen Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Phil Dennis-Jordan --- Notes: v2: - Separate commit for the unaligned I/O helper functions. [Laszlo] - Dummy implementations return values despite ASSERT(). [Laszlo] - Build failure in ArmVirtPkg fixed. [Laszlo] - More consistent API docs and function ordering. OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 6 ++ OvmfPkg/QemuVideoDxe/UnalignedIoInternal.h | 59 ++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c | 69 +++++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c | 79 +++++++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoMsc.c | 81 ++++++++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c | 65 ++++++++++++++++ 6 files changed, 359 insertions(+) diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf index affb6ffd88e0..346a5aed94fa 100644 --- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf @@ -41,6 +41,12 @@ [Sources.common] [Sources.Ia32, Sources.X64] VbeShim.c + UnalignedIoGcc.c | GCC + UnalignedIoMsc.c | MSFT + UnalignedIoIcc.c | INTEL + +[Sources.IPF, Sources.EBC, Sources.ARM, Sources.AARCH64] + UnalignedIoUnsupported.c [Packages] MdePkg/MdePkg.dec diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoInternal.h b/OvmfPkg/QemuVideoDxe/UnalignedIoInternal.h new file mode 100644 index 000000000000..a069f3b98087 --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoInternal.h @@ -0,0 +1,59 @@ +/** @file + Unaligned port I/O, with implementations for various x86 compilers and a dummy + for platforms which do not support unaligned port I/O. + + Copyright (c) 2017, Phil Dennis-Jordan.
+ 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 _UNALIGNED_IO_INTERNAL_H_ +#define _UNALIGNED_IO_INTERNAL_H_ + +/** + Performs a 32-bit write to the specified, possibly unaligned I/O-type address. + + Writes the 32-bit I/O port specified by Port with the value specified by Value + and returns Value. This function must guarantee that all I/O read and write + operations are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port I/O port address + @param[in] Value 32-bit word to write + + @return The value written to the I/O port. + +**/ +UINT32 +UnalignedIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ); + +/** + Reads 32-bit word from the specified, possibly unaligned I/O-type address. + + Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned. + This function must guarantee that all I/O read and write operations are + serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port I/O port from which to read. + + @return The value read from the specified location. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ); + +#endif diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c b/OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c new file mode 100644 index 000000000000..8bb74c784c06 --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c @@ -0,0 +1,69 @@ +/** @file + Unaligned Port I/O. This file has compiler specifics for GCC as there is no + ANSI C standard for doing IO. + + Based on IoLibGcc.c. + + Copyright (c) 2006 - 2010, Intel Corporation. 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 "UnalignedIoInternal.h" + +/** + Performs a 32-bit write to the specified, possibly unaligned I/O-type address. + + Writes the 32-bit I/O port specified by Port with the value specified by Value + and returns Value. This function must guarantee that all I/O read and write + operations are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port I/O port address + @param[in] Value 32-bit word to write + + @return The value written to the I/O port. + +**/ +UINT32 +UnalignedIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + __asm__ __volatile__ ( "outl %0, %1" : : "a"(Value), "Nd"((UINT16)Port) ); + return Value; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type address. + + Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned. + This function must guarantee that all I/O read and write operations are + serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port I/O port from which to read. + + @return The value read from the specified location. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + UINT32 Data; + __asm__ __volatile__ ( "inl %1, %0" : "=a"(Data) : "Nd"((UINT16)Port) ); + return Data; +} + diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c b/OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c new file mode 100644 index 000000000000..ac365a8b6be5 --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c @@ -0,0 +1,79 @@ +/** @file + Unaligned port I/O. This file has compiler specifics for ICC as there + is no ANSI C standard for doing IO. + + Based on IoLibIcc.c. + + Copyright (c) 2006 - 2008, Intel Corporation. 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 "UnalignedIoInternal.h" + +/** + Performs a 32-bit write to the specified, possibly unaligned I/O-type address. + + Writes the 32-bit I/O port specified by Port with the value specified by Value + and returns Value. This function must guarantee that all I/O read and write + operations are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written the I/O port. + +**/ +UINT32 +UnalignedIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + __asm { + mov eax, dword ptr [Value] + mov dx, word ptr [Port] + out dx, eax + } + + return Value; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type address. + + Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned. + This function must guarantee that all I/O read and write operations are + serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + UINT32 Data; + + __asm { + mov dx, word ptr [Port] + in eax, dx + mov dword ptr [Data], eax + } + + return Data; +} diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoMsc.c b/OvmfPkg/QemuVideoDxe/UnalignedIoMsc.c new file mode 100644 index 000000000000..2eda40a47e2b --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoMsc.c @@ -0,0 +1,81 @@ +/** @file + Unaligned port I/O. This file has compiler specifics for Microsoft C as there + is no ANSI C standard for doing IO. + + Based on IoLibMsc.c + + Copyright (c) 2006 - 2010, Intel Corporation. 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 "UnalignedIoInternal.h" + +unsigned long _inpd (unsigned short port); +unsigned long _outpd (unsigned short port, unsigned long dataword ); +void _ReadWriteBarrier (void); + +/** + Performs a 32-bit write to the specified, possibly unaligned I/O-type address. + + Writes the 32-bit I/O port specified by Port with the value specified by Value + and returns Value. This function must guarantee that all I/O read and write + operations are serialized. + + If 32-bit I/O port operations are not supported, then ASSERT(). + If Port is not aligned on a 32-bit boundary, then ASSERT(). + + @param Port The I/O port to write. + @param Value The value to write to the I/O port. + + @return The value written to the I/O port. + +**/ +UINT32 +EFIAPI +UnalignedIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + _ReadWriteBarrier (); + _outpd ((UINT16)Port, Value); + _ReadWriteBarrier (); + return Value; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type address. + + Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned. + This function must guarantee that all I/O read and write operations are + serialized. + + If 32-bit I/O port operations are not supported, then ASSERT(). + If Port is not aligned on a 32-bit boundary, then ASSERT(). + + @param Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +EFIAPI +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + UINT32 Value; + + _ReadWriteBarrier (); + Value = _inpd ((UINT16)Port); + _ReadWriteBarrier (); + return Value; +} diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c b/OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c new file mode 100644 index 000000000000..1d37ecb7bec0 --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c @@ -0,0 +1,65 @@ +/** @file + Unaligned port I/O dummy implementation for platforms which do not support it. + + Copyright (c) 2017, Phil Dennis-Jordan.
+ 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 "UnalignedIoInternal.h" +#include + +/** + Performs a 32-bit write to the specified, possibly unaligned I/O-type address. + + Writes the 32-bit I/O port specified by Port with the value specified by Value + and returns Value. This function must guarantee that all I/O read and write + operations are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port I/O port address + @param[in] Value 32-bit word to write + + @return The value written to the I/O port. + +**/ +UINT32 +UnalignedIoWrite32 ( + IN UINTN Port, + IN UINT32 Value + ) +{ + ASSERT (FALSE); + return 0; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type address. + + Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned. + This function must guarantee that all I/O read and write operations are + serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port I/O port from which to read. + + @return The value read from the specified location. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + ASSERT (FALSE); + return 0; +} -- 2.3.2 (Apple Git-55)