2020-07-09 21:06:48 +02:00
|
|
|
/** @file
|
|
|
|
Copyright (C) 2020, vit9696. 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>
|
|
|
|
|
|
|
|
STATIC
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
OcUgaDrawGetMode (
|
|
|
|
IN EFI_UGA_DRAW_PROTOCOL *This,
|
|
|
|
OUT UINT32 *HorizontalResolution,
|
|
|
|
OUT UINT32 *VerticalResolution,
|
|
|
|
OUT UINT32 *ColorDepth,
|
|
|
|
OUT UINT32 *RefreshRate
|
|
|
|
)
|
|
|
|
{
|
|
|
|
OC_UGA_PROTOCOL *OcUgaDraw;
|
|
|
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
|
|
|
|
|
|
|
|
DEBUG ((DEBUG_INFO, "OCC: OcUgaDrawGetMode %p\n", This));
|
|
|
|
|
|
|
|
if (This == NULL
|
|
|
|
|| HorizontalResolution == NULL
|
|
|
|
|| VerticalResolution == NULL
|
|
|
|
|| ColorDepth == NULL
|
|
|
|
|| RefreshRate == NULL) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga);
|
|
|
|
Info = OcUgaDraw->GraphicsOutput->Mode->Info;
|
|
|
|
|
|
|
|
DEBUG ((
|
|
|
|
DEBUG_INFO,
|
|
|
|
"OCC: OcUgaDrawGetMode Info is %ux%u (%u)\n",
|
|
|
|
Info->HorizontalResolution,
|
|
|
|
Info->VerticalResolution,
|
|
|
|
Info->PixelFormat
|
|
|
|
));
|
|
|
|
|
|
|
|
if (Info->HorizontalResolution == 0 || Info->VerticalResolution == 0) {
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
*HorizontalResolution = Info->HorizontalResolution;
|
|
|
|
*VerticalResolution = Info->VerticalResolution;
|
|
|
|
*ColorDepth = DEFAULT_COLOUR_DEPTH;
|
|
|
|
*RefreshRate = DEFAULT_REFRESH_RATE;
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
OcUgaDrawSetMode (
|
|
|
|
IN EFI_UGA_DRAW_PROTOCOL *This,
|
|
|
|
IN UINT32 HorizontalResolution,
|
|
|
|
IN UINT32 VerticalResolution,
|
|
|
|
IN UINT32 ColorDepth,
|
|
|
|
IN UINT32 RefreshRate
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
OC_UGA_PROTOCOL *OcUgaDraw;
|
|
|
|
|
|
|
|
OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga);
|
|
|
|
|
|
|
|
DEBUG ((
|
|
|
|
DEBUG_INFO,
|
|
|
|
"OCC: OcUgaDrawSetMode %p %ux%u@%u/%u\n",
|
|
|
|
This,
|
|
|
|
HorizontalResolution,
|
|
|
|
VerticalResolution,
|
|
|
|
ColorDepth,
|
|
|
|
RefreshRate
|
|
|
|
));
|
|
|
|
|
|
|
|
OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga);
|
|
|
|
|
|
|
|
Status = OcSetConsoleResolutionForProtocol (
|
|
|
|
OcUgaDraw->GraphicsOutput,
|
|
|
|
HorizontalResolution,
|
|
|
|
VerticalResolution,
|
|
|
|
ColorDepth
|
|
|
|
);
|
|
|
|
|
|
|
|
DEBUG ((DEBUG_INFO, "OCC: UGA SetConsoleResolutionOnHandle attempt - %r\n", Status));
|
|
|
|
|
2020-07-15 19:29:27 +02:00
|
|
|
if (EFI_ERROR(Status)) {
|
2020-07-09 21:06:48 +02:00
|
|
|
Status = OcSetConsoleResolutionForProtocol (
|
|
|
|
OcUgaDraw->GraphicsOutput,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0
|
|
|
|
);
|
|
|
|
DEBUG ((DEBUG_INFO, "OCC: UGA SetConsoleResolutionOnHandle max attempt - %r\n", Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
OcUgaDrawBlt (
|
|
|
|
IN EFI_UGA_DRAW_PROTOCOL *This,
|
|
|
|
IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
|
|
|
|
IN EFI_UGA_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_UGA_PROTOCOL *OcUgaDraw;
|
|
|
|
|
|
|
|
OcUgaDraw = BASE_CR (This, OC_UGA_PROTOCOL, Uga);
|
|
|
|
|
|
|
|
return OcUgaDraw->GraphicsOutput->Blt (
|
|
|
|
OcUgaDraw->GraphicsOutput,
|
|
|
|
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer,
|
|
|
|
(EFI_GRAPHICS_OUTPUT_BLT_OPERATION) BltOperation,
|
|
|
|
SourceX,
|
|
|
|
SourceY,
|
|
|
|
DestinationX,
|
|
|
|
DestinationY,
|
|
|
|
Width,
|
|
|
|
Height,
|
|
|
|
Delta
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
OcProvideUgaPassThrough (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINTN HandleCount;
|
|
|
|
EFI_HANDLE *HandleBuffer;
|
|
|
|
UINTN Index;
|
|
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
|
|
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
|
|
|
|
OC_UGA_PROTOCOL *OcUgaDraw;
|
|
|
|
|
|
|
|
//
|
|
|
|
// For now we do not use this, but as a side note:
|
|
|
|
// MacPro5,1 has 2 GOP protocols:
|
|
|
|
// - for GPU
|
|
|
|
// - for ConsoleOutput
|
|
|
|
// and 1 UGA protocol:
|
|
|
|
// - for unknown handle
|
|
|
|
//
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
|
|
ByProtocol,
|
|
|
|
&gEfiUgaDrawProtocolGuid,
|
|
|
|
NULL,
|
|
|
|
&HandleCount,
|
|
|
|
&HandleBuffer
|
|
|
|
);
|
|
|
|
|
2020-07-15 19:29:27 +02:00
|
|
|
if (!EFI_ERROR(Status)) {
|
2020-07-09 21:06:48 +02:00
|
|
|
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"));
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
|
|
ByProtocol,
|
|
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
|
|
NULL,
|
|
|
|
&HandleCount,
|
|
|
|
&HandleBuffer
|
|
|
|
);
|
|
|
|
|
2020-07-15 19:29:27 +02:00
|
|
|
if (!EFI_ERROR(Status)) {
|
2020-07-09 21:06:48 +02:00
|
|
|
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
|
|
|
|
);
|
|
|
|
|
2020-07-15 19:29:27 +02:00
|
|
|
if (EFI_ERROR(Status)) {
|
2020-07-09 21:06:48 +02:00
|
|
|
DEBUG ((DEBUG_INFO, "OCC: No GOP protocol - %r\n", Status));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gBS->HandleProtocol (
|
|
|
|
HandleBuffer[Index],
|
|
|
|
&gEfiUgaDrawProtocolGuid,
|
|
|
|
(VOID **) &UgaDraw
|
|
|
|
);
|
|
|
|
|
2020-07-15 19:29:27 +02:00
|
|
|
if (EFI_ERROR(Status)) {
|
2020-07-09 21:06:48 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FreePool (HandleBuffer);
|
|
|
|
} else {
|
|
|
|
DEBUG ((DEBUG_INFO, "OCC: Failed to find handles with GOP\n"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|