OcDriverConnectionLib: Add ReconnectGraphicsOnConnect option (#301)

This commit is contained in:
John Davis 2021-11-27 05:46:22 -06:00 committed by GitHub
parent a2fcc8d7eb
commit bf5043a862
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 15 deletions

View File

@ -10,6 +10,7 @@ OpenCore Changelog
- Added XCPM CPU power management ACPI table for Intel Alder Lake
- Updated draw order to avoid graphics tearing in OpenCanopy
- Fixed handling PCI device paths with logical units in ScanPolicy
- Added `ReconnectGraphicsOnConnect` option for enabling alternative UEFI graphics drivers
#### v0.7.5
- Revised OpenLinuxBoot documentation

View File

@ -7338,6 +7338,19 @@ with the boot menu.
\emph{Note}: This option will also replace incompatible implementations of GOP on the
console handle, as may be the case on the \texttt{MacPro5,1} when using modern GPUs.
\item
\texttt{ReconnectGraphicsOnConnect}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Description}: Reconnect all graphics drivers during driver connection.
On certain firmware, it may be desireable to use an alternative graphics driver
providing better screen resolution options on legacy machines, or a driver supporting
\texttt{ForceResolution}. This option attempts to disconnect all currently connected
graphics drivers before connecting newly loaded drivers.
\emph{Note}: This option requires \texttt{ConnectDrivers} to be enabled.
\item
\texttt{ReconnectOnResChange}\\
\textbf{Type}: \texttt{plist\ boolean}\\

View File

@ -1500,6 +1500,8 @@
<false/>
<key>ProvideConsoleGop</key>
<true/>
<key>ReconnectGraphicsOnConnect</key>
<false/>
<key>ReconnectOnResChange</key>
<false/>
<key>ReplaceTabWithSpace</key>

View File

@ -1838,6 +1838,8 @@
<false/>
<key>ProvideConsoleGop</key>
<true/>
<key>ReconnectGraphicsOnConnect</key>
<false/>
<key>ReconnectOnResChange</key>
<false/>
<key>ReplaceTabWithSpace</key>

View File

@ -654,7 +654,8 @@ typedef enum {
_(INT8 , UIScale , , -1 , ()) \
_(BOOLEAN , UgaPassThrough , , FALSE , ()) \
_(BOOLEAN , DirectGopRendering , , FALSE , ()) \
_(BOOLEAN , ForceResolution , , FALSE , ())
_(BOOLEAN , ForceResolution , , FALSE , ()) \
_(BOOLEAN , ReconnectGraphicsOnConnect , , FALSE , ())
OC_DECLARE (OC_UEFI_OUTPUT)
///

View File

@ -38,6 +38,14 @@ OcUnblockUnmountedPartitions (
VOID
);
/**
Disconnects all graphics drivers attached to PCI I/O protcols.
**/
VOID
OcDisconnectGraphicsDrivers (
VOID
);
/**
Disconnect effectively all drivers attached at handle.

View File

@ -774,20 +774,21 @@ mUefiInputSchema[] = {
STATIC
OC_SCHEMA
mUefiOutputSchema[] = {
OC_SCHEMA_BOOLEAN_IN ("ClearScreenOnModeSwitch",OC_GLOBAL_CONFIG, Uefi.Output.ClearScreenOnModeSwitch),
OC_SCHEMA_STRING_IN ("ConsoleMode", OC_GLOBAL_CONFIG, Uefi.Output.ConsoleMode),
OC_SCHEMA_BOOLEAN_IN ("DirectGopRendering", OC_GLOBAL_CONFIG, Uefi.Output.DirectGopRendering),
OC_SCHEMA_BOOLEAN_IN ("ForceResolution", OC_GLOBAL_CONFIG, Uefi.Output.ForceResolution),
OC_SCHEMA_STRING_IN ("GopPassThrough", OC_GLOBAL_CONFIG, Uefi.Output.GopPassThrough),
OC_SCHEMA_BOOLEAN_IN ("IgnoreTextInGraphics", OC_GLOBAL_CONFIG, Uefi.Output.IgnoreTextInGraphics),
OC_SCHEMA_BOOLEAN_IN ("ProvideConsoleGop", OC_GLOBAL_CONFIG, Uefi.Output.ProvideConsoleGop),
OC_SCHEMA_BOOLEAN_IN ("ReconnectOnResChange", OC_GLOBAL_CONFIG, Uefi.Output.ReconnectOnResChange),
OC_SCHEMA_BOOLEAN_IN ("ReplaceTabWithSpace", OC_GLOBAL_CONFIG, Uefi.Output.ReplaceTabWithSpace),
OC_SCHEMA_STRING_IN ("Resolution", OC_GLOBAL_CONFIG, Uefi.Output.Resolution),
OC_SCHEMA_BOOLEAN_IN ("SanitiseClearScreen", OC_GLOBAL_CONFIG, Uefi.Output.SanitiseClearScreen),
OC_SCHEMA_STRING_IN ("TextRenderer", OC_GLOBAL_CONFIG, Uefi.Output.TextRenderer),
OC_SCHEMA_INTEGER_IN ("UIScale", OC_GLOBAL_CONFIG, Uefi.Output.UIScale),
OC_SCHEMA_BOOLEAN_IN ("UgaPassThrough", OC_GLOBAL_CONFIG, Uefi.Output.UgaPassThrough),
OC_SCHEMA_BOOLEAN_IN ("ClearScreenOnModeSwitch", OC_GLOBAL_CONFIG, Uefi.Output.ClearScreenOnModeSwitch),
OC_SCHEMA_STRING_IN ("ConsoleMode", OC_GLOBAL_CONFIG, Uefi.Output.ConsoleMode),
OC_SCHEMA_BOOLEAN_IN ("DirectGopRendering", OC_GLOBAL_CONFIG, Uefi.Output.DirectGopRendering),
OC_SCHEMA_BOOLEAN_IN ("ForceResolution", OC_GLOBAL_CONFIG, Uefi.Output.ForceResolution),
OC_SCHEMA_STRING_IN ("GopPassThrough", OC_GLOBAL_CONFIG, Uefi.Output.GopPassThrough),
OC_SCHEMA_BOOLEAN_IN ("IgnoreTextInGraphics", OC_GLOBAL_CONFIG, Uefi.Output.IgnoreTextInGraphics),
OC_SCHEMA_BOOLEAN_IN ("ProvideConsoleGop", OC_GLOBAL_CONFIG, Uefi.Output.ProvideConsoleGop),
OC_SCHEMA_BOOLEAN_IN ("ReconnectGraphicsOnConnect",OC_GLOBAL_CONFIG, Uefi.Output.ReconnectGraphicsOnConnect),
OC_SCHEMA_BOOLEAN_IN ("ReconnectOnResChange", OC_GLOBAL_CONFIG, Uefi.Output.ReconnectOnResChange),
OC_SCHEMA_BOOLEAN_IN ("ReplaceTabWithSpace", OC_GLOBAL_CONFIG, Uefi.Output.ReplaceTabWithSpace),
OC_SCHEMA_STRING_IN ("Resolution", OC_GLOBAL_CONFIG, Uefi.Output.Resolution),
OC_SCHEMA_BOOLEAN_IN ("SanitiseClearScreen", OC_GLOBAL_CONFIG, Uefi.Output.SanitiseClearScreen),
OC_SCHEMA_STRING_IN ("TextRenderer", OC_GLOBAL_CONFIG, Uefi.Output.TextRenderer),
OC_SCHEMA_INTEGER_IN ("UIScale", OC_GLOBAL_CONFIG, Uefi.Output.UIScale),
OC_SCHEMA_BOOLEAN_IN ("UgaPassThrough", OC_GLOBAL_CONFIG, Uefi.Output.UgaPassThrough),
};
STATIC

View File

@ -12,7 +12,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <IndustryStandard/Pci.h>
#include <Protocol/BlockIo.h>
#include <Protocol/PciIo.h>
#include <Protocol/SimpleFileSystem.h>
#include <Library/DebugLib.h>
@ -126,3 +129,57 @@ OcUnblockUnmountedPartitions (
FreePool (Handles);
}
VOID
OcDisconnectGraphicsDrivers (
VOID
)
{
EFI_STATUS Status;
UINT32 Index;
UINTN HandleCount;
EFI_HANDLE *HandleBuffer;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
//
// Locate all currently connected PCI I/O protocols and disconnect graphics drivers.
//
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiPciIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCDC: Found %u handles with PCI I/O\n", (UINT32) HandleCount));
for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo
);
if (EFI_ERROR (Status)) {
continue;
}
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint32,
0,
sizeof (Pci) / sizeof (UINT32),
&Pci
);
if (!EFI_ERROR (Status)) {
if (IS_PCI_VGA (&Pci) == TRUE) {
Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
DEBUG ((DEBUG_INFO, "OCDC: Disconnected graphics driver handle %u - %p result - %r\n", Index, HandleBuffer[Index], Status));
}
}
}
FreePool (HandleBuffer);
}
}

View File

@ -905,6 +905,13 @@ OcLoadUefiSupport (
// DriversToConnect is not freed as it is owned by OcRegisterDriversToHighestPriority.
//
}
if (Config->Uefi.Output.ReconnectGraphicsOnConnect) {
DEBUG ((DEBUG_INFO, "OC: Disconnecting graphics drivers...\n"));
OcDisconnectGraphicsDrivers ();
DEBUG ((DEBUG_INFO, "OC: Disconnecting graphics drivers done...\n"));
}
OcConnectDrivers ();
DEBUG ((DEBUG_INFO, "OC: Connecting drivers done...\n"));
} else {