\r
**/\r
\r
-#include "Qemu.h"\r
+#include <IndustryStandard/VmwareSvga.h>\r
#include <IndustryStandard/Acpi.h>\r
+#include "Qemu.h"\r
+#include "UnalignedIoInternal.h"\r
\r
EFI_DRIVER_BINDING_PROTOCOL gQemuVideoDriverBinding = {\r
QemuVideoControllerDriverSupported,\r
0x0100,\r
QEMU_VIDEO_BOCHS,\r
L"QEMU QXL VGA"\r
+ },{\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
+ QEMU_VIDEO_VMWARE_SVGA,\r
+ L"QEMU VMWare SVGA"\r
},{\r
0 /* end of list */\r
}\r
}\r
\r
Status = EFI_UNSUPPORTED;\r
+ if (!IS_PCI_VGA (&Pci)) {\r
+ goto Done;\r
+ }\r
Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
if (Card != NULL) {\r
DEBUG ((EFI_D_INFO, "QemuVideo: %s detected\n", Card->Name));\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
+ // 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
goto UninstallGop;\r
}\r
\r
+#if defined MDE_CPU_IA32 || defined MDE_CPU_X64\r
if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO ||\r
Private->Variant == QEMU_VIDEO_BOCHS) {\r
InstallVbeShim (Card->Name, Private->GraphicsOutput.Mode->FrameBufferBase);\r
}\r
+#endif\r
\r
gBS->RestoreTPL (OldTpl);\r
return EFI_SUCCESS;\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
Private->PciIo->Mem.Write (\r
Private->PciIo,\r
EfiPciIoWidthFillUint32,\r
- 0,\r
+ Private->FrameBufferVramBarIndex,\r
0,\r
0x400000 >> 2,\r
&Color\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