The GraphicsConsoleDxe driver (in MdeModulePkg/Universal/Console)
determines the preferred video resolution from the dynamic PCDs
- gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
- gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
Before BDS connects the console(s), let's look up a UEFI variable called
"PreferredResolution" (belonging to gOvmfSystemConfigGuid), parse its
contents (eg. "1024x768"), and set the above PCDs accordingly.
This enables guests to set/query their preferred GOP resolutions
persistently (effective from next boot), using either the UEFI shell's
"setvar" and "dmpstore" commands:
setvar PreferredResolution -guid 7235C51C-0C80-4CAB-87AC-3B084A6304B1 \
-bs -rt -nv ="1024x768"
dmpstore PreferredResolution -guid 7235C51C-0C80-4CAB-87AC-3B084A6304B1
or the guest OS's own utilities that wrap gRT->SetVariable() /
gRT->GetVariable().
Setting the GOP resolution during boot is useful when the guest OS (for
lack of a dedicated display driver) continues to work with the original
GOP resolution and framebuffer.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <[email protected]>
---
OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf | 5 ++
OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c | 60 +++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
index a2b72ba..31ab235 100644
--- a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+++ b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -53,11 +53,16 @@
QemuFwCfgLib
LoadLinuxLib
+[Guids]
+ gOvmfSystemConfigGuid # ALWAYS_CONSUMED
+
[Pcd]
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
[Pcd.IA32, Pcd.X64]
gEfiMdePkgTokenSpaceGuid.PcdFSBClock
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index ab9c93e..2d20739 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -14,6 +14,7 @@
#include "BdsPlatform.h"
#include "QemuBootOrder.h"
+#include <Guid/OvmfSystemConfig.h>
//
@@ -1027,6 +1028,64 @@ Returns:
}
+/**
+ Read a resolution string with format "1024x768" from the PreferredResolution
+ variable under gOvmfSystemConfigGuid, and pass it to GraphicsConsoleDxe via
+ dynamic PCDs.
+
+ We don't try to enforce the format, we just recognize sensible resolutions
+ given in the correct format, and avoid undefined behavior.
+
+ @retval EFI_SUCCESS PCDs have been set.
+ @retval EFI_INVALID_PARAMETER Invalid format detected in variable contents.
+ @return Status codes from gRT->GetVariable().
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SetPreferredResolution (
+ VOID
+ )
+{
+ UINTN DataSize;
+ UINT8 Data[16];
+ EFI_STATUS Status;
+ STATIC CHAR16 Variable[] = L"PreferredResolution";
+ UINT32 Dimensions[2];
+ UINTN DimIdx;
+ UINTN Idx;
+
+ DataSize = sizeof Data;
+ Status = gRT->GetVariable (Variable, &gOvmfSystemConfigGuid, NULL, &DataSize,
+ Data);
+ if (EFI_ERROR (Status)) {
+ DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR,
+ "%a: failed to get %s: %r\n", __FUNCTION__, Variable, Status));
+ return Status;
+ }
+
+ ZeroMem (Dimensions, sizeof Dimensions);
+ DimIdx = 0;
+ for (Idx = 0; Idx < DataSize; ++Idx) {
+ if (Data[Idx] >= '0' && Data[Idx] <= '9' && DimIdx < 2) {
+ Dimensions[DimIdx] = Dimensions[DimIdx] * 10 + (Data[Idx] - '0');
+ } else if (Data[Idx] == 'x') {
+ ++DimIdx;
+ } else {
+ DEBUG ((EFI_D_ERROR, "%a: invalid format at position %d\n", __FUNCTION__,
+ (INT32) Idx));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "%a: setting %Ldx%Ld\n", __FUNCTION__,
+ (INT64) Dimensions[0], (INT64) Dimensions[1]));
+ PcdSet32 (PcdVideoHorizontalResolution, Dimensions[0]);
+ PcdSet32 (PcdVideoVerticalResolution, Dimensions[1]);
+ return EFI_SUCCESS;
+}
+
+
VOID
EFIAPI
PlatformBdsPolicyBehavior (
@@ -1108,6 +1167,7 @@ Returns:
//
// Connect platform console
//
+ SetPreferredResolution ();
Status = PlatformBdsConnectConsole (gPlatformConsole);
if (EFI_ERROR (Status)) {
//
--
1.8.3.1
------------------------------------------------------------------------------
WatchGuard Dimension instantly turns raw network data into actionable
security intelligence. It gives you real-time visual feedback on key
security issues and trends. Skip the complicated setup - simply import
a virtual appliance and go from zero to informed in seconds.
http://pubads.g.doubleclick.net/gampad/clk?id=123612991&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel