mirror of https://github.com/acidanthera/audk.git
OvmfPkg/QemuVideoDxe: parse edid blob, detect display resolution
Check whenever an EDID blob is present. In case it is get the display resolution from it. Unless PcdVideoResolutionSource indicates the display resolution has been set already, update PcdVideoHorizontalResolution and PcdVideoVerticalResolution accordingly. Also add the resolution to the mode list. This will make OVMF boot up with the display resolution configured by QEMU, which is 1280x800 by default. The resolution can be set using the xres and yres properties. Here is an example for FullHD: qemu-system-x86_64 -device VGA,xres=1920,yres=1080 Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3778 Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1749250 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
55c05427b9
commit
49a2d8cbf5
|
@ -284,6 +284,88 @@ QemuVideoBochsAddMode (
|
|||
Private->MaxMode++;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
QemuVideoBochsEdid (
|
||||
QEMU_VIDEO_PRIVATE_DATA *Private,
|
||||
UINT32 *XRes,
|
||||
UINT32 *YRes
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (Private->Variant != QEMU_VIDEO_BOCHS_MMIO) {
|
||||
return;
|
||||
}
|
||||
|
||||
Status = Private->PciIo->Mem.Read (
|
||||
Private->PciIo,
|
||||
EfiPciIoWidthUint8,
|
||||
PCI_BAR_IDX2,
|
||||
0,
|
||||
sizeof (Private->Edid),
|
||||
Private->Edid
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: mmio read failed\n",
|
||||
__FUNCTION__
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Private->Edid[0] != 0x00) ||
|
||||
(Private->Edid[1] != 0xff))
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: magic check failed\n",
|
||||
__FUNCTION__
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: blob found (extensions: %d)\n",
|
||||
__FUNCTION__,
|
||||
Private->Edid[126]
|
||||
));
|
||||
|
||||
if ((Private->Edid[54] == 0x00) &&
|
||||
(Private->Edid[55] == 0x00))
|
||||
{
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: no detailed timing descriptor\n",
|
||||
__FUNCTION__
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
*XRes = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4);
|
||||
*YRes = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4);
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"%a: default resolution: %dx%d\n",
|
||||
__FUNCTION__,
|
||||
*XRes,
|
||||
*YRes
|
||||
));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// TODO: register edid as gEfiEdidDiscoveredProtocolGuid ?
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
QemuVideoBochsModeSetup (
|
||||
QEMU_VIDEO_PRIVATE_DATA *Private,
|
||||
|
@ -291,7 +373,7 @@ QemuVideoBochsModeSetup (
|
|||
)
|
||||
{
|
||||
UINT32 AvailableFbSize;
|
||||
UINT32 Index;
|
||||
UINT32 Index, XRes = 0, YRes = 0;
|
||||
|
||||
//
|
||||
// Fetch the available framebuffer size.
|
||||
|
@ -374,13 +456,29 @@ QemuVideoBochsModeSetup (
|
|||
// Setup Video Modes
|
||||
//
|
||||
Private->ModeData = AllocatePool (
|
||||
sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT
|
||||
sizeof (Private->ModeData[0]) * (QEMU_VIDEO_BOCHS_MODE_COUNT+1)
|
||||
);
|
||||
if (Private->ModeData == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
QemuVideoBochsEdid (Private, &XRes, &YRes);
|
||||
if (XRes && YRes) {
|
||||
QemuVideoBochsAddMode (
|
||||
Private,
|
||||
AvailableFbSize,
|
||||
XRes,
|
||||
YRes
|
||||
);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index++) {
|
||||
if ((QemuVideoBochsModes[Index].Width == XRes) &&
|
||||
(QemuVideoBochsModes[Index].Height == YRes))
|
||||
{
|
||||
continue; // duplicate with edid resolution
|
||||
}
|
||||
|
||||
QemuVideoBochsAddMode (
|
||||
Private,
|
||||
AvailableFbSize,
|
||||
|
|
|
@ -115,6 +115,8 @@ typedef struct {
|
|||
FRAME_BUFFER_CONFIGURE *FrameBufferBltConfigure;
|
||||
UINTN FrameBufferBltConfigureSize;
|
||||
UINT8 FrameBufferVramBarIndex;
|
||||
|
||||
UINT8 Edid[128];
|
||||
} QEMU_VIDEO_PRIVATE_DATA;
|
||||
|
||||
///
|
||||
|
|
|
@ -63,4 +63,7 @@
|
|||
|
||||
[Pcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdVideoResolutionSource
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
|
||||
|
|
Loading…
Reference in New Issue