EFI: add support for graphics mode output
* We can now switch between graphics and text modes, and display the splash screen
This commit is contained in:
@@ -243,4 +243,5 @@ platform_switch_to_text_mode(void)
|
||||
{
|
||||
kSystemTable->ConOut->Reset(kSystemTable->ConOut, false);
|
||||
kSystemTable->ConOut->SetMode(kSystemTable->ConOut, sScreenMode);
|
||||
gKernelArgs.frame_buffer.enabled = false;
|
||||
}
|
||||
|
||||
@@ -4,22 +4,89 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <boot/kernel_args.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/platform/generic/video.h>
|
||||
#include <boot/stage2.h>
|
||||
|
||||
#include "efi_platform.h"
|
||||
|
||||
|
||||
static EFI_GUID sGraphicsOutputGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
static EFI_GRAPHICS_OUTPUT_PROTOCOL *sGraphicsOutput;
|
||||
static UINTN sGraphicsMode;
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
platform_init_video(void)
|
||||
{
|
||||
return B_ERROR;
|
||||
EFI_STATUS status = kBootServices->LocateProtocol(&sGraphicsOutputGuid,
|
||||
NULL, (void **)&sGraphicsOutput);
|
||||
if (sGraphicsOutput == NULL || status != EFI_SUCCESS) {
|
||||
gKernelArgs.frame_buffer.enabled = false;
|
||||
sGraphicsOutput = NULL;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
UINTN bestArea = 0;
|
||||
UINTN bestDepth = 0;
|
||||
|
||||
for (UINTN mode = 0; mode < sGraphicsOutput->Mode->MaxMode; ++mode) {
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||
UINTN size, depth;
|
||||
sGraphicsOutput->QueryMode(sGraphicsOutput, mode, &size, &info);
|
||||
UINTN area = info->HorizontalResolution * info->VerticalResolution;
|
||||
if (info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor)
|
||||
depth = 32;
|
||||
else if (info->PixelFormat == PixelBitMask
|
||||
&& info->PixelInformation.RedMask == 0xFF0000
|
||||
&& info->PixelInformation.GreenMask == 0x00FF00
|
||||
&& info->PixelInformation.BlueMask == 0x0000FF
|
||||
&& info->PixelInformation.ReservedMask == 0)
|
||||
depth = 24;
|
||||
else
|
||||
continue;
|
||||
|
||||
area *= depth;
|
||||
if (area >= bestArea) {
|
||||
bestArea = area;
|
||||
bestDepth = depth;
|
||||
sGraphicsMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestArea == 0 || bestDepth == 0) {
|
||||
sGraphicsOutput = NULL;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
platform_switch_to_logo(void)
|
||||
{
|
||||
if (sGraphicsOutput == NULL || gKernelArgs.frame_buffer.enabled)
|
||||
return;
|
||||
|
||||
sGraphicsOutput->SetMode(sGraphicsOutput, sGraphicsMode);
|
||||
gKernelArgs.frame_buffer.enabled = true;
|
||||
gKernelArgs.frame_buffer.physical_buffer.start =
|
||||
sGraphicsOutput->Mode->FrameBufferBase;
|
||||
gKernelArgs.frame_buffer.physical_buffer.size =
|
||||
sGraphicsOutput->Mode->FrameBufferSize;
|
||||
gKernelArgs.frame_buffer.width =
|
||||
sGraphicsOutput->Mode->Info->HorizontalResolution;
|
||||
gKernelArgs.frame_buffer.height =
|
||||
sGraphicsOutput->Mode->Info->VerticalResolution;
|
||||
gKernelArgs.frame_buffer.depth =
|
||||
sGraphicsOutput->Mode->Info->PixelFormat == PixelBitMask ? 24 : 32;
|
||||
gKernelArgs.frame_buffer.bytes_per_row =
|
||||
sGraphicsOutput->Mode->Info->PixelsPerScanLine
|
||||
* gKernelArgs.frame_buffer.depth / 8;
|
||||
|
||||
video_display_splash(gKernelArgs.frame_buffer.physical_buffer.start);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user