Introduce ability to change screen resolution
All checks were successful
Builds / ExectOS (i686) (push) Successful in 44s
Builds / ExectOS (amd64) (push) Successful in 46s

This commit is contained in:
Rafal Kupiec 2024-03-15 15:12:12 +01:00
parent 662b49d96e
commit 848731c9e6
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
4 changed files with 333 additions and 115 deletions

View File

@ -123,6 +123,7 @@ typedef EFI_STATUS (*PBL_EXECIMAGE_VERIFY_IMAGE)(IN PVOID ImagePointer);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PEFI_GRAPHICS_PROTOCOL Protocol); typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PEFI_GRAPHICS_PROTOCOL Protocol);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PXTBL_FRAMEBUFFER_INFORMATION FbInfo); typedef EFI_STATUS (*PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PXTBL_FRAMEBUFFER_INFORMATION FbInfo);
typedef EFI_STATUS (*PBL_FRAMEBUFFER_INITIALIZE)(); typedef EFI_STATUS (*PBL_FRAMEBUFFER_INITIALIZE)();
typedef EFI_STATUS (*PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION)(IN UINT Width, IN UINT Height);
/* Boot parameters structure */ /* Boot parameters structure */
typedef struct _XTBL_BOOT_PARAMETERS typedef struct _XTBL_BOOT_PARAMETERS
@ -252,24 +253,35 @@ typedef struct _XTBL_FRAMEBUFFER_INFORMATION
EFI_GRAPHICS_PROTOCOL Protocol; EFI_GRAPHICS_PROTOCOL Protocol;
EFI_PHYSICAL_ADDRESS FrameBufferBase; EFI_PHYSICAL_ADDRESS FrameBufferBase;
ULONG_PTR FrameBufferSize; ULONG_PTR FrameBufferSize;
UINT Width; UINT DefaultMode;
UINT Height; union
UINT BitsPerPixel; {
UINT BytesPerPixel; PEFI_GRAPHICS_OUTPUT_PROTOCOL Gop;
UINT PixelsPerScanLine; PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL Uga;
UINT Pitch; } Driver;
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
struct struct
{ {
USHORT BlueMask; UINT Width;
USHORT BlueShift; UINT Height;
USHORT GreenMask; UINT Depth;
USHORT GreenShift; UINT RefreshRate;
USHORT RedMask; UINT BitsPerPixel;
USHORT RedShift; UINT BytesPerPixel;
USHORT ReservedMask; UINT PixelsPerScanLine;
USHORT ReservedShift; UINT Pitch;
} PixelInformation; EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
struct
{
USHORT BlueMask;
USHORT BlueShift;
USHORT GreenMask;
USHORT GreenShift;
USHORT RedMask;
USHORT RedShift;
USHORT ReservedMask;
USHORT ReservedShift;
} PixelInformation;
} ModeInfo;
} XTBL_FRAMEBUFFER_INFORMATION, *PXTBL_FRAMEBUFFER_INFORMATION; } XTBL_FRAMEBUFFER_INFORMATION, *PXTBL_FRAMEBUFFER_INFORMATION;
/* XTLDR ACPI protocol structure */ /* XTLDR ACPI protocol structure */
@ -311,6 +323,7 @@ typedef struct _XTBL_FRAMEBUFFER_PROTOCOL
PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver; PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver;
PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation; PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation;
PBL_FRAMEBUFFER_INITIALIZE Initialize; PBL_FRAMEBUFFER_INITIALIZE Initialize;
PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION SetScreenResolution;
} XTBL_FRAMEBUFFER_PROTOCOL, *PXTBL_FRAMEBUFFER_PROTOCOL; } XTBL_FRAMEBUFFER_PROTOCOL, *PXTBL_FRAMEBUFFER_PROTOCOL;
/* XTLDR Loader protocol structure */ /* XTLDR Loader protocol structure */

View File

@ -13,7 +13,7 @@
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>"); MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
MODULE_DESCRIPTION(L"EFI FB (FrameBuffer) support"); MODULE_DESCRIPTION(L"EFI FB (FrameBuffer) support");
MODULE_LICENSE(L"GPLv3"); MODULE_LICENSE(L"GPLv3");
MODULE_VERSION(L"0.1"); MODULE_VERSION(L"0.2");
/** /**
* Provides an EFI Frame Buffer protocol driver name used for initialization. * Provides an EFI Frame Buffer protocol driver name used for initialization.
@ -65,14 +65,14 @@ FbGetDisplayInformation(OUT PXTBL_FRAMEBUFFER_INFORMATION FbInfo)
} }
/* Copy framebuffer information */ /* Copy framebuffer information */
FbInfo->BitsPerPixel = FbpDisplayInfo.BitsPerPixel; FbInfo->ModeInfo.BitsPerPixel = FbpDisplayInfo.ModeInfo.BitsPerPixel;
FbInfo->BytesPerPixel = FbpDisplayInfo.BytesPerPixel; FbInfo->ModeInfo.BytesPerPixel = FbpDisplayInfo.ModeInfo.BytesPerPixel;
FbInfo->PixelFormat = FbpDisplayInfo.PixelFormat; FbInfo->ModeInfo.PixelFormat = FbpDisplayInfo.ModeInfo.PixelFormat;
FbInfo->PixelInformation = FbpDisplayInfo.PixelInformation; FbInfo->ModeInfo.PixelInformation = FbpDisplayInfo.ModeInfo.PixelInformation;
FbInfo->PixelsPerScanLine = FbpDisplayInfo.PixelsPerScanLine; FbInfo->ModeInfo.PixelsPerScanLine = FbpDisplayInfo.ModeInfo.PixelsPerScanLine;
FbInfo->Width = FbpDisplayInfo.Width; FbInfo->ModeInfo.Width = FbpDisplayInfo.ModeInfo.Width;
FbInfo->Height = FbpDisplayInfo.Height; FbInfo->ModeInfo.Height = FbpDisplayInfo.ModeInfo.Height;
FbInfo->Pitch = FbpDisplayInfo.Pitch; FbInfo->ModeInfo.Pitch = FbpDisplayInfo.ModeInfo.Pitch;
FbInfo->FrameBufferBase = FbpDisplayInfo.FrameBufferBase; FbInfo->FrameBufferBase = FbpDisplayInfo.FrameBufferBase;
FbInfo->FrameBufferSize = FbpDisplayInfo.FrameBufferSize; FbInfo->FrameBufferSize = FbpDisplayInfo.FrameBufferSize;
FbInfo->Protocol = FbpDisplayInfo.Protocol; FbInfo->Protocol = FbpDisplayInfo.Protocol;
@ -96,10 +96,7 @@ FbInitializeDisplay()
EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID; EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID;
PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION GopModeInfo; PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION GopModeInfo;
PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL Uga; UINT Depth, QueryMode, Refresh;
PEFI_GRAPHICS_OUTPUT_PROTOCOL Gop;
EFI_PIXEL_BITMASK PixelBitMask;
UINT Depth, Refresh;
ULONG_PTR InfoSize; ULONG_PTR InfoSize;
EFI_HANDLE Handle; EFI_HANDLE Handle;
EFI_STATUS Status; EFI_STATUS Status;
@ -107,19 +104,17 @@ FbInitializeDisplay()
/* Check if framebuffer already initialized */ /* Check if framebuffer already initialized */
if(!FbpDisplayInfo.Initialized) if(!FbpDisplayInfo.Initialized)
{ {
/* Set initial framebuffer state */ /* Print debug message */
XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n"); XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n");
FbpDisplayInfo.Protocol = NONE;
FbpDisplayInfo.Initialized = FALSE;
/* Attempt to open EFI GOP protocol */ /* Attempt to open EFI GOP protocol */
Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&Gop, &GopGuid); Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&FbpDisplayInfo.Driver.Gop, &GopGuid);
/* Check if Graphics Output Protocol (GOP) is available */ /* Check if Graphics Output Protocol (GOP) is available */
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Check if there are any video modes available */ /* Check if there are any video modes available */
if(Gop->Mode->MaxMode == 0) if(FbpDisplayInfo.Driver.Gop->Mode->MaxMode == 0)
{ {
/* No video modes available */ /* No video modes available */
XtLdrProtocol->Debug.Print(L"ERROR: No GOP video mode available\n"); XtLdrProtocol->Debug.Print(L"ERROR: No GOP video mode available\n");
@ -127,11 +122,12 @@ FbInitializeDisplay()
} }
/* Query current graphics mode */ /* Query current graphics mode */
Status = Gop->QueryMode(Gop, Gop->Mode == NULL ? 0 : Gop->Mode->Mode, &InfoSize, &GopModeInfo); QueryMode = FbpDisplayInfo.Driver.Gop->Mode == NULL ? 0 : FbpDisplayInfo.Driver.Gop->Mode->Mode;
Status = FbpDisplayInfo.Driver.Gop->QueryMode(FbpDisplayInfo.Driver.Gop, QueryMode, &InfoSize, &GopModeInfo);
if(Status == STATUS_EFI_NOT_STARTED) if(Status == STATUS_EFI_NOT_STARTED)
{ {
/* Set the mode to circumvent buggy UEFI firmware */ /* Set the mode to circumvent buggy UEFI firmware */
Status = Gop->SetMode(Gop, 0); Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, 0);
} }
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@ -140,22 +136,19 @@ FbInitializeDisplay()
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
/* Store GOP framebuffer information */ /* Store frame buffer base address and protocol used */
FbpDisplayInfo.FrameBufferBase = FbpDisplayInfo.Driver.Gop->Mode->FrameBufferBase;
FbpDisplayInfo.DefaultMode = FbpDisplayInfo.Driver.Gop->Mode->Mode;
FbpDisplayInfo.Protocol = GOP; FbpDisplayInfo.Protocol = GOP;
FbpDisplayInfo.Width = Gop->Mode->Info->HorizontalResolution;
FbpDisplayInfo.Height = Gop->Mode->Info->VerticalResolution;
FbpDisplayInfo.PixelsPerScanLine = Gop->Mode->Info->PixelsPerScanLine;
FbpDisplayInfo.PixelFormat = Gop->Mode->Info->PixelFormat;
/* Get pixel bit mask information */ /* Get current mode information */
PixelBitMask = Gop->Mode->Info->PixelInformation; Status = FbpGetModeInfo();
if(Status != STATUS_EFI_SUCCESS)
/* Set framebuffer address and size */ {
FbpDisplayInfo.FrameBufferBase = Gop->Mode->FrameBufferBase; /* Unable to get mode information */
FbpDisplayInfo.FrameBufferSize = Gop->Mode->FrameBufferSize; XtLdrProtocol->Debug.Print(L"ERROR: Failed to get GOP mode information (Status Code: 0x%zX)\n");
return STATUS_EFI_UNSUPPORTED;
/* Get pixel information */ }
FbpGetPixelInformation(&FbpDisplayInfo, &PixelBitMask);
/* Found GOP */ /* Found GOP */
XtLdrProtocol->Debug.Print(L"Found EFI-GOP compatible display adapter @ %P (%zu bytes)\n", XtLdrProtocol->Debug.Print(L"Found EFI-GOP compatible display adapter @ %P (%zu bytes)\n",
@ -167,13 +160,14 @@ FbInitializeDisplay()
else else
{ {
/* GOP is unavailable, attempt to open UGA protocol */ /* GOP is unavailable, attempt to open UGA protocol */
Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&Uga, &UgaGuid); Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&FbpDisplayInfo.Driver.Uga, &UgaGuid);
/* Check if Universal Graphics Adapter (UGA) is available */ /* Check if Universal Graphics Adapter (UGA) is available */
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Get current video mode */ /* Get current video mode */
Status = Uga->GetMode(Uga, &FbpDisplayInfo.Width, &FbpDisplayInfo.Height, &Depth, &Refresh); Status = FbpDisplayInfo.Driver.Uga->GetMode(FbpDisplayInfo.Driver.Uga, &FbpDisplayInfo.ModeInfo.Width,
&FbpDisplayInfo.ModeInfo.Height, &Depth, &Refresh);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Unable to get current UGA mode */ /* Unable to get current UGA mode */
@ -196,21 +190,18 @@ FbInitializeDisplay()
return STATUS_EFI_DEVICE_ERROR; return STATUS_EFI_DEVICE_ERROR;
} }
/* Set framebuffer information */ /* Store framebuffer protocol information */
FbpDisplayInfo.DefaultMode = 0;
FbpDisplayInfo.Protocol = UGA; FbpDisplayInfo.Protocol = UGA;
FbpDisplayInfo.PixelsPerScanLine = FbpDisplayInfo.Width;
FbpDisplayInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
/* Get pixel bit mask information */ /* Get mode information */
PixelBitMask = (EFI_PIXEL_BITMASK){0, 0, 0, 0}; Status = FbpGetModeInfo();
if(Status != STATUS_EFI_SUCCESS)
/* Get pixel information */ {
FbpGetPixelInformation(&FbpDisplayInfo, &PixelBitMask); /* Unable to get mode information */
XtLdrProtocol->Debug.Print(L"ERROR: Failed to get UGA mode information (Status Code: 0x%zX)\n");
/* Set framebuffer size */ return STATUS_EFI_UNSUPPORTED;
FbpDisplayInfo.FrameBufferSize = FbpDisplayInfo.Width * }
FbpDisplayInfo.Height *
FbpDisplayInfo.BytesPerPixel + 1024;
/* Found UGA */ /* Found UGA */
XtLdrProtocol->Debug.Print(L"Found EFI-UGA compatible display adapter @ %P (%zu bytes)\n", XtLdrProtocol->Debug.Print(L"Found EFI-UGA compatible display adapter @ %P (%zu bytes)\n",
@ -229,8 +220,8 @@ FbInitializeDisplay()
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
/* Calculate framebuffer pitch */ XtLdrProtocol->Debug.Print(L"Current screen resolution is %ux%ux%u\n", FbpDisplayInfo.ModeInfo.Width,
FbpDisplayInfo.Pitch = FbpDisplayInfo.PixelsPerScanLine * (FbpDisplayInfo.BitsPerPixel / 8); FbpDisplayInfo.ModeInfo.Height, FbpDisplayInfo.ModeInfo.BitsPerPixel);
/* Set framebuffer initialization flag */ /* Set framebuffer initialization flag */
FbpDisplayInfo.Initialized = TRUE; FbpDisplayInfo.Initialized = TRUE;
@ -240,6 +231,120 @@ FbInitializeDisplay()
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/**
* Sets custom screen resolution, based on the provided width and height.
*
* @param Width
* Supplies the width of the screen.
*
* @param Height
* Supplies the height of the screen.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
FbSetScreenResolution(IN UINT Width,
IN UINT Height)
{
PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
BOOLEAN ModeChanged;
EFI_STATUS Status;
UINT_PTR Size;
UINT Mode;
/* Check if framebuffer is initialized */
if(!FbpDisplayInfo.Initialized)
{
/* Framebuffer not ready to change screen mode */
return STATUS_EFI_NOT_READY;
}
ModeChanged = FALSE;
/* Change screen mode depending on display adapter protocol */
switch(FbpDisplayInfo.Protocol)
{
case GOP:
/* GOP available, check if user specified screen resolution */
if(Width == 0 || Height == 0)
{
/* No resolution specified, temporarily set lowest supported screen resolution */
Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, 1);
if(Status == STATUS_EFI_SUCCESS)
{
/* Restore default graphics mode */
Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, FbpDisplayInfo.DefaultMode);
ModeChanged = (Status == STATUS_EFI_SUCCESS);
}
}
else
{
/* User specified screen resolution, find a corresponding mode */
Mode = 1;
while(Mode <= FbpDisplayInfo.Driver.Gop->Mode->MaxMode)
{
/* Get mode information */
Status = FbpDisplayInfo.Driver.Gop->QueryMode(FbpDisplayInfo.Driver.Gop, Mode, &Size, &ModeInfo);
if(Status == STATUS_EFI_SUCCESS && Size >= sizeof(*ModeInfo) && ModeInfo != NULL)
{
/* Check if match found */
if(ModeInfo->HorizontalResolution == Width && ModeInfo->VerticalResolution == Height)
{
/* Found corresponding mode, attempt to set it */
Status = FbpDisplayInfo.Driver.Gop->SetMode(FbpDisplayInfo.Driver.Gop, Mode);
if(Status == STATUS_EFI_SUCCESS)
{
/* New mode set correctly, use it */
ModeChanged = TRUE;
break;
}
}
}
/* Try with next mode */
Mode++;
}
}
break;
case UGA:
/* Set UGA screen mode, trying to keep current color depth and refresh rate */
Status = FbpDisplayInfo.Driver.Uga->SetMode(FbpDisplayInfo.Driver.Uga, Width, Height,
FbpDisplayInfo.ModeInfo.Depth,
FbpDisplayInfo.ModeInfo.RefreshRate);
if(Status == STATUS_EFI_SUCCESS)
{
/* New mode set correctly, use it */
ModeChanged = TRUE;
}
break;
default:
/* This should never be reached */
break;
}
if(!ModeChanged)
{
/* Failed to change screen mode */
XtLdrProtocol->Debug.Print(L"ERROR: Failed to change screen mode to %ux%u (Status Code: 0x%zX)\n",
Width, Height, Status);
return STATUS_EFI_UNSUPPORTED;
}
/* Get new screen mode information */
Status = FbpGetModeInfo();
if(Status == STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Debug.Print(L"Changed screen resolution to %ux%ux%u\n", FbpDisplayInfo.ModeInfo.Width,
FbpDisplayInfo.ModeInfo.Height, FbpDisplayInfo.ModeInfo.BitsPerPixel);
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Finds a PCI Display Adapter and returns its framebuffer address. * Finds a PCI Display Adapter and returns its framebuffer address.
* *
@ -393,6 +498,86 @@ FbpGetColorMask(IN UINT PixelBitMask,
} }
} }
/**
* Gets information about the current display mode and stores it in internal structure.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
FbpGetModeInfo()
{
PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
EFI_PIXEL_BITMASK PixelBitMask;
XTSTATUS Status;
UINT_PTR Size;
switch(FbpDisplayInfo.Protocol)
{
case GOP:
/* Query GOP mode information */
Status = FbpDisplayInfo.Driver.Gop->QueryMode(FbpDisplayInfo.Driver.Gop,
FbpDisplayInfo.Driver.Gop->Mode->Mode,
&Size, &ModeInfo);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get GOP mode information, return error */
return Status;
}
/* Get pixel bit mask information */
FbpGetPixelInformation(&FbpDisplayInfo.Driver.Gop->Mode->Info->PixelInformation);
/* Store GOP framebuffer information */
FbpDisplayInfo.ModeInfo.Width = FbpDisplayInfo.Driver.Gop->Mode->Info->HorizontalResolution;
FbpDisplayInfo.ModeInfo.Height = FbpDisplayInfo.Driver.Gop->Mode->Info->VerticalResolution;
FbpDisplayInfo.ModeInfo.Depth = FbpDisplayInfo.ModeInfo.BitsPerPixel;
FbpDisplayInfo.ModeInfo.PixelsPerScanLine = FbpDisplayInfo.Driver.Gop->Mode->Info->PixelsPerScanLine;
FbpDisplayInfo.ModeInfo.Pitch = FbpDisplayInfo.ModeInfo.PixelsPerScanLine *
(FbpDisplayInfo.ModeInfo.BitsPerPixel / 8);
FbpDisplayInfo.ModeInfo.RefreshRate = 0;
/* Store pixel format information and frame buffer size */
FbpDisplayInfo.ModeInfo.PixelFormat = FbpDisplayInfo.Driver.Gop->Mode->Info->PixelFormat;
FbpDisplayInfo.FrameBufferSize = FbpDisplayInfo.Driver.Gop->Mode->FrameBufferSize;
break;
case UGA:
/* Query UGA mode information */
Status = FbpDisplayInfo.Driver.Uga->GetMode(FbpDisplayInfo.Driver.Uga, &FbpDisplayInfo.ModeInfo.Width,
&FbpDisplayInfo.ModeInfo.Height, &FbpDisplayInfo.ModeInfo.Depth,
&FbpDisplayInfo.ModeInfo.RefreshRate);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get UGA mode information, return error */
return Status;
}
/* Get pixel bit mask information */
PixelBitMask = (EFI_PIXEL_BITMASK){0, 0, 0, 0};
FbpGetPixelInformation(&PixelBitMask);
/* Store UGA framebuffer information */
FbpDisplayInfo.ModeInfo.PixelsPerScanLine = FbpDisplayInfo.ModeInfo.Width;
FbpDisplayInfo.ModeInfo.Pitch = FbpDisplayInfo.ModeInfo.PixelsPerScanLine *
(FbpDisplayInfo.ModeInfo.BitsPerPixel / 8);
/* Store pixel format information and recalculate frame buffer size */
FbpDisplayInfo.ModeInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
FbpDisplayInfo.FrameBufferSize = FbpDisplayInfo.ModeInfo.Width *
FbpDisplayInfo.ModeInfo.Height *
FbpDisplayInfo.ModeInfo.BytesPerPixel + 1024;
break;
default:
/* This should never be reached as no other display driver is supported */
break;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Gets pixel information based on the reported pixel format. * Gets pixel information based on the reported pixel format.
* *
@ -408,41 +593,40 @@ FbpGetColorMask(IN UINT PixelBitMask,
*/ */
XTCDECL XTCDECL
VOID VOID
FbpGetPixelInformation(IN OUT PXTBL_FRAMEBUFFER_INFORMATION FrameBufferInfo, FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask)
IN PEFI_PIXEL_BITMASK PixelsBitMask)
{ {
UINT CompoundMask; UINT CompoundMask;
/* Check reported pixel format */ /* Check reported pixel format */
switch(FrameBufferInfo->PixelFormat) switch(FbpDisplayInfo.ModeInfo.PixelFormat)
{ {
case PixelBlueGreenRedReserved8BitPerColor: case PixelBlueGreenRedReserved8BitPerColor:
/* BGRR, 32 bits per pixel */ /* BGRR, 32 bits per pixel */
FrameBufferInfo->BitsPerPixel = 32; FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
FrameBufferInfo->PixelInformation.BlueMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0xFF;
FrameBufferInfo->PixelInformation.BlueShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;
FrameBufferInfo->PixelInformation.GreenMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0xFF;
FrameBufferInfo->PixelInformation.GreenShift = 8; FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;
FrameBufferInfo->PixelInformation.RedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0xFF;
FrameBufferInfo->PixelInformation.RedShift = 16; FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 16;
FrameBufferInfo->PixelInformation.ReservedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0xFF;
FrameBufferInfo->PixelInformation.ReservedShift = 24; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;
break; break;
case PixelRedGreenBlueReserved8BitPerColor: case PixelRedGreenBlueReserved8BitPerColor:
/* RGBR, 32 bits per pixel */ /* RGBR, 32 bits per pixel */
FrameBufferInfo->BitsPerPixel = 32; FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
FrameBufferInfo->PixelInformation.BlueMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0xFF;
FrameBufferInfo->PixelInformation.BlueShift = 16; FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 16;
FrameBufferInfo->PixelInformation.GreenMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0xFF;
FrameBufferInfo->PixelInformation.GreenShift = 8; FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;
FrameBufferInfo->PixelInformation.RedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0xFF;
FrameBufferInfo->PixelInformation.RedShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0;
FrameBufferInfo->PixelInformation.ReservedMask = 0xFF; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0xFF;
FrameBufferInfo->PixelInformation.ReservedShift = 24; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;
break; break;
case PixelBitMask: case PixelBitMask:
/* Assume 32 bits per pixel */ /* Assume 32 bits per pixel */
FrameBufferInfo->BitsPerPixel = 32; FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
/* Calculate compound mask */ /* Calculate compound mask */
CompoundMask = PixelsBitMask->RedMask | CompoundMask = PixelsBitMask->RedMask |
@ -453,36 +637,36 @@ FbpGetPixelInformation(IN OUT PXTBL_FRAMEBUFFER_INFORMATION FrameBufferInfo,
/* Recalculate bits per pixel */ /* Recalculate bits per pixel */
while((CompoundMask & (1 << 31)) == 0) while((CompoundMask & (1 << 31)) == 0)
{ {
FrameBufferInfo->BitsPerPixel--; FbpDisplayInfo.ModeInfo.BitsPerPixel--;
CompoundMask <<= 1; CompoundMask <<= 1;
} }
/* Set pixel information */ /* Set pixel information */
FbpGetColorMask(PixelsBitMask->RedMask, &FrameBufferInfo->PixelInformation.RedMask, FbpGetColorMask(PixelsBitMask->RedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.RedMask,
&FrameBufferInfo->PixelInformation.RedShift); &FbpDisplayInfo.ModeInfo.PixelInformation.RedShift);
FbpGetColorMask(PixelsBitMask->GreenMask, &FrameBufferInfo->PixelInformation.GreenMask, FbpGetColorMask(PixelsBitMask->GreenMask, &FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask,
&FrameBufferInfo->PixelInformation.GreenShift); &FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift);
FbpGetColorMask(PixelsBitMask->BlueMask, &FrameBufferInfo->PixelInformation.BlueMask, FbpGetColorMask(PixelsBitMask->BlueMask, &FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask,
&FrameBufferInfo->PixelInformation.BlueShift); &FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift);
FbpGetColorMask(PixelsBitMask->ReservedMask, &FrameBufferInfo->PixelInformation.ReservedMask, FbpGetColorMask(PixelsBitMask->ReservedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask,
&FrameBufferInfo->PixelInformation.ReservedShift); &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift);
break; break;
default: default:
/* Unknown pixel format */ /* Unknown pixel format */
FrameBufferInfo->BitsPerPixel = 0; FbpDisplayInfo.ModeInfo.BitsPerPixel = 0;
FrameBufferInfo->PixelInformation.BlueMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0x0;
FrameBufferInfo->PixelInformation.BlueShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;
FrameBufferInfo->PixelInformation.GreenMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0x0;
FrameBufferInfo->PixelInformation.GreenShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 0;
FrameBufferInfo->PixelInformation.RedMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0x0;
FrameBufferInfo->PixelInformation.RedShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0;
FrameBufferInfo->PixelInformation.ReservedMask = 0x0; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0x0;
FrameBufferInfo->PixelInformation.ReservedShift = 0; FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0;
break; break;
} }
/* Calculate bytes per pixel based on bits per pixel */ /* Calculate bytes per pixel based on bits per pixel */
FrameBufferInfo->BytesPerPixel = FrameBufferInfo->BitsPerPixel >> 3; FbpDisplayInfo.ModeInfo.BytesPerPixel = FbpDisplayInfo.ModeInfo.BitsPerPixel >> 3;
} }
/** /**
@ -514,10 +698,15 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
return STATUS_EFI_PROTOCOL_ERROR; return STATUS_EFI_PROTOCOL_ERROR;
} }
/* Set initial framebuffer state */
FbpDisplayInfo.Protocol = NONE;
FbpDisplayInfo.Initialized = FALSE;
/* Set routines available via XTLDR framebuffer protocol */ /* Set routines available via XTLDR framebuffer protocol */
FbpFrameBufferProtocol.GetDisplayDriver = FbGetDisplayDriver; FbpFrameBufferProtocol.GetDisplayDriver = FbGetDisplayDriver;
FbpFrameBufferProtocol.GetDisplayInformation = FbGetDisplayInformation; FbpFrameBufferProtocol.GetDisplayInformation = FbGetDisplayInformation;
FbpFrameBufferProtocol.Initialize = FbInitializeDisplay; FbpFrameBufferProtocol.Initialize = FbInitializeDisplay;
FbpFrameBufferProtocol.SetScreenResolution = FbSetScreenResolution;
/* Register XTOS boot protocol */ /* Register XTOS boot protocol */
return XtLdrProtocol->Protocol.Install(&FbpFrameBufferProtocol, &Guid); return XtLdrProtocol->Protocol.Install(&FbpFrameBufferProtocol, &Guid);

View File

@ -14,10 +14,23 @@
/* FrameBuffer support protocol related routines forward references */ /* FrameBuffer support protocol related routines forward references */
XTCDECL
EFI_STATUS
FbGetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol);
XTCDECL
EFI_STATUS
FbGetDisplayInformation(OUT PXTBL_FRAMEBUFFER_INFORMATION FbInfo);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
FbInitializeDisplay(); FbInitializeDisplay();
XTCDECL
EFI_STATUS
FbSetScreenResolution(IN UINT Width,
IN UINT Height);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address); FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address);
@ -28,10 +41,13 @@ FbpGetColorMask(IN UINT EfiMask,
OUT PUSHORT ColorMask, OUT PUSHORT ColorMask,
OUT PUSHORT ColorShift); OUT PUSHORT ColorShift);
XTCDECL
EFI_STATUS
FbpGetModeInfo();
XTCDECL XTCDECL
VOID VOID
FbpGetPixelInformation(IN OUT PXTBL_FRAMEBUFFER_INFORMATION FrameBufferInfo, FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask);
IN PEFI_PIXEL_BITMASK PixelsBitMask);
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS

View File

@ -44,11 +44,11 @@ XtGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock,
InformationBlock->Protocol = FrameBufferInfo->Protocol; InformationBlock->Protocol = FrameBufferInfo->Protocol;
InformationBlock->Address = (PVOID)FrameBufferInfo->FrameBufferBase; InformationBlock->Address = (PVOID)FrameBufferInfo->FrameBufferBase;
InformationBlock->BufferSize = FrameBufferInfo->FrameBufferSize; InformationBlock->BufferSize = FrameBufferInfo->FrameBufferSize;
InformationBlock->Width = FrameBufferInfo->Width; InformationBlock->Width = FrameBufferInfo->ModeInfo.Width;
InformationBlock->Height = FrameBufferInfo->Height; InformationBlock->Height = FrameBufferInfo->ModeInfo.Height;
InformationBlock->BitsPerPixel = FrameBufferInfo->BitsPerPixel; InformationBlock->BitsPerPixel = FrameBufferInfo->ModeInfo.BitsPerPixel;
InformationBlock->PixelsPerScanLine = FrameBufferInfo->PixelsPerScanLine; InformationBlock->PixelsPerScanLine = FrameBufferInfo->ModeInfo.PixelsPerScanLine;
InformationBlock->Pitch = FrameBufferInfo->Pitch; InformationBlock->Pitch = FrameBufferInfo->ModeInfo.Pitch;
} }
XTCDECL XTCDECL