2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/io/display/efi/gop.c
5 * PURPOSE: Boot Library EFI GOP Routines
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 /* FUNCTIONS *****************************************************************/
18 ConsoleEfiGopGetGraphicalFormat (
19 _In_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*ModeInfo
,
20 _Out_ PULONG PixelDepth
23 /* Convert the format to depth */
24 if (ModeInfo
->PixelFormat
== PixelBlueGreenRedReserved8BitPerColor
)
27 return STATUS_SUCCESS
;
29 if (ModeInfo
->PixelFormat
== PixelBitMask
)
32 return STATUS_SUCCESS
;
34 return STATUS_UNSUCCESSFUL
;
38 ConsoleEfiGopIsPixelFormatSupported (
39 _In_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Mode
43 EFI_PIXEL_BITMASK PixelMask
;
47 /* Check if it's simple BGR8 */
48 if (Mode
->PixelFormat
== PixelBlueGreenRedReserved8BitPerColor
)
54 /* Otherwise, we can check if it's a masked format */
55 if (Mode
->PixelFormat
== PixelBitMask
)
57 /* Check if the masked format is BGR8 */
58 PixelMask
.BlueMask
= 0xFF;
59 PixelMask
.GreenMask
= 0xFF00;
60 PixelMask
.RedMask
= 0xFF0000;
61 PixelMask
.ReservedMask
= 0;
62 if (RtlEqualMemory(&Mode
->PixelInformation
,
71 /* Return if the format was supported */
77 ConsoleEfiGopFindModeFromAllowed (
78 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopProtocol
,
79 _In_ PBL_DISPLAY_MODE SupportedModes
,
80 _In_ ULONG MaximumIndex
,
81 _Out_ PULONG SupportedMode
84 return STATUS_NOT_IMPLEMENTED
;
89 _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
93 UINTN CurrentMode
, Dummy
;
94 ULONG Mode
, PixelDepth
;
95 UINTN FrameBufferSize
;
96 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInformation
;
97 EFI_GRAPHICS_OUTPUT_PROTOCOL
* Protocol
;
99 PHYSICAL_ADDRESS FrameBufferPhysical
;
101 /* Capture the current mode and protocol */
102 Mode
= GraphicsConsole
->Mode
;
103 Protocol
= GraphicsConsole
->Protocol
;
105 /* Get the current mode and its information */
106 Status
= EfiGopGetCurrentMode(Protocol
, &CurrentMode
, &ModeInformation
);
107 if (!NT_SUCCESS(Status
))
112 /* Check if we're not in the mode we should be */
113 if (CurrentMode
!= Mode
)
116 Status
= EfiGopSetMode(Protocol
, Mode
);
117 if (!NT_SUCCESS(Status
))
122 /* Reset the OEM bitmap and get the new more information */
123 BlDisplayInvalidateOemBitmap();
124 EfiGopGetCurrentMode(Protocol
, &Dummy
, &ModeInformation
);
127 /* Get the pixel depth for this mode */
128 Status
= ConsoleEfiGopGetGraphicalFormat(&ModeInformation
, &PixelDepth
);
129 if (NT_SUCCESS(Status
))
131 /* Get the framebuffer for this mode */
132 EfiGopGetFrameBuffer(Protocol
, &FrameBufferPhysical
, &FrameBufferSize
);
134 /* Map the framebuffer, try as writeback first */
136 Status
= BlMmMapPhysicalAddressEx(&FrameBuffer
,
139 FrameBufferPhysical
);
140 if (!NT_SUCCESS(Status
))
142 /* That didn't work, so try uncached next */
143 Status
= BlMmMapPhysicalAddressEx(&FrameBuffer
,
146 FrameBufferPhysical
);
150 /* Check if getting all the required information worked out */
151 if (NT_SUCCESS(Status
))
153 /* Capture the resolution, depth, and framebuffer information */
154 GraphicsConsole
->DisplayMode
.HRes
= ModeInformation
.HorizontalResolution
;
155 GraphicsConsole
->DisplayMode
.VRes
= ModeInformation
.VerticalResolution
;
156 GraphicsConsole
->DisplayMode
.HRes2
= ModeInformation
.PixelsPerScanLine
;
157 GraphicsConsole
->PixelDepth
= PixelDepth
;
158 GraphicsConsole
->FrameBuffer
= FrameBuffer
;
159 GraphicsConsole
->FrameBufferSize
= FrameBufferSize
;
160 GraphicsConsole
->PixelsPerScanLine
= ModeInformation
.PixelsPerScanLine
;
163 Status
= STATUS_SUCCESS
;
165 else if (CurrentMode
!= GraphicsConsole
->Mode
)
167 /* We failed somewhere, reset the mode and the OEM bitmap back */
168 EfiGopSetMode(Protocol
, CurrentMode
);
169 BlDisplayInvalidateOemBitmap();
172 /* Return back to caller */
178 _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
183 /* Did we switch modes when we turned on the console? */
184 OldMode
= GraphicsConsole
->OldMode
;
185 if (GraphicsConsole
->Mode
!= OldMode
)
187 /* Restore the old mode and reset the OEM bitmap in ACPI */
188 EfiGopSetMode(GraphicsConsole
->Protocol
, OldMode
);
189 BlDisplayInvalidateOemBitmap();
192 /* Close the GOP protocol */
193 EfiCloseProtocol(GraphicsConsole
->Handle
,
194 &EfiGraphicsOutputProtocol
);
199 _In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
203 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopProtocol
;
204 ULONG Mode
, PixelDepth
;
206 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInformation
;
207 BOOLEAN CurrentModeOk
;
209 /* Open a handle to GOP */
210 Status
= EfiOpenProtocol(GraphicsConsole
->Handle
,
211 &EfiGraphicsOutputProtocol
,
212 (PVOID
*)&GopProtocol
);
213 if (!NT_SUCCESS(Status
))
215 EfiPrintf(L
"GOP OPEN failed: %lx\r\n", Status
);
216 return STATUS_NOT_SUPPORTED
;
219 /* Get the current mode */
220 Status
= EfiGopGetCurrentMode(GopProtocol
, &CurrentMode
, &ModeInformation
);
221 if (!NT_SUCCESS(Status
))
223 EfiPrintf(L
"GOP mode failed: %lx\r\n", Status
);
229 /* Check if any custom BCD options were provided */
230 if (ConsoleGraphicalResolutionListFlags
&
231 (BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG
|
232 BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG
))
234 /* We'll have to find a mode */
235 CurrentModeOk
= FALSE
;
239 /* Then we should be in the default mode, check if the pixel format is OK */
240 CurrentModeOk
= ConsoleEfiGopIsPixelFormatSupported(&ModeInformation
);
243 /* Is the mode/format OK? */
246 /* Nope -- we'll have to go find one */
247 Status
= ConsoleEfiGopFindModeFromAllowed(GopProtocol
,
248 ConsoleGraphicalResolutionList
,
249 ConsoleGraphicalResolutionListSize
,
251 if (!NT_SUCCESS(Status
))
257 /* Store mode information */
258 GraphicsConsole
->Protocol
= GopProtocol
;
259 GraphicsConsole
->Mode
= Mode
;
260 GraphicsConsole
->OldMode
= CurrentMode
;
262 /* Get format information */
263 Status
= ConsoleEfiGopGetGraphicalFormat(&ModeInformation
, &PixelDepth
);
264 if (NT_SUCCESS(Status
))
267 GraphicsConsole
->OldDisplayMode
.HRes
= ModeInformation
.HorizontalResolution
;
268 GraphicsConsole
->OldDisplayMode
.VRes
= ModeInformation
.VerticalResolution
;
269 GraphicsConsole
->OldDisplayMode
.HRes2
= ModeInformation
.PixelsPerScanLine
;
270 GraphicsConsole
->PixelDepth
= PixelDepth
;
271 return STATUS_SUCCESS
;
275 /* We failed, close the protocol and return the failure code */
276 EfiPrintf(L
"Get format failed: %lx\r\n", Status
);
277 EfiCloseProtocol(GraphicsConsole
->Handle
, &EfiGraphicsOutputProtocol
);