未验证 提交 7180cdb4 编写于 作者: P PMheart 提交者: GitHub

OpenCoreUefiInOut: Added `GopPassThrough` option to support GOP protocol over UGA (#211)

上级 8db317ca
......@@ -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),
......
/** @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,84 +172,79 @@ OcProvideUgaPassThrough (
// and 1 UGA protocol:
// - for unknown handle
//
DEBUG_CODE_BEGIN ();
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with UGA draw\n", (UINT32) OcCountProtocolInstances (&gEfiUgaDrawProtocolGuid)));
DEBUG_CODE_END ();
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiUgaDrawProtocolGuid,
&gEfiGraphicsOutputProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCC: Found %u handles with UGA draw\n", (UINT32) HandleCount));
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with GOP - %r\n", Status));
FreePool (HandleBuffer);
} else {
DEBUG ((DEBUG_INFO, "OCC: Found NO handles with UGA draw\n"));
return Status;
}
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiGraphicsOutputProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer
);
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]));
if (!EFI_ERROR (Status)) {
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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册