Introduce ability to change screen resolution

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

View File

@ -13,7 +13,7 @@
MODULE_AUTHOR(L"Rafal Kupiec <belliash@codingworkshop.eu.org>");
MODULE_DESCRIPTION(L"EFI FB (FrameBuffer) support");
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.
@ -65,14 +65,14 @@ FbGetDisplayInformation(OUT PXTBL_FRAMEBUFFER_INFORMATION FbInfo)
}
/* Copy framebuffer information */
FbInfo->BitsPerPixel = FbpDisplayInfo.BitsPerPixel;
FbInfo->BytesPerPixel = FbpDisplayInfo.BytesPerPixel;
FbInfo->PixelFormat = FbpDisplayInfo.PixelFormat;
FbInfo->PixelInformation = FbpDisplayInfo.PixelInformation;
FbInfo->PixelsPerScanLine = FbpDisplayInfo.PixelsPerScanLine;
FbInfo->Width = FbpDisplayInfo.Width;
FbInfo->Height = FbpDisplayInfo.Height;
FbInfo->Pitch = FbpDisplayInfo.Pitch;
FbInfo->ModeInfo.BitsPerPixel = FbpDisplayInfo.ModeInfo.BitsPerPixel;
FbInfo->ModeInfo.BytesPerPixel = FbpDisplayInfo.ModeInfo.BytesPerPixel;
FbInfo->ModeInfo.PixelFormat = FbpDisplayInfo.ModeInfo.PixelFormat;
FbInfo->ModeInfo.PixelInformation = FbpDisplayInfo.ModeInfo.PixelInformation;
FbInfo->ModeInfo.PixelsPerScanLine = FbpDisplayInfo.ModeInfo.PixelsPerScanLine;
FbInfo->ModeInfo.Width = FbpDisplayInfo.ModeInfo.Width;
FbInfo->ModeInfo.Height = FbpDisplayInfo.ModeInfo.Height;
FbInfo->ModeInfo.Pitch = FbpDisplayInfo.ModeInfo.Pitch;
FbInfo->FrameBufferBase = FbpDisplayInfo.FrameBufferBase;
FbInfo->FrameBufferSize = FbpDisplayInfo.FrameBufferSize;
FbInfo->Protocol = FbpDisplayInfo.Protocol;
@ -96,10 +96,7 @@ FbInitializeDisplay()
EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID;
PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION GopModeInfo;
PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL Uga;
PEFI_GRAPHICS_OUTPUT_PROTOCOL Gop;
EFI_PIXEL_BITMASK PixelBitMask;
UINT Depth, Refresh;
UINT Depth, QueryMode, Refresh;
ULONG_PTR InfoSize;
EFI_HANDLE Handle;
EFI_STATUS Status;
@ -107,19 +104,17 @@ FbInitializeDisplay()
/* Check if framebuffer already initialized */
if(!FbpDisplayInfo.Initialized)
{
/* Set initial framebuffer state */
/* Print debug message */
XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n");
FbpDisplayInfo.Protocol = NONE;
FbpDisplayInfo.Initialized = FALSE;
/* 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 */
if(Status == STATUS_EFI_SUCCESS)
{
/* Check if there are any video modes available */
if(Gop->Mode->MaxMode == 0)
if(FbpDisplayInfo.Driver.Gop->Mode->MaxMode == 0)
{
/* No video modes available */
XtLdrProtocol->Debug.Print(L"ERROR: No GOP video mode available\n");
@ -127,11 +122,12 @@ FbInitializeDisplay()
}
/* 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)
{
/* 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)
{
@ -140,22 +136,19 @@ FbInitializeDisplay()
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.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 */
PixelBitMask = Gop->Mode->Info->PixelInformation;
/* Set framebuffer address and size */
FbpDisplayInfo.FrameBufferBase = Gop->Mode->FrameBufferBase;
FbpDisplayInfo.FrameBufferSize = Gop->Mode->FrameBufferSize;
/* Get pixel information */
FbpGetPixelInformation(&FbpDisplayInfo, &PixelBitMask);
/* Get current mode information */
Status = FbpGetModeInfo();
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get mode information */
XtLdrProtocol->Debug.Print(L"ERROR: Failed to get GOP mode information (Status Code: 0x%zX)\n");
return STATUS_EFI_UNSUPPORTED;
}
/* Found GOP */
XtLdrProtocol->Debug.Print(L"Found EFI-GOP compatible display adapter @ %P (%zu bytes)\n",
@ -167,13 +160,14 @@ FbInitializeDisplay()
else
{
/* 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 */
if(Status == STATUS_EFI_SUCCESS)
{
/* 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)
{
/* Unable to get current UGA mode */
@ -196,21 +190,18 @@ FbInitializeDisplay()
return STATUS_EFI_DEVICE_ERROR;
}
/* Set framebuffer information */
/* Store framebuffer protocol information */
FbpDisplayInfo.DefaultMode = 0;
FbpDisplayInfo.Protocol = UGA;
FbpDisplayInfo.PixelsPerScanLine = FbpDisplayInfo.Width;
FbpDisplayInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
/* Get pixel bit mask information */
PixelBitMask = (EFI_PIXEL_BITMASK){0, 0, 0, 0};
/* Get pixel information */
FbpGetPixelInformation(&FbpDisplayInfo, &PixelBitMask);
/* Set framebuffer size */
FbpDisplayInfo.FrameBufferSize = FbpDisplayInfo.Width *
FbpDisplayInfo.Height *
FbpDisplayInfo.BytesPerPixel + 1024;
/* Get mode information */
Status = FbpGetModeInfo();
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get mode information */
XtLdrProtocol->Debug.Print(L"ERROR: Failed to get UGA mode information (Status Code: 0x%zX)\n");
return STATUS_EFI_UNSUPPORTED;
}
/* Found UGA */
XtLdrProtocol->Debug.Print(L"Found EFI-UGA compatible display adapter @ %P (%zu bytes)\n",
@ -229,8 +220,8 @@ FbInitializeDisplay()
return STATUS_EFI_NOT_FOUND;
}
/* Calculate framebuffer pitch */
FbpDisplayInfo.Pitch = FbpDisplayInfo.PixelsPerScanLine * (FbpDisplayInfo.BitsPerPixel / 8);
XtLdrProtocol->Debug.Print(L"Current screen resolution is %ux%ux%u\n", FbpDisplayInfo.ModeInfo.Width,
FbpDisplayInfo.ModeInfo.Height, FbpDisplayInfo.ModeInfo.BitsPerPixel);
/* Set framebuffer initialization flag */
FbpDisplayInfo.Initialized = TRUE;
@ -240,6 +231,120 @@ FbInitializeDisplay()
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.
*
@ -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.
*
@ -408,41 +593,40 @@ FbpGetColorMask(IN UINT PixelBitMask,
*/
XTCDECL
VOID
FbpGetPixelInformation(IN OUT PXTBL_FRAMEBUFFER_INFORMATION FrameBufferInfo,
IN PEFI_PIXEL_BITMASK PixelsBitMask)
FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask)
{
UINT CompoundMask;
/* Check reported pixel format */
switch(FrameBufferInfo->PixelFormat)
switch(FbpDisplayInfo.ModeInfo.PixelFormat)
{
case PixelBlueGreenRedReserved8BitPerColor:
/* BGRR, 32 bits per pixel */
FrameBufferInfo->BitsPerPixel = 32;
FrameBufferInfo->PixelInformation.BlueMask = 0xFF;
FrameBufferInfo->PixelInformation.BlueShift = 0;
FrameBufferInfo->PixelInformation.GreenMask = 0xFF;
FrameBufferInfo->PixelInformation.GreenShift = 8;
FrameBufferInfo->PixelInformation.RedMask = 0xFF;
FrameBufferInfo->PixelInformation.RedShift = 16;
FrameBufferInfo->PixelInformation.ReservedMask = 0xFF;
FrameBufferInfo->PixelInformation.ReservedShift = 24;
FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 16;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;
break;
case PixelRedGreenBlueReserved8BitPerColor:
/* RGBR, 32 bits per pixel */
FrameBufferInfo->BitsPerPixel = 32;
FrameBufferInfo->PixelInformation.BlueMask = 0xFF;
FrameBufferInfo->PixelInformation.BlueShift = 16;
FrameBufferInfo->PixelInformation.GreenMask = 0xFF;
FrameBufferInfo->PixelInformation.GreenShift = 8;
FrameBufferInfo->PixelInformation.RedMask = 0xFF;
FrameBufferInfo->PixelInformation.RedShift = 0;
FrameBufferInfo->PixelInformation.ReservedMask = 0xFF;
FrameBufferInfo->PixelInformation.ReservedShift = 24;
FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 16;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;
FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0xFF;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;
break;
case PixelBitMask:
/* Assume 32 bits per pixel */
FrameBufferInfo->BitsPerPixel = 32;
FbpDisplayInfo.ModeInfo.BitsPerPixel = 32;
/* Calculate compound mask */
CompoundMask = PixelsBitMask->RedMask |
@ -453,36 +637,36 @@ FbpGetPixelInformation(IN OUT PXTBL_FRAMEBUFFER_INFORMATION FrameBufferInfo,
/* Recalculate bits per pixel */
while((CompoundMask & (1 << 31)) == 0)
{
FrameBufferInfo->BitsPerPixel--;
FbpDisplayInfo.ModeInfo.BitsPerPixel--;
CompoundMask <<= 1;
}
/* Set pixel information */
FbpGetColorMask(PixelsBitMask->RedMask, &FrameBufferInfo->PixelInformation.RedMask,
&FrameBufferInfo->PixelInformation.RedShift);
FbpGetColorMask(PixelsBitMask->GreenMask, &FrameBufferInfo->PixelInformation.GreenMask,
&FrameBufferInfo->PixelInformation.GreenShift);
FbpGetColorMask(PixelsBitMask->BlueMask, &FrameBufferInfo->PixelInformation.BlueMask,
&FrameBufferInfo->PixelInformation.BlueShift);
FbpGetColorMask(PixelsBitMask->ReservedMask, &FrameBufferInfo->PixelInformation.ReservedMask,
&FrameBufferInfo->PixelInformation.ReservedShift);
FbpGetColorMask(PixelsBitMask->RedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.RedMask,
&FbpDisplayInfo.ModeInfo.PixelInformation.RedShift);
FbpGetColorMask(PixelsBitMask->GreenMask, &FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask,
&FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift);
FbpGetColorMask(PixelsBitMask->BlueMask, &FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask,
&FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift);
FbpGetColorMask(PixelsBitMask->ReservedMask, &FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask,
&FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift);
break;
default:
/* Unknown pixel format */
FrameBufferInfo->BitsPerPixel = 0;
FrameBufferInfo->PixelInformation.BlueMask = 0x0;
FrameBufferInfo->PixelInformation.BlueShift = 0;
FrameBufferInfo->PixelInformation.GreenMask = 0x0;
FrameBufferInfo->PixelInformation.GreenShift = 0;
FrameBufferInfo->PixelInformation.RedMask = 0x0;
FrameBufferInfo->PixelInformation.RedShift = 0;
FrameBufferInfo->PixelInformation.ReservedMask = 0x0;
FrameBufferInfo->PixelInformation.ReservedShift = 0;
FbpDisplayInfo.ModeInfo.BitsPerPixel = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueMask = 0x0;
FbpDisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenMask = 0x0;
FbpDisplayInfo.ModeInfo.PixelInformation.GreenShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.RedMask = 0x0;
FbpDisplayInfo.ModeInfo.PixelInformation.RedShift = 0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedMask = 0x0;
FbpDisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0;
break;
}
/* 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;
}
/* Set initial framebuffer state */
FbpDisplayInfo.Protocol = NONE;
FbpDisplayInfo.Initialized = FALSE;
/* Set routines available via XTLDR framebuffer protocol */
FbpFrameBufferProtocol.GetDisplayDriver = FbGetDisplayDriver;
FbpFrameBufferProtocol.GetDisplayInformation = FbGetDisplayInformation;
FbpFrameBufferProtocol.Initialize = FbInitializeDisplay;
FbpFrameBufferProtocol.SetScreenResolution = FbSetScreenResolution;
/* Register XTOS boot protocol */
return XtLdrProtocol->Protocol.Install(&FbpFrameBufferProtocol, &Guid);

View File

@ -14,10 +14,23 @@
/* 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
EFI_STATUS
FbInitializeDisplay();
XTCDECL
EFI_STATUS
FbSetScreenResolution(IN UINT Width,
IN UINT Height);
XTCDECL
EFI_STATUS
FbpFindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address);
@ -28,10 +41,13 @@ FbpGetColorMask(IN UINT EfiMask,
OUT PUSHORT ColorMask,
OUT PUSHORT ColorShift);
XTCDECL
EFI_STATUS
FbpGetModeInfo();
XTCDECL
VOID
FbpGetPixelInformation(IN OUT PXTBL_FRAMEBUFFER_INFORMATION FrameBufferInfo,
IN PEFI_PIXEL_BITMASK PixelsBitMask);
FbpGetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask);
XTCDECL
EFI_STATUS

View File

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