From nobody Sun May 5 10:25:47 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; dkim=fail spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1491546379707160.57451255513206; Thu, 6 Apr 2017 23:26:19 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2209321DFA7BD; Thu, 6 Apr 2017 23:26:18 -0700 (PDT) Received: from mail-pg0-x243.google.com (mail-pg0-x243.google.com [IPv6:2607:f8b0:400e:c05::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 2898120D77DC6 for ; Thu, 6 Apr 2017 23:26:17 -0700 (PDT) Received: by mail-pg0-x243.google.com with SMTP id g2so13256259pge.2 for ; Thu, 06 Apr 2017 23:26:17 -0700 (PDT) Received: from Phils-MBP-57025.fritz.box.fritz.box ([165.84.56.107]) by smtp.gmail.com with ESMTPSA id e70sm7124608pfh.84.2017.04.06.23.26.14 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 06 Apr 2017 23:26:16 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org 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=OdpsXf47hawZQMjvWWFbjKqheSs0UEskqoEQ8np95Jk=; b=MBXCtbofSQKWhlO4QoyEkN7ikb6yzRJYd/oRqB6lqPZdbOrvAv3dosCrjbWAmlroed oEyb1n+dM1eYVxm6uz3bMjH4QWo2Gk4YGghhMnf0+iDfRcCB7H6LzAoKjg+EN7pC+hM3 hCGYtFdVx7aqraTFhMCEb8pWGC9rrD9/SpZO0pNA0CWepCUKf0wMzsuGRoR5DzOBXfGT NStV+htiAhkA/z+lCDTyJXnukG+JL08CNLM113XNRffe9ZJwOBTD+5Su+cJspVqsul7C W2OdJ/shjQYgcbzYlJegDdaiUNCltu8hVDteh7OObuFVSVMACp7TESiCXfTjPeiKa2Y8 T/gQ== 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=OdpsXf47hawZQMjvWWFbjKqheSs0UEskqoEQ8np95Jk=; b=Z1qlfWUUR8Sk4ntxhqXM+w6VGXp7CsP++jfcUoQ0wNCxINK1W/MeR9zh7t64xE6/V6 x5vQxArRrJTtb4RHsjb5lh0hSKnZ9GmF1e3EUSDkn1VLXVjInMYdHzvH19/5vc1cMch4 nWUI+miKERAgzRh0V1MgzVuFm0i5l73zmrnctBs5BmBnxHJi2KgLki2NUD8xal0ZqjVT cPUQu1xYMJPUI9Xzkl+5QaMUwGFYXhYCg5CRV2uwWgcXQ/BS6xRYLasjuvr9oJfb/CB8 hkS3tis4opRLULEiuNMc047FCkloprCdifhgBPVFvatgq+8Zw0HkJ6ElFW0mVikdAEkr fr9w== X-Gm-Message-State: AFeK/H3dxPb/DbfbsJ4trniLuy01+67F9h6x61RpDyHI52pcD1TsldPRTr36d+KVSPiHgA== X-Received: by 10.99.170.2 with SMTP id e2mr39940994pgf.0.1491546376791; Thu, 06 Apr 2017 23:26:16 -0700 (PDT) From: Phil Dennis-Jordan To: edk2-devel@lists.01.org Date: Fri, 7 Apr 2017 18:25:56 +1200 Message-Id: <1491546358-58572-2-git-send-email-lists@philjordan.eu> X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1491546358-58572-1-git-send-email-lists@philjordan.eu> References: <1491546358-58572-1-git-send-email-lists@philjordan.eu> Subject: [edk2] [PATCH v5 1/3] OvmfPkg: VMWare SVGA display device register definitions 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: , Cc: Jordan Justen , Phil Dennis-Jordan , Laszlo Ersek MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Phil Dennis-Jordan This adds a header file defining symbolic constants for the VMWare SVGA virtual display device in preparation for supporting it in QemuVideoDxe. It is mostly an extract of the file lib/vmware/svga_reg.h from commit 329dd537456f93a806841ec8a8213aed11395def of VMWare's vmware-svga repository at git://git.code.sf.net/p/vmware-svga/git (See also http://vmware-svga.sourceforge.net/ ) Only the bare essentials necessary for initialisation, modesetting and framebuffer access have been kept from the original file; macro names have been prefixed with VMWARE_SVGA_ instead of SVGA2_, and the enum definition has been adapted to comply with EDK2 naming conventions. The original file was released by VMWare under the MIT license, this has been retained. Cc: Jordan Justen Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Phil Dennis-Jordan Reviewed-by: Laszlo Ersek Reviewed-by: Jordan Justen --- Notes: v2: - New, custom header file instead of importing VMWare's verbatim. [Lasz= lo] =20 v3: - Prefixed macros with VMWARE_SVGA_ instead of SVGA2_ [Jordan, Laszlo] - Adjusted enum definition to comply with EDK2 convention [Jordan, Lasz= lo] - Tweaks to definitions of numeric constants [Laszlo] - Renamed the file to fit with convention [Jordan, Laszlo] - Dropped the "2" from SVGA2 wherever appropriate. =20 v4, v5: (no changes) OvmfPkg/Include/IndustryStandard/VmwareSvga.h | 104 ++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/OvmfPkg/Include/IndustryStandard/VmwareSvga.h b/OvmfPkg/Includ= e/IndustryStandard/VmwareSvga.h new file mode 100644 index 000000000000..693d44bab6c3 --- /dev/null +++ b/OvmfPkg/Include/IndustryStandard/VmwareSvga.h @@ -0,0 +1,104 @@ +/** @file + + Macro and enum definitions of a subset of port numbers, register identif= iers + and values required for driving the VMWare SVGA virtual display adapter, + also implemented by Qemu. + + This file's contents was extracted from file lib/vmware/svga_reg.h in co= mmit + 329dd537456f93a806841ec8a8213aed11395def of VMWare's vmware-svga reposit= ory: + git://git.code.sf.net/p/vmware-svga/git + + + Copyright 1998-2009 VMware, Inc. All rights reserved. + Portions Copyright 2017 Phil Dennis-Jordan + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +**/ + +#ifndef _VMWARE_SVGA_H_ +#define _VMWARE_SVGA_H_ + +#include + +// +// IDs for recognising the device +// +#define VMWARE_PCI_VENDOR_ID_VMWARE 0x15AD +#define VMWARE_PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 + +// +// I/O port BAR offsets for register selection and read/write. +// +// The register index is written to the 32-bit index port, followed by a 3= 2-bit +// read or write on the value port to read or set that register's contents. +// +#define VMWARE_SVGA_INDEX_PORT 0x0 +#define VMWARE_SVGA_VALUE_PORT 0x1 + +// +// Some of the device's register indices for basic framebuffer functionali= ty. +// +typedef enum { + VmwareSvgaRegId =3D 0, + VmwareSvgaRegEnable =3D 1, + VmwareSvgaRegWidth =3D 2, + VmwareSvgaRegHeight =3D 3, + VmwareSvgaRegMaxWidth =3D 4, + VmwareSvgaRegMaxHeight =3D 5, + + VmwareSvgaRegBitsPerPixel =3D 7, + + VmwareSvgaRegRedMask =3D 9, + VmwareSvgaRegGreenMask =3D 10, + VmwareSvgaRegBlueMask =3D 11, + VmwareSvgaRegBytesPerLine =3D 12, + + VmwareSvgaRegFbOffset =3D 14, + + VmwareSvgaRegFbSize =3D 16, + VmwareSvgaRegCapabilities =3D 17, + + VmwareSvgaRegHostBitsPerPixel =3D 28, +} VMWARE_SVGA_REGISTER; + +// +// Values used with VmwareSvgaRegId for sanity-checking the device and get= ting +// its version. +// +#define VMWARE_SVGA_MAGIC 0x900000U +#define VMWARE_SVGA_MAKE_ID(ver) (VMWARE_SVGA_MAGIC << 8 | (ver)) + +#define VMWARE_SVGA_VERSION_2 2 +#define VMWARE_SVGA_ID_2 VMWARE_SVGA_MAKE_ID (VMWARE_SVGA_VERSIO= N_2) + +#define VMWARE_SVGA_VERSION_1 1 +#define VMWARE_SVGA_ID_1 VMWARE_SVGA_MAKE_ID (VMWARE_SVGA_VERSIO= N_1) + +#define VMWARE_SVGA_VERSION_0 0 +#define VMWARE_SVGA_ID_0 VMWARE_SVGA_MAKE_ID (VMWARE_SVGA_VERSIO= N_0) + +// +// One of the capability bits advertised by VmwareSvgaRegCapabilities. +// +#define VMWARE_SVGA_CAP_8BIT_EMULATION BIT8 + +#endif --=20 2.3.2 (Apple Git-55) _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Sun May 5 10:25:47 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; dkim=fail spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 149154638241445.024485541612876; Thu, 6 Apr 2017 23:26:22 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 544E320D77DD0; Thu, 6 Apr 2017 23:26:21 -0700 (PDT) Received: from mail-pg0-x242.google.com (mail-pg0-x242.google.com [IPv6:2607:f8b0:400e:c05::242]) (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 960542194233D for ; Thu, 6 Apr 2017 23:26:20 -0700 (PDT) Received: by mail-pg0-x242.google.com with SMTP id 79so13311173pgf.0 for ; Thu, 06 Apr 2017 23:26:20 -0700 (PDT) Received: from Phils-MBP-57025.fritz.box.fritz.box ([165.84.56.107]) by smtp.gmail.com with ESMTPSA id e70sm7124608pfh.84.2017.04.06.23.26.17 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 06 Apr 2017 23:26:19 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org 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=h//LacR9FtGUlbjwNJwAxCEj6DDc0qzzLd8oIz5fWAo=; b=BmQeuqtn9xb1F02tQUjr7CslQBS98Rc+FMtgNMu6HrfEV672iXI3cgToMC5DUrrzWK lrDHQPJicY4OgvjYH+xbEWcUPS5KIG5xUlNiuEiRHRs9R7KX46hXWzNVt7alFYcLsiqQ Y/NqOcsSNMxRSgnsFnGxeH5azMz9F5967fX2i7FJ3FS4pDPx+w6otTngjwL2kvIonbMd Hje2TpMX+pHw+1kOZy0HibZ1gr7zos3YFRRLbs8OySUk8Lbel/tWNUxMMEwrLVCaADTC 1Ld4si3Xn/zfz+oVw6t+QKc5zjSShHgIFZf3ykxNX/YylKg9J+44YqXs3Lj8kwTfe+9Q t2uw== 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=h//LacR9FtGUlbjwNJwAxCEj6DDc0qzzLd8oIz5fWAo=; b=U0mW0lzj39hqCObyVzdhFU/42mUbZg118iBCpG/LA454tyfR1h60hPd66Q2SUDoWIo JqT6M28EXEoyrzJYrrug4z3IUIj3vXnLlCl/eiaz4c23RNvmjIucvf19awujbZLrjJ7i /6bkeBINbENXdjlwxx5aDobXTJjk1kRULRHC41abB957ybdS1gMKixnRqFb75EZ/BpKt fiV3V3nLxEJIjLBX7x5QTJxBbW/huFDDzQ0Q2s/2d42W3GXaj5q3HcEklQkTZjR6avmZ 237q/AhQADX/7OImCBic2FBaZtUwjoHR+EPjTcXlJ+toxKT2NgRufQvl0P2XrYUMKe/8 54Qw== X-Gm-Message-State: AFeK/H20NMJ00Sh47Nywd61ge5ywORvGeWnSoGbMkcrxxSpEhFMkTERUOfYil9VyXTvbUg== X-Received: by 10.99.109.67 with SMTP id i64mr39234998pgc.56.1491546380064; Thu, 06 Apr 2017 23:26:20 -0700 (PDT) From: Phil Dennis-Jordan To: edk2-devel@lists.01.org Date: Fri, 7 Apr 2017 18:25:57 +1200 Message-Id: <1491546358-58572-3-git-send-email-lists@philjordan.eu> X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1491546358-58572-1-git-send-email-lists@philjordan.eu> References: <1491546358-58572-1-git-send-email-lists@philjordan.eu> Subject: [edk2] [PATCH v5 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: , Cc: Jordan Justen , Phil Dennis-Jordan , Laszlo Ersek MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Phil Dennis-Jordan The VMWare SVGA 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 Io.Read/Io.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 IoRead32, 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 Suggested-by: Jordan Justen Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Phil Dennis-Jordan Reviewed-by: Laszlo Ersek Reviewed-by: Jordan Justen --- 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. =20 v3: - Fixed typos in commit message [Laszlo] - Added Suggested-by: tag [Laszlo] - Rewrapped comment lines to 79 chars [Laszlo] - Corrected whitespace in function calls [Laszlo] - EFIAPI dropped. [Laszlo] - Fixed return value in dummy UnsignedIoWrite32 [Laszlo] - Dropped "N" imm8 constraint in GCC inline asm [Laszlo] =20 v4, v5: (no changes) OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 6 ++ OvmfPkg/QemuVideoDxe/UnalignedIoInternal.h | 59 +++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c | 70 +++++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c | 80 ++++++++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoMsc.c | 78 +++++++++++++++++++ OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c | 66 ++++++++++++++++ 6 files changed, 359 insertions(+) diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/Q= emuVideoDxe.inf index affb6ffd88e0..346a5aed94fa 100644 --- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf +++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf @@ -41,6 +41,12 @@ [Sources.common] =20 [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 =20 [Packages] MdePkg/MdePkg.dec diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoInternal.h b/OvmfPkg/QemuVideo= Dxe/UnalignedIoInternal.h new file mode 100644 index 000000000000..234de6c21bd1 --- /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 availa= ble + 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 IMP= LIED. + +**/ + +#ifndef _UNALIGNED_IO_INTERNAL_H_ +#define _UNALIGNED_IO_INTERNAL_H_ + +/** + Performs a 32-bit write to the specified, possibly unaligned I/O-type ad= dress. + + 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 wr= ite + 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 a 32-bit word from the specified, possibly unaligned I/O-type addr= ess. + + 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 opera= tions + are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ); + +#endif diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c b/OvmfPkg/QemuVideoDxe/U= nalignedIoGcc.c new file mode 100644 index 000000000000..105d55d3b903 --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoGcc.c @@ -0,0 +1,70 @@ +/** @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 availa= ble + 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 IMP= LIED. + +**/ + + +#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), "d" ((UINT16)Port)= ); + return Value; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type addr= ess. + + 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 opera= tions + are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + UINT32 Data; + __asm__ __volatile__ ( "inl %1, %0" : "=3Da" (Data) : "d" ((UINT16)Port)= ); + return Data; +} + diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c b/OvmfPkg/QemuVideoDxe/U= nalignedIoIcc.c new file mode 100644 index 000000000000..79f3e446ddba --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoIcc.c @@ -0,0 +1,80 @@ +/** @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 availa= ble + 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 IMP= LIED. + +**/ + + +#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 { + 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 addr= ess. + + 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 opera= tions + are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] 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/U= nalignedIoMsc.c new file mode 100644 index 000000000000..a466baee8486 --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoMsc.c @@ -0,0 +1,78 @@ +/** @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 availa= ble + 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 IMP= LIED. + +**/ + + +#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 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 + ) +{ + _ReadWriteBarrier (); + _outpd ((UINT16)Port, Value); + _ReadWriteBarrier (); + return Value; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type addr= ess. + + 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 opera= tions + are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + UINT32 Value; + + _ReadWriteBarrier (); + Value =3D _inpd ((UINT16)Port); + _ReadWriteBarrier (); + return Value; +} diff --git a/OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c b/OvmfPkg/QemuVi= deoDxe/UnalignedIoUnsupported.c new file mode 100644 index 000000000000..57560ab38fcf --- /dev/null +++ b/OvmfPkg/QemuVideoDxe/UnalignedIoUnsupported.c @@ -0,0 +1,66 @@ +/** @file + Unaligned port I/O dummy implementation for platforms which do not suppo= rt it. + + Copyright (c) 2017, Phil Dennis-Jordan.
+ This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + +**/ + + +#include +#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 + ) +{ + ASSERT (FALSE); + return Value; +} + +/** + Reads a 32-bit word from the specified, possibly unaligned I/O-type addr= ess. + + 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 opera= tions + are serialized. + + If 32-bit unaligned I/O port operations are not supported, then ASSERT(). + + @param[in] Port The I/O port to read. + + @return The value read. + +**/ +UINT32 +UnalignedIoRead32 ( + IN UINTN Port + ) +{ + ASSERT (FALSE); + return 0; +} --=20 2.3.2 (Apple Git-55) _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Sun May 5 10:25:47 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; dkim=fail spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 149154638663567.95944116949283; Thu, 6 Apr 2017 23:26:26 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 88BA520D77DDA; Thu, 6 Apr 2017 23:26:25 -0700 (PDT) Received: from mail-pg0-x242.google.com (mail-pg0-x242.google.com [IPv6:2607:f8b0:400e:c05::242]) (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 BF2AD2194233D for ; Thu, 6 Apr 2017 23:26:23 -0700 (PDT) Received: by mail-pg0-x242.google.com with SMTP id 79so13311445pgf.0 for ; Thu, 06 Apr 2017 23:26:23 -0700 (PDT) Received: from Phils-MBP-57025.fritz.box.fritz.box ([165.84.56.107]) by smtp.gmail.com with ESMTPSA id e70sm7124608pfh.84.2017.04.06.23.26.20 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 06 Apr 2017 23:26:22 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org 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=YrZuxNWvjvyokmu6x57s0Idfk71plSWZncBAKQ6NuDg=; b=weELtR6Dl0Pmvl5EOEeBpHNycG7EDchzBzGo2cdXGcGarnYOvOP4j78cqfTpXqLL4q Eqjhpse7VQj3G62f8mZJ4Vc06axaMUr+vKn96cmEEXHmAH8ckF6FaNQnvqjKPvfXBrOF CfyBy7ET7ihMOixHoikQiwuVxJRkP+k1Ddn+9G4NzQ+7q7mN+gXi9RpMhJr4KNjYhgv4 BcWKaneYWCPfgsLeoHTttm2QjAojXt0AsGb0aJXjGBu37RWgMjqGf80p0yPCF7vXEG+I SvqQL2uopgQcIypPea1UO1VTmqyFIiq69zIJjRtT89ags6CUJrKNT7TZxe7v30nm9P3u FUng== 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=YrZuxNWvjvyokmu6x57s0Idfk71plSWZncBAKQ6NuDg=; b=XQHE9aSjCOwOzG8NQVHnM4Yx9tAmyRrFZQb238S3/9wHq2QOWlasWpfrMnw9JHi2Ut 7ro+A9dwuyZRHK85shBiIEcWNzuykWQlH4Obbpex4Y2zwSTuIJjoS48tfJ8mt/7NBtVA qOrxFTET/Fk1HeN3qqgdnjcSwhp7K+wMVuw/Obh7iKdtFm4l5P9aiiwsiQovzHEfWxkS ry7PyJviwzxz489dJoE1Fz7rhzvBGFv6Yfmx7o+YZJQ3maEZEMwhw5u+M/lJxV6ON9KZ AQSzXCnVQi7739B8XRo2jCpSI2CVU5HTFlCPxg6VLUtklH+Qsv3/sbCPtcQE2UMjWjGw aX5Q== X-Gm-Message-State: AFeK/H3ui+GsKu5VbOukUOAll7TsR426G6GyhfABpHohQqkMbmAM9ZCNBdangO9My7Jxyg== X-Received: by 10.99.2.139 with SMTP id 133mr39128985pgc.168.1491546383249; Thu, 06 Apr 2017 23:26:23 -0700 (PDT) From: Phil Dennis-Jordan To: edk2-devel@lists.01.org Date: Fri, 7 Apr 2017 18:25:58 +1200 Message-Id: <1491546358-58572-4-git-send-email-lists@philjordan.eu> X-Mailer: git-send-email 2.3.2 (Apple Git-55) In-Reply-To: <1491546358-58572-1-git-send-email-lists@philjordan.eu> References: <1491546358-58572-1-git-send-email-lists@philjordan.eu> Subject: [edk2] [PATCH v5 3/3] OvmfPkg/QemuVideoDxe: VMWare SVGA device support 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: , Cc: Jordan Justen , Phil Dennis-Jordan , Laszlo Ersek MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Phil Dennis-Jordan In addition to the QXL, Cirrus, etc. VGA adapters, Qemu also implements a basic version of VMWare's SVGA display device. Drivers for this device exist for some guest OSes which do not support Qemu's other display adapters, so supporting it in OVMF is useful in conjunction with those OSes. This change adds support for the SVGA device's framebuffer to QemuVideoDxe's graphics output protocol implementation, based on VMWare's documentation. The most basic initialisation, framebuffer layout query, and mode setting operations are implemented. The device relies on port-based 32-bit I/O, unfortunately on misaligned addresses. This limits the driver's support to the x86 family of platforms. Cc: Jordan Justen Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Phil Dennis-Jordan Reviewed-by: Jordan Justen Reviewed-by: Laszlo Ersek --- Notes: v2: - Unaligned I/O helper functions moved to separate commit [Laszlo] - Multi-line function call whitespace fixes. =20 v3: - Dropped the "2" from "SVGA2" where appropriate. [Jordan, Laszlo] - Renamed various struct fields and functions with consistent prefixes = [Laszlo] - #include orders fixed [Laszlo] - Renamedi/moved lots of local variables to comply with convention. [La= szlo] - Added error checking to PCI BAR queries. [Laszlo] - Moved some function definitions around for better grouping. [Laszlo] - Fixed ClearScreen() to use the correct VRAM BAR. [Laszlo] - Changed modelist initialisation to fetch all mode data on startup, so= mode queries can return everything including channel masks without hitting= the device. Mask calculations hopefully make more sense now. [Laszlo] - Whitespace fixes. [Laszlo] - Fixed a memory leak in BAR query. =20 v4: - Simplified mode info pixel mask calculation & PCI BAR OOB check. [Las= zlo] - Replaced struct assignment with CopyMem. [Laszlo] - Whitespace & comment typo fixes. [Laszlo] =20 v5: - Removed duplicate hw register read in QemuVideoVmwareSvgaModeSetup. [= Laszlo] - Fixed memory leak of VMWare SVGA specific modelist. [Laszlo] OvmfPkg/QemuVideoDxe/Qemu.h | 29 ++++ OvmfPkg/QemuVideoDxe/Driver.c | 134 ++++++++++++++++- OvmfPkg/QemuVideoDxe/Gop.c | 61 +++++++- OvmfPkg/QemuVideoDxe/Initialize.c | 157 ++++++++++++++++++++ 4 files changed, 374 insertions(+), 7 deletions(-) diff --git a/OvmfPkg/QemuVideoDxe/Qemu.h b/OvmfPkg/QemuVideoDxe/Qemu.h index 2ce37defc5b8..7fbb25b3efd3 100644 --- a/OvmfPkg/QemuVideoDxe/Qemu.h +++ b/OvmfPkg/QemuVideoDxe/Qemu.h @@ -92,6 +92,7 @@ typedef enum { QEMU_VIDEO_CIRRUS_5446, QEMU_VIDEO_BOCHS, QEMU_VIDEO_BOCHS_MMIO, + QEMU_VIDEO_VMWARE_SVGA, } QEMU_VIDEO_VARIANT; =20 typedef struct { @@ -115,10 +116,13 @@ typedef struct { // UINTN MaxMode; QEMU_VIDEO_MODE_DATA *ModeData; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *VmwareSvgaModeInfo; =20 QEMU_VIDEO_VARIANT Variant; FRAME_BUFFER_CONFIGURE *FrameBufferBltConfigure; UINTN FrameBufferBltConfigureSize; + UINT8 FrameBufferVramBarIndex; + UINT16 VmwareSvgaBasePort; } QEMU_VIDEO_PRIVATE_DATA; =20 /// @@ -502,9 +506,34 @@ QemuVideoBochsModeSetup ( BOOLEAN IsQxl ); =20 +EFI_STATUS +QemuVideoVmwareSvgaModeSetup ( + QEMU_VIDEO_PRIVATE_DATA *Private + ); + VOID InstallVbeShim ( IN CONST CHAR16 *CardName, IN EFI_PHYSICAL_ADDRESS FrameBufferBase ); + +VOID +VmwareSvgaWrite ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Register, + UINT32 Value + ); + +UINT32 +VmwareSvgaRead ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Register + ); + +VOID +InitializeVmwareSvgaGraphicsMode ( + QEMU_VIDEO_PRIVATE_DATA *Private, + QEMU_VIDEO_BOCHS_MODES *ModeData + ); + #endif diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c index fc8025ec46de..0dce80e59ba8 100644 --- a/OvmfPkg/QemuVideoDxe/Driver.c +++ b/OvmfPkg/QemuVideoDxe/Driver.c @@ -14,8 +14,10 @@ =20 **/ =20 -#include "Qemu.h" +#include #include +#include "Qemu.h" +#include "UnalignedIoInternal.h" =20 EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding =3D { QemuVideoControllerDriverSupported, @@ -58,6 +60,11 @@ QEMU_VIDEO_CARD gQemuVideoCardList[] =3D { QEMU_VIDEO_BOCHS_MMIO, L"QEMU VirtIO VGA" },{ + VMWARE_PCI_VENDOR_ID_VMWARE, + VMWARE_PCI_DEVICE_ID_VMWARE_SVGA2, + QEMU_VIDEO_VMWARE_SVGA, + L"QEMU VMWare SVGA" + },{ 0 /* end of list */ } }; @@ -242,6 +249,7 @@ QemuVideoControllerDriverStart ( goto ClosePciIo; } Private->Variant =3D Card->Variant; + Private->FrameBufferVramBarIndex =3D PCI_BAR_IDX0; =20 // // IsQxl is based on the detected Card->Variant, which at a later point = might @@ -317,6 +325,58 @@ QemuVideoControllerDriverStart ( } =20 // + // Check if accessing Vmware SVGA interface works + // + if (Private->Variant =3D=3D QEMU_VIDEO_VMWARE_SVGA) { + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *IoDesc; + UINT32 TargetId; + UINT32 SvgaIdRead; + + IoDesc =3D NULL; + Status =3D Private->PciIo->GetBarAttributes ( + Private->PciIo, + PCI_BAR_IDX0, + NULL, + (VOID**) &IoDesc + ); + if (EFI_ERROR (Status) || + IoDesc->ResType !=3D ACPI_ADDRESS_SPACE_TYPE_IO || + IoDesc->AddrRangeMin > MAX_UINT16 + 1 - (VMWARE_SVGA_VALUE_PORT + = 4)) { + if (IoDesc !=3D NULL) { + FreePool (IoDesc); + } + Status =3D EFI_DEVICE_ERROR; + goto RestoreAttributes; + } + Private->VmwareSvgaBasePort =3D (UINT16) IoDesc->AddrRangeMin; + FreePool (IoDesc); + + TargetId =3D VMWARE_SVGA_ID_2; + while (TRUE) { + VmwareSvgaWrite (Private, VmwareSvgaRegId, TargetId); + SvgaIdRead =3D VmwareSvgaRead (Private, VmwareSvgaRegId); + if ((SvgaIdRead =3D=3D TargetId) || (TargetId <=3D VMWARE_SVGA_ID_0)= ) { + break; + } + TargetId--; + } + + if (SvgaIdRead !=3D TargetId) { + DEBUG (( + DEBUG_ERROR, + "QemuVideo: QEMU_VIDEO_VMWARE_SVGA ID mismatch " + "(got 0x%x, base address 0x%x)\n", + SvgaIdRead, + Private->VmwareSvgaBasePort + )); + Status =3D EFI_DEVICE_ERROR; + goto RestoreAttributes; + } + + Private->FrameBufferVramBarIndex =3D PCI_BAR_IDX1; + } + + // // Get ParentDevicePath // Status =3D gBS->HandleProtocol ( @@ -371,6 +431,9 @@ QemuVideoControllerDriverStart ( case QEMU_VIDEO_BOCHS: Status =3D QemuVideoBochsModeSetup (Private, IsQxl); break; + case QEMU_VIDEO_VMWARE_SVGA: + Status =3D QemuVideoVmwareSvgaModeSetup (Private); + break; default: ASSERT (FALSE); Status =3D EFI_DEVICE_ERROR; @@ -432,6 +495,9 @@ DestructQemuVideoGraphics: =20 FreeModeData: FreePool (Private->ModeData); + if (Private->VmwareSvgaModeInfo !=3D NULL) { + FreePool (Private->VmwareSvgaModeInfo); + } =20 UninstallGopDevicePath: gBS->UninstallProtocolInterface (Private->Handle, @@ -553,6 +619,9 @@ QemuVideoControllerDriverStop ( ); =20 FreePool (Private->ModeData); + if (Private->VmwareSvgaModeInfo !=3D NULL) { + FreePool (Private->VmwareSvgaModeInfo); + } gBS->UninstallProtocolInterface (Private->Handle, &gEfiDevicePathProtocolGuid, Private->GopDevicePath); FreePool (Private->GopDevicePath); @@ -750,7 +819,7 @@ ClearScreen ( Private->PciIo->Mem.Write ( Private->PciIo, EfiPciIoWidthFillUint32, - 0, + Private->FrameBufferVramBarIndex, 0, 0x400000 >> 2, &Color @@ -888,6 +957,38 @@ BochsRead ( } =20 VOID +VmwareSvgaWrite ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Register, + UINT32 Value + ) +{ + UnalignedIoWrite32 ( + Private->VmwareSvgaBasePort + VMWARE_SVGA_INDEX_PORT, + Register + ); + UnalignedIoWrite32 ( + Private->VmwareSvgaBasePort + VMWARE_SVGA_VALUE_PORT, + Value + ); +} + +UINT32 +VmwareSvgaRead ( + QEMU_VIDEO_PRIVATE_DATA *Private, + UINT16 Register + ) +{ + UnalignedIoWrite32 ( + Private->VmwareSvgaBasePort + VMWARE_SVGA_INDEX_PORT, + Register + ); + return UnalignedIoRead32 ( + Private->VmwareSvgaBasePort + VMWARE_SVGA_VALUE_PORT + ); +} + +VOID VgaOutb ( QEMU_VIDEO_PRIVATE_DATA *Private, UINTN Reg, @@ -941,6 +1042,35 @@ InitializeBochsGraphicsMode ( ClearScreen (Private); } =20 +VOID +InitializeVmwareSvgaGraphicsMode ( + QEMU_VIDEO_PRIVATE_DATA *Private, + QEMU_VIDEO_BOCHS_MODES *ModeData + ) +{ + UINT32 Capabilities; + + VmwareSvgaWrite (Private, VmwareSvgaRegWidth, ModeData->Width); + VmwareSvgaWrite (Private, VmwareSvgaRegHeight, ModeData->Height); + + Capabilities =3D VmwareSvgaRead ( + Private, + VmwareSvgaRegCapabilities + ); + if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) !=3D 0) { + VmwareSvgaWrite ( + Private, + VmwareSvgaRegBitsPerPixel, + ModeData->ColorDepth + ); + } + + VmwareSvgaWrite (Private, VmwareSvgaRegEnable, 1); + + SetDefaultPalette (Private); + ClearScreen (Private); +} + EFI_STATUS EFIAPI InitializeQemuVideo ( diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index 359e9217d3d1..512fd27acbda 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -13,6 +13,7 @@ =20 **/ =20 +#include #include "Qemu.h" =20 STATIC @@ -75,6 +76,42 @@ QemuVideoCompleteModeData ( return EFI_SUCCESS; } =20 +STATIC +EFI_STATUS +QemuVideoVmwareSvgaCompleteModeData ( + IN QEMU_VIDEO_PRIVATE_DATA *Private, + OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc; + UINT32 BytesPerLine, FbOffset, BytesPerPi= xel; + + Info =3D Mode->Info; + CopyMem (Info, &Private->VmwareSvgaModeInfo[Mode->Mode], sizeof (*Info)); + BytesPerPixel =3D Private->ModeData[Mode->Mode].ColorDepth / 8; + BytesPerLine =3D Info->PixelsPerScanLine * BytesPerPixel; + + FbOffset =3D VmwareSvgaRead (Private, VmwareSvgaRegFbOffset); + + Status =3D Private->PciIo->GetBarAttributes ( + Private->PciIo, + PCI_BAR_IDX1, + NULL, + (VOID**) &FrameBufDesc + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Mode->FrameBufferBase =3D FrameBufDesc->AddrRangeMin + FbOffset; + Mode->FrameBufferSize =3D BytesPerLine * Info->VerticalResolution; + + FreePool (FrameBufDesc); + return Status; +} + =20 // // Graphics Output Protocol Member Functions @@ -124,10 +161,14 @@ Routine Description: =20 *SizeOfInfo =3D sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); =20 - ModeData =3D &Private->ModeData[ModeNumber]; - (*Info)->HorizontalResolution =3D ModeData->HorizontalResolution; - (*Info)->VerticalResolution =3D ModeData->VerticalResolution; - QemuVideoCompleteModeInfo (ModeData, *Info); + if (Private->Variant =3D=3D QEMU_VIDEO_VMWARE_SVGA) { + CopyMem (*Info, &Private->VmwareSvgaModeInfo[ModeNumber], sizeof (**In= fo)); + } else { + ModeData =3D &Private->ModeData[ModeNumber]; + (*Info)->HorizontalResolution =3D ModeData->HorizontalResolution; + (*Info)->VerticalResolution =3D ModeData->VerticalResolution; + QemuVideoCompleteModeInfo (ModeData, *Info); + } =20 return EFI_SUCCESS; } @@ -176,6 +217,12 @@ Routine Description: case QEMU_VIDEO_BOCHS: InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->I= nternalModeIndex]); break; + case QEMU_VIDEO_VMWARE_SVGA: + InitializeVmwareSvgaGraphicsMode ( + Private, + &QemuVideoBochsModes[ModeData->InternalModeIndex] + ); + break; default: ASSERT (FALSE); return EFI_DEVICE_ERROR; @@ -186,7 +233,11 @@ Routine Description: This->Mode->Info->VerticalResolution =3D ModeData->VerticalResolution; This->Mode->SizeOfInfo =3D sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); =20 - QemuVideoCompleteModeData (Private, This->Mode); + if (Private->Variant =3D=3D QEMU_VIDEO_VMWARE_SVGA) { + QemuVideoVmwareSvgaCompleteModeData (Private, This->Mode); + } else { + QemuVideoCompleteModeData (Private, This->Mode); + } =20 // // Re-initialize the frame buffer configure when mode changes. diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initi= alize.c index d5d8cfef9661..357124d628e7 100644 --- a/OvmfPkg/QemuVideoDxe/Initialize.c +++ b/OvmfPkg/QemuVideoDxe/Initialize.c @@ -13,6 +13,7 @@ =20 **/ =20 +#include #include "Qemu.h" =20 =20 @@ -346,3 +347,159 @@ QemuVideoBochsModeSetup ( return EFI_SUCCESS; } =20 +EFI_STATUS +QemuVideoVmwareSvgaModeSetup ( + QEMU_VIDEO_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + UINT32 FbSize; + UINT32 MaxWidth, MaxHeight; + UINT32 Capabilities; + UINT32 BitsPerPixel; + UINT32 Index; + QEMU_VIDEO_MODE_DATA *ModeData; + QEMU_VIDEO_BOCHS_MODES *VideoMode; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo; + + VmwareSvgaWrite (Private, VmwareSvgaRegEnable, 0); + + Private->ModeData =3D + AllocatePool (sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_CO= UNT); + if (Private->ModeData =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ModeDataAllocError; + } + + Private->VmwareSvgaModeInfo =3D + AllocatePool ( + sizeof (Private->VmwareSvgaModeInfo[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT + ); + if (Private->VmwareSvgaModeInfo =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto ModeInfoAllocError; + } + + FbSize =3D VmwareSvgaRead (Private, VmwareSvgaRegFbSize); + MaxWidth =3D VmwareSvgaRead (Private, VmwareSvgaRegMaxWidth); + MaxHeight =3D VmwareSvgaRead (Private, VmwareSvgaRegMaxHeight); + Capabilities =3D VmwareSvgaRead (Private, VmwareSvgaRegCapabilities); + if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) !=3D 0) { + BitsPerPixel =3D VmwareSvgaRead ( + Private, + VmwareSvgaRegHostBitsPerPixel + ); + VmwareSvgaWrite ( + Private, + VmwareSvgaRegBitsPerPixel, + BitsPerPixel + ); + } else { + BitsPerPixel =3D VmwareSvgaRead ( + Private, + VmwareSvgaRegBitsPerPixel + ); + } + + if (FbSize =3D=3D 0 || + MaxWidth =3D=3D 0 || + MaxHeight =3D=3D 0 || + BitsPerPixel =3D=3D 0 || + BitsPerPixel % 8 !=3D 0) { + Status =3D EFI_DEVICE_ERROR; + goto Rollback; + } + + ModeData =3D Private->ModeData; + ModeInfo =3D Private->VmwareSvgaModeInfo; + VideoMode =3D &QemuVideoBochsModes[0]; + for (Index =3D 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) { + UINTN RequiredFbSize; + + RequiredFbSize =3D (UINTN) VideoMode->Width * VideoMode->Height * + (BitsPerPixel / 8); + if (RequiredFbSize <=3D FbSize && + VideoMode->Width <=3D MaxWidth && + VideoMode->Height <=3D MaxHeight) { + UINT32 BytesPerLine; + UINT32 RedMask, GreenMask, BlueMask, PixelMask; + + VmwareSvgaWrite ( + Private, + VmwareSvgaRegWidth, + VideoMode->Width + ); + VmwareSvgaWrite ( + Private, + VmwareSvgaRegHeight, + VideoMode->Height + ); + + ModeData->InternalModeIndex =3D Index; + ModeData->HorizontalResolution =3D VideoMode->Width; + ModeData->VerticalResolution =3D VideoMode->Height; + ModeData->ColorDepth =3D BitsPerPixel; + + // + // Setting VmwareSvgaRegWidth/VmwareSvgaRegHeight actually changes + // the device's display mode, so we save all properties of each mode= up + // front to avoid inadvertent mode changes later. + // + ModeInfo->Version =3D 0; + ModeInfo->HorizontalResolution =3D ModeData->HorizontalResolution; + ModeInfo->VerticalResolution =3D ModeData->VerticalResolution; + + ModeInfo->PixelFormat =3D PixelBitMask; + + RedMask =3D VmwareSvgaRead (Private, VmwareSvgaRegRedMask); + ModeInfo->PixelInformation.RedMask =3D RedMask; + + GreenMask =3D VmwareSvgaRead (Private, VmwareSvgaRegGreenMask); + ModeInfo->PixelInformation.GreenMask =3D GreenMask; + + BlueMask =3D VmwareSvgaRead (Private, VmwareSvgaRegBlueMask); + ModeInfo->PixelInformation.BlueMask =3D BlueMask; + + // + // Reserved mask is whatever bits in the pixel not containing RGB da= ta, + // so start with binary 1s for every bit in the pixel, then mask off + // bits already used for RGB. Special case 32 to avoid undefined + // behaviour in the shift. + // + if (BitsPerPixel =3D=3D 32) { + if (BlueMask =3D=3D 0xff && GreenMask =3D=3D 0xff00 && RedMask =3D= =3D 0xff0000) { + ModeInfo->PixelFormat =3D PixelBlueGreenRedReserved8BitPerColor; + } else if (BlueMask =3D=3D 0xff0000 && + GreenMask =3D=3D 0xff00 && + RedMask =3D=3D 0xff) { + ModeInfo->PixelFormat =3D PixelRedGreenBlueReserved8BitPerColor; + } + PixelMask =3D MAX_UINT32; + } else { + PixelMask =3D (1u << BitsPerPixel) - 1; + } + ModeInfo->PixelInformation.ReservedMask =3D + PixelMask & ~(RedMask | GreenMask | BlueMask); + + BytesPerLine =3D VmwareSvgaRead (Private, VmwareSvgaRegBytesPerLine); + ModeInfo->PixelsPerScanLine =3D BytesPerLine / (BitsPerPixel / 8); + + ModeData++; + ModeInfo++; + } + VideoMode++; + } + Private->MaxMode =3D ModeData - Private->ModeData; + return EFI_SUCCESS; + +Rollback: + FreePool (Private->VmwareSvgaModeInfo); + Private->VmwareSvgaModeInfo =3D NULL; + +ModeInfoAllocError: + FreePool (Private->ModeData); + Private->ModeData =3D NULL; + +ModeDataAllocError: + return Status; +} --=20 2.3.2 (Apple Git-55) _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel