summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2022-04-08 10:23:33 +0200
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2022-04-25 21:01:13 +0000
commit916f90baa547b3ebef8fa87c530e2f0c8e35e1e3 (patch)
tree3c0203a6a40fcf79b10ad1e3ce9870f392a796da
parent86de090b9950aaa0d8392745088fb0b150f17f3a (diff)
downloadedk2-916f90baa547b3ebef8fa87c530e2f0c8e35e1e3.tar.gz
edk2-916f90baa547b3ebef8fa87c530e2f0c8e35e1e3.tar.bz2
edk2-916f90baa547b3ebef8fa87c530e2f0c8e35e1e3.zip
OvmfPkg/VirtioGpuDxe: query native display resolution from host
Try query native display resolution from the host. When successful, setup PcdVideoHorizontalResolution and PcdVideoVerticalResolution accordingly and add the video mode to the GOP mode list if needed. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
-rw-r--r--OvmfPkg/VirtioGpuDxe/Gop.c92
-rw-r--r--OvmfPkg/VirtioGpuDxe/VirtioGpu.h6
-rw-r--r--OvmfPkg/VirtioGpuDxe/VirtioGpu.inf6
3 files changed, 99 insertions, 5 deletions
diff --git a/OvmfPkg/VirtioGpuDxe/Gop.c b/OvmfPkg/VirtioGpuDxe/Gop.c
index 05daefcbfb..70a81c10c8 100644
--- a/OvmfPkg/VirtioGpuDxe/Gop.c
+++ b/OvmfPkg/VirtioGpuDxe/Gop.c
@@ -9,6 +9,7 @@
**/
#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
#include "VirtioGpu.h"
@@ -195,11 +196,54 @@ STATIC CONST GOP_RESOLUTION mGopResolutions[] = {
STATIC
VOID
EFIAPI
+GopNativeResolution (
+ IN VGPU_GOP *VgpuGop,
+ OUT UINT32 *XRes,
+ OUT UINT32 *YRes
+ )
+{
+ volatile VIRTIO_GPU_RESP_DISPLAY_INFO DisplayInfo;
+ EFI_STATUS Status;
+ UINTN Index;
+
+ Status = VirtioGpuGetDisplayInfo (VgpuGop->ParentBus, &DisplayInfo);
+ if (Status != EFI_SUCCESS) {
+ return;
+ }
+
+ for (Index = 0; Index < VIRTIO_GPU_MAX_SCANOUTS; Index++) {
+ if (!DisplayInfo.Pmodes[Index].Enabled ||
+ !DisplayInfo.Pmodes[Index].Rectangle.Width ||
+ !DisplayInfo.Pmodes[Index].Rectangle.Height)
+ {
+ continue;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: #%d: %dx%d\n",
+ __FUNCTION__,
+ Index,
+ DisplayInfo.Pmodes[Index].Rectangle.Width,
+ DisplayInfo.Pmodes[Index].Rectangle.Height
+ ));
+ if ((*XRes == 0) || (*YRes == 0)) {
+ *XRes = DisplayInfo.Pmodes[Index].Rectangle.Width;
+ *YRes = DisplayInfo.Pmodes[Index].Rectangle.Height;
+ }
+ }
+}
+
+STATIC
+VOID
+EFIAPI
GopInitialize (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This
)
{
- VGPU_GOP *VgpuGop;
+ VGPU_GOP *VgpuGop;
+ EFI_STATUS Status;
+ UINT32 XRes = 0, YRes = 0, Index;
VgpuGop = VGPU_GOP_FROM_GOP (This);
@@ -216,6 +260,37 @@ GopInitialize (
VgpuGop->GopMode.SizeOfInfo = sizeof VgpuGop->GopModeInfo;
VgpuGop->GopModeInfo.PixelFormat = PixelBltOnly;
+
+ //
+ // query host for display resolution
+ //
+ GopNativeResolution (VgpuGop, &XRes, &YRes);
+ if ((XRes == 0) || (YRes == 0)) {
+ return;
+ }
+
+ if (PcdGet8 (PcdVideoResolutionSource) == 0) {
+ Status = PcdSet32S (PcdVideoHorizontalResolution, XRes);
+ ASSERT_RETURN_ERROR (Status);
+ Status = PcdSet32S (PcdVideoVerticalResolution, YRes);
+ ASSERT_RETURN_ERROR (Status);
+ Status = PcdSet8S (PcdVideoResolutionSource, 2);
+ ASSERT_RETURN_ERROR (Status);
+ }
+
+ VgpuGop->NativeXRes = XRes;
+ VgpuGop->NativeYRes = YRes;
+ for (Index = 0; Index < ARRAY_SIZE (mGopResolutions); Index++) {
+ if ((mGopResolutions[Index].Width == XRes) &&
+ (mGopResolutions[Index].Height == YRes))
+ {
+ // native resolution already is in mode list
+ return;
+ }
+ }
+
+ // add to mode list
+ VgpuGop->GopMode.MaxMode++;
}
//
@@ -242,10 +317,17 @@ GopQueryMode (
return EFI_OUT_OF_RESOURCES;
}
- GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;
- GopModeInfo->VerticalResolution = mGopResolutions[ModeNumber].Height;
- GopModeInfo->PixelFormat = PixelBltOnly;
- GopModeInfo->PixelsPerScanLine = mGopResolutions[ModeNumber].Width;
+ if (ModeNumber < ARRAY_SIZE (mGopResolutions)) {
+ GopModeInfo->HorizontalResolution = mGopResolutions[ModeNumber].Width;
+ GopModeInfo->VerticalResolution = mGopResolutions[ModeNumber].Height;
+ } else {
+ VGPU_GOP *VgpuGop = VGPU_GOP_FROM_GOP (This);
+ GopModeInfo->HorizontalResolution = VgpuGop->NativeXRes;
+ GopModeInfo->VerticalResolution = VgpuGop->NativeYRes;
+ }
+
+ GopModeInfo->PixelFormat = PixelBltOnly;
+ GopModeInfo->PixelsPerScanLine = GopModeInfo->HorizontalResolution;
*SizeOfInfo = sizeof *GopModeInfo;
*Info = GopModeInfo;
diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h
index 1d781088bb..45da564152 100644
--- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.h
+++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.h
@@ -151,6 +151,12 @@ struct VGPU_GOP_STRUCT {
// BackingStore is non-NULL.
//
VOID *BackingStoreMap;
+
+ //
+ // native display resolution
+ //
+ UINT32 NativeXRes;
+ UINT32 NativeYRes;
};
//
diff --git a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
index 9e66bcd4b9..d88c87e129 100644
--- a/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
+++ b/OvmfPkg/VirtioGpuDxe/VirtioGpu.inf
@@ -25,6 +25,7 @@
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
@@ -43,3 +44,8 @@
gEfiGraphicsOutputProtocolGuid ## BY_START
gEfiPciIoProtocolGuid ## TO_START
gVirtioDeviceProtocolGuid ## TO_START
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution