From: Laszlo Ersek <lersek@redhat.com>
To: Phil Dennis-Jordan <lists@philjordan.eu>, edk2-devel@lists.01.org
Cc: Jordan Justen <jordan.l.justen@intel.com>,
Phil Dennis-Jordan <phil@philjordan.eu>
Subject: Re: [PATCH v4 3/3] OvmfPkg/QemuVideoDxe: VMWare SVGA device support
Date: Wed, 5 Apr 2017 15:58:33 +0200 [thread overview]
Message-ID: <9ccc975c-36ad-e3ba-d909-3863c09dbf57@redhat.com> (raw)
In-Reply-To: <1491396916-53170-4-git-send-email-lists@philjordan.eu>
On 04/05/17 14:55, Phil Dennis-Jordan wrote:
> From: Phil Dennis-Jordan <phil@philjordan.eu>
>
> 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 <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
> ---
>
> Notes:
> v2:
> - Unaligned I/O helper functions moved to separate commit [Laszlo]
> - Multi-line function call whitespace fixes.
>
> 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. [Laszlo]
> - 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.
>
> v4:
> - Simplified mode info pixel mask calculation & PCI BAR OOB check. [Laszlo]
> - Replaced struct assignment with CopyMem. [Laszlo]
> - Whitespace & comment typo fixes. [Laszlo]
Also, you moved around the "BytesPerLine" assignment.
Then I noticed that you actually moved around the *second* instance of
it, so you continue to have two identical assignments, one of which
should be superfluous:
[snip]
> +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
> + );
> + BytesPerLine = VmwareSvgaRead (
> + Private,
> + VmwareSvgaRegBytesPerLine
> + );
This is #1.
> +
> + 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);
This is #2.
Which one do you want to keep? I think we should drop #1, and keep #2.
Do you wish to submit v5, or are you okay if I remove #1 for you at
commit time?
With this tweak,
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Before committing, I would like to give Jordan a chance to comment as
well. I think Friday this week should be a good day to commit the series.
Impressive work!
Thank you,
Laszlo
> + 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;
> +}
>
next prev parent reply other threads:[~2017-04-05 13:58 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-05 12:55 [PATCH v4 0/3] OvmfPkg/QemuVideoDxe: Add VMWare SVGA framebuffer support Phil Dennis-Jordan
2017-04-05 12:55 ` [PATCH v4 1/3] OvmfPkg: VMWare SVGA display device register definitions Phil Dennis-Jordan
2017-04-05 12:55 ` [PATCH v4 2/3] OvmfPkg/QemuVideoDxe: Helper functions for unaligned port I/O Phil Dennis-Jordan
2017-04-05 12:55 ` [PATCH v4 3/3] OvmfPkg/QemuVideoDxe: VMWare SVGA device support Phil Dennis-Jordan
2017-04-05 13:58 ` Laszlo Ersek [this message]
2017-04-05 19:41 ` Jordan Justen
2017-04-06 5:12 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9ccc975c-36ad-e3ba-d909-3863c09dbf57@redhat.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox