Reapply "OvmfPkg/QemuVideoDxe: VMWare SVGA device support"
This reverts commit98856a724c
, reapplyingc137d95081
. Note that the commit now being reverted is technically correct; the only reason we're reverting it is because it should not have been pushed past the Soft Feature Freeze for the edk2-stable201811 tag. Cc: Anthony Perard <anthony.perard@citrix.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Julien Grall <julien.grall@linaro.org> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Cc: yuchenlin <yuchenlin@synology.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1319 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: yuchenlin <yuchenlin@synology.com>
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
**/
|
||||
|
||||
#include <IndustryStandard/VmwareSvga.h>
|
||||
#include "Qemu.h"
|
||||
|
||||
|
||||
@@ -346,3 +347,159 @@ QemuVideoBochsModeSetup (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
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 =
|
||||
AllocatePool (sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT);
|
||||
if (Private->ModeData == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ModeDataAllocError;
|
||||
}
|
||||
|
||||
Private->VmwareSvgaModeInfo =
|
||||
AllocatePool (
|
||||
sizeof (Private->VmwareSvgaModeInfo[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT
|
||||
);
|
||||
if (Private->VmwareSvgaModeInfo == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ModeInfoAllocError;
|
||||
}
|
||||
|
||||
FbSize = VmwareSvgaRead (Private, VmwareSvgaRegFbSize);
|
||||
MaxWidth = VmwareSvgaRead (Private, VmwareSvgaRegMaxWidth);
|
||||
MaxHeight = VmwareSvgaRead (Private, VmwareSvgaRegMaxHeight);
|
||||
Capabilities = VmwareSvgaRead (Private, VmwareSvgaRegCapabilities);
|
||||
if ((Capabilities & VMWARE_SVGA_CAP_8BIT_EMULATION) != 0) {
|
||||
BitsPerPixel = VmwareSvgaRead (
|
||||
Private,
|
||||
VmwareSvgaRegHostBitsPerPixel
|
||||
);
|
||||
VmwareSvgaWrite (
|
||||
Private,
|
||||
VmwareSvgaRegBitsPerPixel,
|
||||
BitsPerPixel
|
||||
);
|
||||
} else {
|
||||
BitsPerPixel = VmwareSvgaRead (
|
||||
Private,
|
||||
VmwareSvgaRegBitsPerPixel
|
||||
);
|
||||
}
|
||||
|
||||
if (FbSize == 0 ||
|
||||
MaxWidth == 0 ||
|
||||
MaxHeight == 0 ||
|
||||
BitsPerPixel == 0 ||
|
||||
BitsPerPixel % 8 != 0) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto Rollback;
|
||||
}
|
||||
|
||||
ModeData = Private->ModeData;
|
||||
ModeInfo = Private->VmwareSvgaModeInfo;
|
||||
VideoMode = &QemuVideoBochsModes[0];
|
||||
for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) {
|
||||
UINTN RequiredFbSize;
|
||||
|
||||
RequiredFbSize = (UINTN) VideoMode->Width * VideoMode->Height *
|
||||
(BitsPerPixel / 8);
|
||||
if (RequiredFbSize <= FbSize &&
|
||||
VideoMode->Width <= MaxWidth &&
|
||||
VideoMode->Height <= MaxHeight) {
|
||||
UINT32 BytesPerLine;
|
||||
UINT32 RedMask, GreenMask, BlueMask, PixelMask;
|
||||
|
||||
VmwareSvgaWrite (
|
||||
Private,
|
||||
VmwareSvgaRegWidth,
|
||||
VideoMode->Width
|
||||
);
|
||||
VmwareSvgaWrite (
|
||||
Private,
|
||||
VmwareSvgaRegHeight,
|
||||
VideoMode->Height
|
||||
);
|
||||
|
||||
ModeData->InternalModeIndex = Index;
|
||||
ModeData->HorizontalResolution = VideoMode->Width;
|
||||
ModeData->VerticalResolution = VideoMode->Height;
|
||||
ModeData->ColorDepth = 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 = 0;
|
||||
ModeInfo->HorizontalResolution = ModeData->HorizontalResolution;
|
||||
ModeInfo->VerticalResolution = ModeData->VerticalResolution;
|
||||
|
||||
ModeInfo->PixelFormat = PixelBitMask;
|
||||
|
||||
RedMask = VmwareSvgaRead (Private, VmwareSvgaRegRedMask);
|
||||
ModeInfo->PixelInformation.RedMask = RedMask;
|
||||
|
||||
GreenMask = VmwareSvgaRead (Private, VmwareSvgaRegGreenMask);
|
||||
ModeInfo->PixelInformation.GreenMask = GreenMask;
|
||||
|
||||
BlueMask = VmwareSvgaRead (Private, VmwareSvgaRegBlueMask);
|
||||
ModeInfo->PixelInformation.BlueMask = BlueMask;
|
||||
|
||||
//
|
||||
// Reserved mask is whatever bits in the pixel not containing RGB data,
|
||||
// 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 == 32) {
|
||||
if (BlueMask == 0xff && GreenMask == 0xff00 && RedMask == 0xff0000) {
|
||||
ModeInfo->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
|
||||
} else if (BlueMask == 0xff0000 &&
|
||||
GreenMask == 0xff00 &&
|
||||
RedMask == 0xff) {
|
||||
ModeInfo->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;
|
||||
}
|
||||
PixelMask = MAX_UINT32;
|
||||
} else {
|
||||
PixelMask = (1u << BitsPerPixel) - 1;
|
||||
}
|
||||
ModeInfo->PixelInformation.ReservedMask =
|
||||
PixelMask & ~(RedMask | GreenMask | BlueMask);
|
||||
|
||||
BytesPerLine = VmwareSvgaRead (Private, VmwareSvgaRegBytesPerLine);
|
||||
ModeInfo->PixelsPerScanLine = BytesPerLine / (BitsPerPixel / 8);
|
||||
|
||||
ModeData++;
|
||||
ModeInfo++;
|
||||
}
|
||||
VideoMode++;
|
||||
}
|
||||
Private->MaxMode = ModeData - Private->ModeData;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
Rollback:
|
||||
FreePool (Private->VmwareSvgaModeInfo);
|
||||
Private->VmwareSvgaModeInfo = NULL;
|
||||
|
||||
ModeInfoAllocError:
|
||||
FreePool (Private->ModeData);
|
||||
Private->ModeData = NULL;
|
||||
|
||||
ModeDataAllocError:
|
||||
return Status;
|
||||
}
|
||||
|
Reference in New Issue
Block a user