diff --git a/Changelog.md b/Changelog.md index 3e85e2a6..22aa5341 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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 diff --git a/Docs/Configuration.tex b/Docs/Configuration.tex index 5b084e70..14510201 100755 --- a/Docs/Configuration.tex +++ b/Docs/Configuration.tex @@ -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}\\ diff --git a/Docs/Sample.plist b/Docs/Sample.plist index 2430b30f..a43ace5f 100644 --- a/Docs/Sample.plist +++ b/Docs/Sample.plist @@ -1500,6 +1500,8 @@ ProvideConsoleGop + ReconnectGraphicsOnConnect + ReconnectOnResChange ReplaceTabWithSpace diff --git a/Docs/SampleCustom.plist b/Docs/SampleCustom.plist index 839dfc3c..e4992f04 100644 --- a/Docs/SampleCustom.plist +++ b/Docs/SampleCustom.plist @@ -1838,6 +1838,8 @@ ProvideConsoleGop + ReconnectGraphicsOnConnect + ReconnectOnResChange ReplaceTabWithSpace diff --git a/Include/Acidanthera/Library/OcConfigurationLib.h b/Include/Acidanthera/Library/OcConfigurationLib.h index bfcf8345..b36facb9 100644 --- a/Include/Acidanthera/Library/OcConfigurationLib.h +++ b/Include/Acidanthera/Library/OcConfigurationLib.h @@ -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) /// diff --git a/Include/Acidanthera/Library/OcDriverConnectionLib.h b/Include/Acidanthera/Library/OcDriverConnectionLib.h index 812b4231..fb8241d6 100644 --- a/Include/Acidanthera/Library/OcDriverConnectionLib.h +++ b/Include/Acidanthera/Library/OcDriverConnectionLib.h @@ -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. diff --git a/Library/OcConfigurationLib/OcConfigurationLib.c b/Library/OcConfigurationLib/OcConfigurationLib.c index 766f9dd8..6a08a441 100644 --- a/Library/OcConfigurationLib/OcConfigurationLib.c +++ b/Library/OcConfigurationLib/OcConfigurationLib.c @@ -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 diff --git a/Library/OcDriverConnectionLib/DriverDisconnection.c b/Library/OcDriverConnectionLib/DriverDisconnection.c index 6289f434..3a19722c 100644 --- a/Library/OcDriverConnectionLib/DriverDisconnection.c +++ b/Library/OcDriverConnectionLib/DriverDisconnection.c @@ -12,7 +12,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include +#include + #include +#include #include #include @@ -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); + } +} diff --git a/Library/OcMainLib/OpenCoreUefi.c b/Library/OcMainLib/OpenCoreUefi.c index a848e502..c1058e36 100644 --- a/Library/OcMainLib/OpenCoreUefi.c +++ b/Library/OcMainLib/OpenCoreUefi.c @@ -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 {