This driver is a sample implementation of the Graphics Output Protocol for\r
the QEMU (Cirrus Logic 5446) video controller.\r
\r
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-#include <IndustryStandard/VmwareSvga.h>\r
-#include <IndustryStandard/Acpi.h>\r
#include "Qemu.h"\r
-#include "UnalignedIoInternal.h"\r
+#include <IndustryStandard/Acpi.h>\r
\r
EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {\r
QemuVideoControllerDriverSupported,\r
\r
QEMU_VIDEO_CARD gQemuVideoCardList[] = {\r
{\r
+ PCI_CLASS_DISPLAY_VGA,\r
CIRRUS_LOGIC_VENDOR_ID,\r
CIRRUS_LOGIC_5430_DEVICE_ID,\r
QEMU_VIDEO_CIRRUS_5430,\r
L"Cirrus 5430"\r
},{\r
+ PCI_CLASS_DISPLAY_VGA,\r
CIRRUS_LOGIC_VENDOR_ID,\r
CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID,\r
QEMU_VIDEO_CIRRUS_5430,\r
L"Cirrus 5430"\r
},{\r
+ PCI_CLASS_DISPLAY_VGA,\r
CIRRUS_LOGIC_VENDOR_ID,\r
CIRRUS_LOGIC_5446_DEVICE_ID,\r
QEMU_VIDEO_CIRRUS_5446,\r
L"Cirrus 5446"\r
},{\r
+ PCI_CLASS_DISPLAY_VGA,\r
0x1234,\r
0x1111,\r
QEMU_VIDEO_BOCHS_MMIO,\r
L"QEMU Standard VGA"\r
},{\r
+ PCI_CLASS_DISPLAY_OTHER,\r
+ 0x1234,\r
+ 0x1111,\r
+ QEMU_VIDEO_BOCHS_MMIO,\r
+ L"QEMU Standard VGA (secondary)"\r
+ },{\r
+ PCI_CLASS_DISPLAY_VGA,\r
0x1b36,\r
0x0100,\r
QEMU_VIDEO_BOCHS,\r
L"QEMU QXL VGA"\r
},{\r
+ PCI_CLASS_DISPLAY_VGA,\r
0x1af4,\r
0x1050,\r
QEMU_VIDEO_BOCHS_MMIO,\r
L"QEMU VirtIO VGA"\r
},{\r
- VMWARE_PCI_VENDOR_ID_VMWARE,\r
- VMWARE_PCI_DEVICE_ID_VMWARE_SVGA2,\r
+ PCI_CLASS_DISPLAY_VGA,\r
+ 0x15ad,\r
+ 0x0405,\r
QEMU_VIDEO_VMWARE_SVGA,\r
L"QEMU VMWare SVGA"\r
},{\r
\r
static QEMU_VIDEO_CARD*\r
QemuVideoDetect(\r
+ IN UINT8 SubClass,\r
IN UINT16 VendorId,\r
IN UINT16 DeviceId\r
)\r
UINTN Index = 0;\r
\r
while (gQemuVideoCardList[Index].VendorId != 0) {\r
- if (gQemuVideoCardList[Index].VendorId == VendorId &&\r
+ if (gQemuVideoCardList[Index].SubClass == SubClass &&\r
+ gQemuVideoCardList[Index].VendorId == VendorId &&\r
gQemuVideoCardList[Index].DeviceId == DeviceId) {\r
return gQemuVideoCardList + Index;\r
}\r
}\r
\r
Status = EFI_UNSUPPORTED;\r
- if (!IS_PCI_VGA (&Pci)) {\r
+ if (!IS_PCI_DISPLAY (&Pci)) {\r
goto Done;\r
}\r
- Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
if (Card != NULL) {\r
DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));\r
Status = EFI_SUCCESS;\r
//\r
// Determine card variant.\r
//\r
- Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
+ Card = QemuVideoDetect(Pci.Hdr.ClassCode[1], Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
if (Card == NULL) {\r
Status = EFI_DEVICE_ERROR;\r
goto ClosePciIo;\r
}\r
Private->Variant = Card->Variant;\r
- Private->FrameBufferVramBarIndex = PCI_BAR_IDX0;\r
\r
//\r
// IsQxl is based on the detected Card->Variant, which at a later point might\r
}\r
}\r
\r
+ //\r
+ // VMWare SVGA is handled like Bochs (with port IO only).\r
+ //\r
+ if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {\r
+ Private->Variant = QEMU_VIDEO_BOCHS;\r
+ Private->FrameBufferVramBarIndex = PCI_BAR_IDX1;\r
+ }\r
+\r
//\r
// Check if accessing the bochs interface works.\r
//\r
}\r
}\r
\r
- //\r
- // Check if accessing Vmware SVGA interface works\r
- //\r
- if (Private->Variant == QEMU_VIDEO_VMWARE_SVGA) {\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *IoDesc;\r
- UINT32 TargetId;\r
- UINT32 SvgaIdRead;\r
-\r
- IoDesc = NULL;\r
- Status = Private->PciIo->GetBarAttributes (\r
- Private->PciIo,\r
- PCI_BAR_IDX0,\r
- NULL,\r
- (VOID**) &IoDesc\r
- );\r
- if (EFI_ERROR (Status) ||\r
- IoDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_IO ||\r
- IoDesc->AddrRangeMin > MAX_UINT16 + 1 - (VMWARE_SVGA_VALUE_PORT + 4)) {\r
- if (IoDesc != NULL) {\r
- FreePool (IoDesc);\r
- }\r
- Status = EFI_DEVICE_ERROR;\r
- goto RestoreAttributes;\r
- }\r
- Private->VmwareSvgaBasePort = (UINT16) IoDesc->AddrRangeMin;\r
- FreePool (IoDesc);\r
-\r
- TargetId = VMWARE_SVGA_ID_2;\r
- while (TRUE) {\r
- VmwareSvgaWrite (Private, VmwareSvgaRegId, TargetId);\r
- SvgaIdRead = VmwareSvgaRead (Private, VmwareSvgaRegId);\r
- if ((SvgaIdRead == TargetId) || (TargetId <= VMWARE_SVGA_ID_0)) {\r
- break;\r
- }\r
- TargetId--;\r
- }\r
-\r
- if (SvgaIdRead != TargetId) {\r
- DEBUG ((\r
- DEBUG_ERROR,\r
- "QemuVideo: QEMU_VIDEO_VMWARE_SVGA ID mismatch "\r
- "(got 0x%x, base address 0x%x)\n",\r
- SvgaIdRead,\r
- Private->VmwareSvgaBasePort\r
- ));\r
- Status = EFI_DEVICE_ERROR;\r
- goto RestoreAttributes;\r
- }\r
-\r
- Private->FrameBufferVramBarIndex = PCI_BAR_IDX1;\r
- }\r
-\r
//\r
// Get ParentDevicePath\r
//\r
case QEMU_VIDEO_BOCHS:\r
Status = QemuVideoBochsModeSetup (Private, IsQxl);\r
break;\r
- case QEMU_VIDEO_VMWARE_SVGA:\r
- Status = QemuVideoVmwareSvgaModeSetup (Private);\r
- break;\r
default:\r
ASSERT (FALSE);\r
Status = EFI_DEVICE_ERROR;\r
\r
FreeModeData:\r
FreePool (Private->ModeData);\r
- if (Private->VmwareSvgaModeInfo != NULL) {\r
- FreePool (Private->VmwareSvgaModeInfo);\r
- }\r
\r
UninstallGopDevicePath:\r
gBS->UninstallProtocolInterface (Private->Handle,\r
);\r
\r
FreePool (Private->ModeData);\r
- if (Private->VmwareSvgaModeInfo != NULL) {\r
- FreePool (Private->VmwareSvgaModeInfo);\r
- }\r
gBS->UninstallProtocolInterface (Private->Handle,\r
&gEfiDevicePathProtocolGuid, Private->GopDevicePath);\r
FreePool (Private->GopDevicePath);\r
return Data;\r
}\r
\r
-VOID\r
-VmwareSvgaWrite (\r
- QEMU_VIDEO_PRIVATE_DATA *Private,\r
- UINT16 Register,\r
- UINT32 Value\r
- )\r
-{\r
- UnalignedIoWrite32 (\r
- Private->VmwareSvgaBasePort + VMWARE_SVGA_INDEX_PORT,\r
- Register\r
- );\r
- UnalignedIoWrite32 (\r
- Private->VmwareSvgaBasePort + VMWARE_SVGA_VALUE_PORT,\r
- Value\r
- );\r
-}\r
-\r
-UINT32\r
-VmwareSvgaRead (\r
- QEMU_VIDEO_PRIVATE_DATA *Private,\r
- UINT16 Register\r
- )\r
-{\r
- UnalignedIoWrite32 (\r
- Private->VmwareSvgaBasePort + VMWARE_SVGA_INDEX_PORT,\r
- Register\r
- );\r
- return UnalignedIoRead32 (\r
- Private->VmwareSvgaBasePort + VMWARE_SVGA_VALUE_PORT\r
- );\r
-}\r
-\r
VOID\r
VgaOutb (\r
QEMU_VIDEO_PRIVATE_DATA *Private,\r
ClearScreen (Private);\r
}\r
\r
-VOID\r
-InitializeVmwareSvgaGraphicsMode (\r
- QEMU_VIDEO_PRIVATE_DATA *Private,\r
- QEMU_VIDEO_BOCHS_MODES *ModeData\r
- )\r
-{\r
- UINT32 Capabilities;\r
-\r
- VmwareSvgaWrite (Private, VmwareSvgaRegWidth, ModeData->Width);\r
- VmwareSvgaWrite (Private, VmwareSvgaRegHeight, ModeData->Height);\r
-\r
- Capabilities = VmwareSvgaRead (\r
- Private,\r
- VmwareSvgaRegCapabilities\r
- );\r
- if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) != 0) {\r
- VmwareSvgaWrite (\r
- Private,\r
- VmwareSvgaRegBitsPerPixel,\r
- ModeData->ColorDepth\r
- );\r
- }\r
-\r
- VmwareSvgaWrite (Private, VmwareSvgaRegEnable, 1);\r
-\r
- SetDefaultPalette (Private);\r
- ClearScreen (Private);\r
-}\r
-\r
EFI_STATUS\r
EFIAPI\r
InitializeQemuVideo (\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // Install EFI Driver Supported EFI Version Protocol required for\r
- // EFI drivers that are on PCI and other plug in cards.\r
- //\r
- gQemuVideoDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &ImageHandle,\r
- &gEfiDriverSupportedEfiVersionProtocolGuid,\r
- &gQemuVideoDriverSupportedEfiVersion,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
return Status;\r
}\r