mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2026-02-01 15:59:39 +00:00
OpenCoreUefiInOut: Added GopPassThrough option to support GOP protocol over UGA (#211)
This commit is contained in:
parent
8db317ca84
commit
7180cdb43b
@ -13,6 +13,7 @@ OpenCore Changelog
|
||||
- Fixed switching to graphics mode when entering OpenCanopy
|
||||
- Fixed installing Apple FB Info protocol when no GOP exists
|
||||
- Fixed abort timeout sound in OpenCanopy on key press
|
||||
- Added `GopPassThrough` option to support GOP protocol over UGA
|
||||
|
||||
#### v0.6.6
|
||||
- Added keyboard and pointer entry scroll support in OpenCanopy
|
||||
|
||||
@ -6395,6 +6395,15 @@ functioning. Feature highlights:
|
||||
performance or fix rendering issues. However, this option is not recommended unless
|
||||
there is an obvious benefit as it may result in issues such as slower scrolling.
|
||||
|
||||
\item
|
||||
\texttt{GopPassThrough}\\
|
||||
\textbf{Type}: \texttt{plist\ boolean}\\
|
||||
\textbf{Failsafe}: \texttt{false}\\
|
||||
\textbf{Description}: Provide GOP protocol instances on top of UGA protocol instances.
|
||||
|
||||
Some types of firmware do not implement the GOP protocol, this option provides it via
|
||||
a UGA-based proxy. This option requires \texttt{ProvideConsoleGop} to be enabled. (TODO)
|
||||
|
||||
\item
|
||||
\texttt{IgnoreTextInGraphics}\\
|
||||
\textbf{Type}: \texttt{plist\ boolean}\\
|
||||
|
||||
@ -1141,6 +1141,8 @@
|
||||
<false/>
|
||||
<key>ForceResolution</key>
|
||||
<false/>
|
||||
<key>GopPassThrough</key>
|
||||
<false/>
|
||||
<key>IgnoreTextInGraphics</key>
|
||||
<false/>
|
||||
<key>ProvideConsoleGop</key>
|
||||
|
||||
@ -1338,6 +1338,8 @@
|
||||
<false/>
|
||||
<key>ForceResolution</key>
|
||||
<false/>
|
||||
<key>GopPassThrough</key>
|
||||
<false/>
|
||||
<key>IgnoreTextInGraphics</key>
|
||||
<false/>
|
||||
<key>ProvideConsoleGop</key>
|
||||
|
||||
@ -622,6 +622,7 @@ typedef enum {
|
||||
_(BOOLEAN , ReconnectOnResChange , , FALSE , ()) \
|
||||
_(BOOLEAN , SanitiseClearScreen , , FALSE , ()) \
|
||||
_(BOOLEAN , UgaPassThrough , , FALSE , ()) \
|
||||
_(BOOLEAN , GopPassThrough , , FALSE , ()) \
|
||||
_(BOOLEAN , DirectGopRendering , , FALSE , ()) \
|
||||
_(BOOLEAN , ForceResolution , , FALSE , ())
|
||||
OC_DECLARE (OC_UEFI_OUTPUT)
|
||||
|
||||
@ -182,6 +182,16 @@ OcProvideUgaPassThrough (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Provide GOP protocol instances on top of existing UGA instances.
|
||||
|
||||
@retval EFI_SUCCESS on success.
|
||||
**/
|
||||
EFI_STATUS
|
||||
OcProvideGopPassThrough (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Install and initialise Apple Framebuffer Info protocol
|
||||
on top of GOP protocol. For EfiBoot 10.4, which can only
|
||||
|
||||
@ -739,6 +739,7 @@ mUefiOutputSchema[] = {
|
||||
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_BOOLEAN_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),
|
||||
|
||||
372
Library/OcConsoleLib/GopPassThrough.c
Normal file
372
Library/OcConsoleLib/GopPassThrough.c
Normal file
@ -0,0 +1,372 @@
|
||||
/** @file
|
||||
Copyright (C) 2020, vit9696. All rights reserved.
|
||||
Copyright (C) 2021, PMheart. All rights reserved.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
|
||||
#include "OcConsoleLibInternal.h"
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <Library/OcMiscLib.h>
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcGopDrawQueryMode (
|
||||
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
|
||||
IN UINT32 ModeNumber,
|
||||
OUT UINTN *SizeOfInfo,
|
||||
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
|
||||
)
|
||||
{
|
||||
if (ModeNumber != 0) {
|
||||
DEBUG ((DEBUG_VERBOSE, "OCC: OcGopDrawQueryMode invalid ModeNumber - %u\n", ModeNumber));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (SizeOfInfo == NULL || Info == NULL) {
|
||||
DEBUG ((DEBUG_VERBOSE, "OCC: OcGopDrawQueryMode got invalid parameter SizeOfInfo or Info!\n"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*SizeOfInfo = This->Mode->SizeOfInfo;
|
||||
*Info = AllocateCopyPool (This->Mode->SizeOfInfo, This->Mode->Info);
|
||||
if (*Info == NULL) {
|
||||
DEBUG ((DEBUG_VERBOSE, "OCC: OcGopDrawQueryMode failed to allocate memory for GOP Info!\n"));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcGopDrawSetMode (
|
||||
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
|
||||
IN UINT32 ModeNumber
|
||||
)
|
||||
{
|
||||
if (ModeNumber != 0) {
|
||||
DEBUG ((DEBUG_VERBOSE, "OCC: OcGopDrawSetMode unsupported ModeNumber - %u\n", ModeNumber));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Assuming 0 is the only mode that is accepted, which is already set.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
OcGopDrawBlt (
|
||||
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
|
||||
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
|
||||
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
|
||||
IN UINTN SourceX,
|
||||
IN UINTN SourceY,
|
||||
IN UINTN DestinationX,
|
||||
IN UINTN DestinationY,
|
||||
IN UINTN Width,
|
||||
IN UINTN Height,
|
||||
IN UINTN Delta OPTIONAL
|
||||
)
|
||||
{
|
||||
OC_GOP_PROTOCOL *OcGopDraw;
|
||||
|
||||
OcGopDraw = BASE_CR (This, OC_GOP_PROTOCOL, GraphicsOutput);
|
||||
|
||||
return OcGopDraw->Uga->Blt (
|
||||
OcGopDraw->Uga,
|
||||
(EFI_UGA_PIXEL *) BltBuffer,
|
||||
(EFI_UGA_BLT_OPERATION) BltOperation,
|
||||
SourceX,
|
||||
SourceY,
|
||||
DestinationX,
|
||||
DestinationY,
|
||||
Width,
|
||||
Height,
|
||||
Delta
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
OcProvideGopPassThrough (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN HandleCount;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN Index;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
||||
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
|
||||
OC_GOP_PROTOCOL *OcGopDraw;
|
||||
APPLE_FRAMEBUFFER_INFO_PROTOCOL *FramebufferInfo;
|
||||
EFI_PHYSICAL_ADDRESS FramebufferBase;
|
||||
UINT32 FramebufferSize;
|
||||
UINT32 ScreenRowBytes;
|
||||
UINT32 ScreenWidth;
|
||||
UINT32 ScreenHeight;
|
||||
UINT32 ScreenDepth;
|
||||
UINT32 HorizontalResolution;
|
||||
UINT32 VerticalResolution;
|
||||
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
|
||||
UINT32 ColorDepth;
|
||||
UINT32 RefreshRate;
|
||||
BOOLEAN HasAppleFramebuffer;
|
||||
|
||||
//
|
||||
// We should not proxy UGA when there is no AppleFramebuffer,
|
||||
// but on systems where there is nothing, it is the only option.
|
||||
// REF: https://github.com/acidanthera/bugtracker/issues/1498
|
||||
//
|
||||
Status = gBS->LocateProtocol (
|
||||
&gAppleFramebufferInfoProtocolGuid,
|
||||
NULL,
|
||||
(VOID *) &FramebufferInfo
|
||||
);
|
||||
HasAppleFramebuffer = !EFI_ERROR (Status);
|
||||
|
||||
DEBUG_CODE_BEGIN ();
|
||||
HandleCount = (UINT32) OcCountProtocolInstances (&gEfiGraphicsOutputProtocolGuid);
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with GOP draw\n", HandleCount));
|
||||
|
||||
HandleCount = (UINT32) OcCountProtocolInstances (&gAppleFramebufferInfoProtocolGuid);
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with Apple Framebuffer info\n", HandleCount));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to locate AppleFramebufferInfo protocol - %r\n", Status));
|
||||
} else {
|
||||
Status = FramebufferInfo->GetInfo (
|
||||
FramebufferInfo,
|
||||
&FramebufferBase,
|
||||
&FramebufferSize,
|
||||
&ScreenRowBytes,
|
||||
&ScreenWidth,
|
||||
&ScreenHeight,
|
||||
&ScreenDepth
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: AppleFramebufferInfo - Got Base %Lx, Size %u, RowBytes %u, Width %u, Height %u, Depth %u\n",
|
||||
FramebufferBase,
|
||||
FramebufferSize,
|
||||
ScreenRowBytes,
|
||||
ScreenWidth,
|
||||
ScreenHeight,
|
||||
ScreenDepth
|
||||
));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCC: AppleFramebufferInfo failed to retrieve info - %r\n", Status));
|
||||
}
|
||||
}
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with UGA - %r\n", Status));
|
||||
FreePool (HandleBuffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with UGA for GOP check\n", (UINT32) HandleCount));
|
||||
for (Index = 0; Index < HandleCount; ++Index) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Trying handle %u - %p\n", (UINT32) Index, HandleBuffer[Index]));
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
(VOID **) &UgaDraw
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: No UGA protocol - %r\n", Status));
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiGraphicsOutputProtocolGuid,
|
||||
(VOID **) &GraphicsOutput
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Skipping GOP proxying as it is already present on handle %u - %p\n", (UINT32) Index, HandleBuffer[Index]));
|
||||
continue;
|
||||
}
|
||||
|
||||
FramebufferBase = 0;
|
||||
FramebufferSize = 0;
|
||||
ScreenRowBytes = 0;
|
||||
PixelFormat = PixelBltOnly;
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gAppleFramebufferInfoProtocolGuid,
|
||||
(VOID **) &FramebufferInfo
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: Failed to retrieve AppleFramebufferInfo protocol on handle %u - %p (%r)\n",
|
||||
(UINT32) Index,
|
||||
HandleBuffer[Index],
|
||||
Status
|
||||
));
|
||||
if (HasAppleFramebuffer) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: Got AppleFramebufferInfo protocol on handle %u - %p\n",
|
||||
(UINT32) Index,
|
||||
HandleBuffer[Index]
|
||||
));
|
||||
|
||||
Status = FramebufferInfo->GetInfo (
|
||||
FramebufferInfo,
|
||||
&FramebufferBase,
|
||||
&FramebufferSize,
|
||||
&ScreenRowBytes,
|
||||
&ScreenWidth,
|
||||
&ScreenHeight,
|
||||
&ScreenDepth
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
PixelFormat = PixelRedGreenBlueReserved8BitPerColor; ///< or PixelBlueGreenRedReserved8BitPerColor?
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: AppleFramebufferInfo - Got Base %Lx, Size %u, RowBytes %u, Width %u, Height %u, Depth %u on handle %u - %p\n",
|
||||
FramebufferBase,
|
||||
FramebufferSize,
|
||||
ScreenRowBytes,
|
||||
ScreenWidth,
|
||||
ScreenHeight,
|
||||
ScreenDepth,
|
||||
(UINT32) Index,
|
||||
HandleBuffer[Index]
|
||||
));
|
||||
} else {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: Failed to get info from AppleFramebufferInfo protocol on handle %u - %p (%r)\n",
|
||||
(UINT32) Index,
|
||||
HandleBuffer[Index],
|
||||
Status
|
||||
));
|
||||
if (HasAppleFramebuffer) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Status = UgaDraw->GetMode (
|
||||
UgaDraw,
|
||||
&HorizontalResolution,
|
||||
&VerticalResolution,
|
||||
&ColorDepth,
|
||||
&RefreshRate
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: UGA->GetMode returns error - %r\n", Status));
|
||||
continue;
|
||||
}
|
||||
|
||||
OcGopDraw = AllocateZeroPool (sizeof (*OcGopDraw));
|
||||
if (OcGopDraw == NULL) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to allocate GOP protocol\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
OcGopDraw->Uga = UgaDraw;
|
||||
OcGopDraw->GraphicsOutput.QueryMode = OcGopDrawQueryMode;
|
||||
OcGopDraw->GraphicsOutput.SetMode = OcGopDrawSetMode;
|
||||
OcGopDraw->GraphicsOutput.Blt = OcGopDrawBlt;
|
||||
OcGopDraw->GraphicsOutput.Mode = AllocateZeroPool (sizeof (*OcGopDraw->GraphicsOutput.Mode));
|
||||
if (OcGopDraw->GraphicsOutput.Mode == NULL) {
|
||||
FreePool (OcGopDraw);
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Only Mode 0 is supported, so there is only one mode supported in total.
|
||||
//
|
||||
OcGopDraw->GraphicsOutput.Mode->MaxMode = 1;
|
||||
//
|
||||
// Again, only Mode 0 is supported.
|
||||
//
|
||||
OcGopDraw->GraphicsOutput.Mode->Mode = 0;
|
||||
OcGopDraw->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (*OcGopDraw->GraphicsOutput.Mode->Info));
|
||||
if (OcGopDraw->GraphicsOutput.Mode->Info == NULL) {
|
||||
FreePool (OcGopDraw->GraphicsOutput.Mode);
|
||||
FreePool (OcGopDraw);
|
||||
continue;
|
||||
}
|
||||
OcGopDraw->GraphicsOutput.Mode->Info->Version = 0;
|
||||
OcGopDraw->GraphicsOutput.Mode->Info->HorizontalResolution = HorizontalResolution;
|
||||
OcGopDraw->GraphicsOutput.Mode->Info->VerticalResolution = VerticalResolution;
|
||||
OcGopDraw->GraphicsOutput.Mode->Info->PixelFormat = PixelFormat;
|
||||
//
|
||||
// No pixel mask is needed (i.e. all zero) in PixelInformation,
|
||||
// plus AllocateZeroPool already assigns zero for it.
|
||||
// Skip.
|
||||
//------------------------------------------------------------------------------
|
||||
// ScreenRowBytes is PixelsPerScanLine * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),
|
||||
// so here to divide it back.
|
||||
//
|
||||
OcGopDraw->GraphicsOutput.Mode->Info->PixelsPerScanLine = ScreenRowBytes / sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
|
||||
OcGopDraw->GraphicsOutput.Mode->SizeOfInfo = sizeof (*OcGopDraw->GraphicsOutput.Mode->Info);
|
||||
OcGopDraw->GraphicsOutput.Mode->FrameBufferBase = FramebufferBase;
|
||||
OcGopDraw->GraphicsOutput.Mode->FrameBufferSize = FramebufferSize;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&HandleBuffer[Index],
|
||||
&gEfiGraphicsOutputProtocolGuid,
|
||||
&OcGopDraw->GraphicsOutput,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (OcGopDraw->GraphicsOutput.Mode->Info);
|
||||
FreePool (OcGopDraw->GraphicsOutput.Mode);
|
||||
FreePool (OcGopDraw);
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: Installed GOP protocol - %r (Handle %u - %p, Resolution %ux%u, FramebufferBase %Lx, PixelFormat %d)\n",
|
||||
Status,
|
||||
(UINT32) Index,
|
||||
HandleBuffer[Index],
|
||||
HorizontalResolution,
|
||||
VerticalResolution,
|
||||
FramebufferBase,
|
||||
PixelFormat
|
||||
));
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -41,6 +41,7 @@
|
||||
[Sources]
|
||||
ConsoleControl.c
|
||||
ConsoleGop.c
|
||||
GopPassThrough.c
|
||||
FramebufferInfo.c
|
||||
OcConsoleLib.c
|
||||
OcConsoleLibInternal.h
|
||||
|
||||
@ -29,6 +29,11 @@ typedef struct {
|
||||
EFI_UGA_DRAW_PROTOCOL Uga;
|
||||
} OC_UGA_PROTOCOL;
|
||||
|
||||
typedef struct {
|
||||
EFI_UGA_DRAW_PROTOCOL *Uga;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
|
||||
} OC_GOP_PROTOCOL;
|
||||
|
||||
EFI_STATUS
|
||||
OcSetConsoleResolutionForProtocol (
|
||||
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
|
||||
#include <Library/OcMiscLib.h>
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
@ -170,20 +172,9 @@ OcProvideUgaPassThrough (
|
||||
// and 1 UGA protocol:
|
||||
// - for unknown handle
|
||||
//
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with UGA draw\n", (UINT32) HandleCount));
|
||||
FreePool (HandleBuffer);
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found NO handles with UGA draw\n"));
|
||||
}
|
||||
DEBUG_CODE_BEGIN ();
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with UGA draw\n", (UINT32) OcCountProtocolInstances (&gEfiUgaDrawProtocolGuid)));
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
@ -192,62 +183,68 @@ OcProvideUgaPassThrough (
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with GOP - %r\n", Status));
|
||||
FreePool (HandleBuffer);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with GOP for UGA check\n", (UINT32) HandleCount));
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < HandleCount; ++Index) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Trying handle %u - %p\n", (UINT32) Index, HandleBuffer[Index]));
|
||||
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with GOP for UGA check\n", (UINT32) HandleCount));
|
||||
for (Index = 0; Index < HandleCount; ++Index) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Trying handle %u - %p\n", (UINT32) Index, HandleBuffer[Index]));
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiGraphicsOutputProtocolGuid,
|
||||
(VOID **) &GraphicsOutput
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: No GOP protocol - %r\n", Status));
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
(VOID **) &UgaDraw
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: No UGA protocol - %r\n", Status));
|
||||
|
||||
OcUgaDraw = AllocateZeroPool (sizeof (*OcUgaDraw));
|
||||
if (OcUgaDraw == NULL) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to allocate UGA protocol\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
OcUgaDraw->GraphicsOutput = GraphicsOutput;
|
||||
OcUgaDraw->Uga.GetMode = OcUgaDrawGetMode;
|
||||
OcUgaDraw->Uga.SetMode = OcUgaDrawSetMode;
|
||||
OcUgaDraw->Uga.Blt = OcUgaDrawBlt;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&HandleBuffer[Index],
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
&OcUgaDraw->Uga,
|
||||
NULL
|
||||
);
|
||||
|
||||
DEBUG ((DEBUG_INFO, "OCC: Installed UGA protocol - %r\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Has UGA protocol, skip\n"));
|
||||
continue;
|
||||
}
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiGraphicsOutputProtocolGuid,
|
||||
(VOID **) &GraphicsOutput
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: No GOP protocol - %r\n", Status));
|
||||
continue;
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with GOP\n"));
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
(VOID **) &UgaDraw
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Skipping UGA proxying as it is already present on handle %u - %p\n", (UINT32) Index, HandleBuffer[Index]));
|
||||
continue;
|
||||
}
|
||||
|
||||
OcUgaDraw = AllocateZeroPool (sizeof (*OcUgaDraw));
|
||||
if (OcUgaDraw == NULL) {
|
||||
DEBUG ((DEBUG_INFO, "OCC: Failed to allocate UGA protocol\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
OcUgaDraw->GraphicsOutput = GraphicsOutput;
|
||||
OcUgaDraw->Uga.GetMode = OcUgaDrawGetMode;
|
||||
OcUgaDraw->Uga.SetMode = OcUgaDrawSetMode;
|
||||
OcUgaDraw->Uga.Blt = OcUgaDrawBlt;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&HandleBuffer[Index],
|
||||
&gEfiUgaDrawProtocolGuid,
|
||||
&OcUgaDraw->Uga,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (OcUgaDraw);
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OCC: Installed UGA protocol - %r (Handle %u - %p)\n",
|
||||
Status,
|
||||
(UINT32) Index,
|
||||
HandleBuffer[Index]
|
||||
));
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -190,6 +190,17 @@ OcLoadUefiOutputSupport (
|
||||
UINT32 Bpp;
|
||||
BOOLEAN SetMax;
|
||||
|
||||
if (Config->Uefi.Output.GopPassThrough) {
|
||||
Status = OcProvideGopPassThrough ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OC: OcProvideGopPassThrough status - %r\n",
|
||||
Status
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (Config->Uefi.Output.ProvideConsoleGop) {
|
||||
OcProvideConsoleGop (TRUE);
|
||||
}
|
||||
@ -244,7 +255,14 @@ OcLoadUefiOutputSupport (
|
||||
}
|
||||
|
||||
if (Config->Uefi.Output.UgaPassThrough) {
|
||||
OcProvideUgaPassThrough ();
|
||||
Status = OcProvideUgaPassThrough ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"OC: OcProvideUgaPassThrough status - %r\n",
|
||||
Status
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
AsciiRenderer = OC_BLOB_GET (&Config->Uefi.Output.TextRenderer);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user