TianoCore EDK2 master
Loading...
Searching...
No Matches
LcdGraphicsOutputDxe.c
Go to the documentation of this file.
1
9#include <PiDxe.h>
15
16#include <Guid/GlobalVariable.h>
17
19
20//
21// Global variables
22//
23
24BOOLEAN mDisplayInitialized = FALSE;
25
26LCD_INSTANCE mLcdTemplate = {
27 LCD_INSTANCE_SIGNATURE,
28 NULL, // Handle
29 { // ModeInfo
30 0, // Version
31 0, // HorizontalResolution
32 0, // VerticalResolution
33 PixelBltOnly, // PixelFormat
34 { 0 }, // PixelInformation
35 0, // PixelsPerScanLine
36 },
37 {
38 0, // MaxMode;
39 0, // Mode;
40 NULL, // Info;
41 0, // SizeOfInfo;
42 0, // FrameBufferBase;
43 0 // FrameBufferSize;
44 },
45 { // Gop
46 LcdGraphicsQueryMode, // QueryMode
47 LcdGraphicsSetMode, // SetMode
48 LcdGraphicsBlt, // Blt
49 NULL // *Mode
50 },
51 { // DevicePath
52 {
53 {
55 {
56 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
57 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
58 },
59 },
60 // Hardware Device Path for Lcd
61 EFI_CALLER_ID_GUID // Use the driver's GUID
62 },
63
64 {
65 END_DEVICE_PATH_TYPE,
66 END_ENTIRE_DEVICE_PATH_SUBTYPE,
67 {
69 0
70 }
71 }
72 },
73 (EFI_EVENT)NULL // ExitBootServicesEvent
74};
75
77LcdInstanceContructor (
78 OUT LCD_INSTANCE **NewInstance
79 )
80{
81 LCD_INSTANCE *Instance;
82
83 Instance = AllocateCopyPool (sizeof (LCD_INSTANCE), &mLcdTemplate);
84 if (Instance == NULL) {
85 return EFI_OUT_OF_RESOURCES;
86 }
87
88 Instance->Gop.Mode = &Instance->Mode;
89 Instance->Gop.Mode->MaxMode = LcdPlatformGetMaxMode ();
90 Instance->Mode.Info = &Instance->ModeInfo;
91
92 *NewInstance = Instance;
93 return EFI_SUCCESS;
94}
95
96//
97// Function Definitions
98//
99
101InitializeDisplay (
102 IN LCD_INSTANCE *Instance
103 )
104{
105 EFI_STATUS Status;
106 EFI_PHYSICAL_ADDRESS VramBaseAddress;
107 UINTN VramSize;
108
109 Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);
110 if (EFI_ERROR (Status)) {
111 return Status;
112 }
113
114 // Setup the LCD
115 Status = LcdInitialize (VramBaseAddress);
116 if (EFI_ERROR (Status)) {
117 goto EXIT_ERROR_LCD_SHUTDOWN;
118 }
119
120 Status = LcdPlatformInitializeDisplay (Instance->Handle);
121 if (EFI_ERROR (Status)) {
122 goto EXIT_ERROR_LCD_SHUTDOWN;
123 }
124
125 // Setup all the relevant mode information
126 Instance->Gop.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
127 Instance->Gop.Mode->FrameBufferBase = VramBaseAddress;
128
129 // Set the flag before changing the mode, to avoid infinite loops
130 mDisplayInitialized = TRUE;
131
132 // All is ok, so don't deal with any errors
133 goto EXIT;
134
135EXIT_ERROR_LCD_SHUTDOWN:
136 DEBUG ((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status));
137
138 LcdShutdown ();
139
140EXIT:
141 return Status;
142}
143
145EFIAPI
146LcdGraphicsOutputDxeInitialize (
147 IN EFI_HANDLE ImageHandle,
148 IN EFI_SYSTEM_TABLE *SystemTable
149 )
150{
151 EFI_STATUS Status;
152 LCD_INSTANCE *Instance;
153
154 Status = LcdIdentify ();
155 if (EFI_ERROR (Status)) {
156 goto EXIT;
157 }
158
159 Status = LcdInstanceContructor (&Instance);
160 if (EFI_ERROR (Status)) {
161 goto EXIT;
162 }
163
164 // Install the Graphics Output Protocol and the Device Path
165 Status = gBS->InstallMultipleProtocolInterfaces (
166 &Instance->Handle,
167 &gEfiGraphicsOutputProtocolGuid,
168 &Instance->Gop,
169 &gEfiDevicePathProtocolGuid,
170 &Instance->DevicePath,
171 NULL
172 );
173
174 if (EFI_ERROR (Status)) {
175 DEBUG ((DEBUG_ERROR, "LcdGraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));
176 goto EXIT;
177 }
178
179 // Register for an ExitBootServicesEvent
180 // When ExitBootServices starts, this function will make sure that the
181 // graphics driver shuts down properly, i.e. it will free up all
182 // allocated memory and perform any necessary hardware re-configuration.
183 Status = gBS->CreateEvent (
184 EVT_SIGNAL_EXIT_BOOT_SERVICES,
185 TPL_NOTIFY,
187 NULL,
188 &Instance->ExitBootServicesEvent
189 );
190
191 if (EFI_ERROR (Status)) {
192 DEBUG ((DEBUG_ERROR, "LcdGraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
193 goto EXIT_ERROR_UNINSTALL_PROTOCOL;
194 }
195
196 // To get here, everything must be fine, so just exit
197 goto EXIT;
198
199EXIT_ERROR_UNINSTALL_PROTOCOL:
200 // The following function could return an error message,
201 // however, to get here something must have gone wrong already,
202 // so preserve the original error, i.e. don't change
203 // the Status variable, even it fails to uninstall the protocol.
204 gBS->UninstallMultipleProtocolInterfaces (
205 Instance->Handle,
206 &gEfiGraphicsOutputProtocolGuid,
207 &Instance->Gop, // Uninstall Graphics Output protocol
208 &gEfiDevicePathProtocolGuid,
209 &Instance->DevicePath, // Uninstall device path
210 NULL
211 );
212
213EXIT:
214 return Status;
215}
216
222VOID
224 IN EFI_EVENT Event,
225 IN VOID *Context
226 )
227{
228 // By default, this PCD is FALSE. But if a platform starts a predefined OS
229 // that does not use a framebuffer then we might want to disable the display
230 // controller to avoid to display corrupted information on the screen.
231 if (FeaturePcdGet (PcdGopDisableOnExitBootServices)) {
232 // Turn-off the Display controller
233 LcdShutdown ();
234 }
235}
236
241EFIAPI
244 IN UINT32 ModeNumber,
245 OUT UINTN *SizeOfInfo,
247 )
248{
249 EFI_STATUS Status;
250 LCD_INSTANCE *Instance;
251
252 Instance = LCD_INSTANCE_FROM_GOP_THIS (This);
253
254 // Setup the hardware if not already done
255 if (!mDisplayInitialized) {
256 Status = InitializeDisplay (Instance);
257 if (EFI_ERROR (Status)) {
258 goto EXIT;
259 }
260 }
261
262 // Error checking
263 if ((This == NULL) ||
264 (Info == NULL) ||
265 (SizeOfInfo == NULL) ||
266 (ModeNumber >= This->Mode->MaxMode))
267 {
268 DEBUG ((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber));
269 Status = EFI_INVALID_PARAMETER;
270 goto EXIT;
271 }
272
274 if (*Info == NULL) {
275 Status = EFI_OUT_OF_RESOURCES;
276 goto EXIT;
277 }
278
279 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
280
281 Status = LcdPlatformQueryMode (ModeNumber, *Info);
282 if (EFI_ERROR (Status)) {
283 FreePool (*Info);
284 }
285
286EXIT:
287 return Status;
288}
289
294EFIAPI
297 IN UINT32 ModeNumber
298 )
299{
300 EFI_STATUS Status;
302 LCD_INSTANCE *Instance;
303 LCD_BPP Bpp;
304
305 Instance = LCD_INSTANCE_FROM_GOP_THIS (This);
306
307 // Setup the hardware if not already done
308 if (!mDisplayInitialized) {
309 Status = InitializeDisplay (Instance);
310 if (EFI_ERROR (Status)) {
311 goto EXIT;
312 }
313 }
314
315 // Check if this mode is supported
316 if (ModeNumber >= This->Mode->MaxMode) {
317 DEBUG ((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber));
318 Status = EFI_UNSUPPORTED;
319 goto EXIT;
320 }
321
322 // Set the oscillator frequency to support the new mode
323 Status = LcdPlatformSetMode (ModeNumber);
324 if (EFI_ERROR (Status)) {
325 Status = EFI_DEVICE_ERROR;
326 goto EXIT;
327 }
328
329 // Update the UEFI mode information
330 This->Mode->Mode = ModeNumber;
331 LcdPlatformQueryMode (ModeNumber, &Instance->ModeInfo);
332 Status = LcdPlatformGetBpp (ModeNumber, &Bpp);
333 if (EFI_ERROR (Status)) {
334 DEBUG ((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Couldn't get bytes per pixel, status: %r\n", Status));
335 goto EXIT;
336 }
337
338 This->Mode->FrameBufferSize = Instance->ModeInfo.VerticalResolution
339 * Instance->ModeInfo.PixelsPerScanLine
340 * GetBytesPerPixel (Bpp);
341
342 // Set the hardware to the new mode
343 Status = LcdSetMode (ModeNumber);
344 if (EFI_ERROR (Status)) {
345 Status = EFI_DEVICE_ERROR;
346 goto EXIT;
347 }
348
349 // The UEFI spec requires that we now clear the visible portions of the
350 // output display to black.
351
352 // Set the fill colour to black
353 SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
354
355 // Fill the entire visible area with the same colour.
356 Status = This->Blt (
357 This,
358 &FillColour,
360 0,
361 0,
362 0,
363 0,
364 This->Mode->Info->HorizontalResolution,
365 This->Mode->Info->VerticalResolution,
366 0
367 );
368
369EXIT:
370 return Status;
371}
372
373UINTN
374GetBytesPerPixel (
375 IN LCD_BPP Bpp
376 )
377{
378 switch (Bpp) {
379 case LcdBitsPerPixel_24:
380 return 4;
381
382 case LcdBitsPerPixel_16_565:
383 case LcdBitsPerPixel_16_555:
384 case LcdBitsPerPixel_12_444:
385 return 2;
386
387 case LcdBitsPerPixel_8:
388 case LcdBitsPerPixel_4:
389 case LcdBitsPerPixel_2:
390 case LcdBitsPerPixel_1:
391 return 1;
392
393 default:
394 return 0;
395 }
396}
UINT64 UINTN
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define HW_VENDOR_DP
Definition: DevicePath.h:133
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI LcdGraphicsSetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber)
VOID LcdGraphicsExitBootServicesEvent(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI LcdGraphicsQueryMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info)
EFI_STATUS LcdSetMode(IN UINT32 ModeNumber)
Definition: HdLcd.c:62
EFI_STATUS LcdInitialize(EFI_PHYSICAL_ADDRESS FrameBaseAddress)
Definition: LcdHwNullLib.c:38
VOID LcdShutdown(VOID)
Definition: ArmMaliDp.c:415
EFI_STATUS LcdIdentify(VOID)
Definition: ArmMaliDp.c:234
UINT32 LcdPlatformGetMaxMode(VOID)
EFI_STATUS LcdPlatformQueryMode(IN UINT32 ModeNumber, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info)
EFI_STATUS LcdPlatformGetBpp(IN UINT32 ModeNumber, OUT LCD_BPP *Bpp)
LCD_BPP
EFI_STATUS LcdPlatformInitializeDisplay(IN EFI_HANDLE Handle)
EFI_STATUS LcdPlatformGetVram(OUT EFI_PHYSICAL_ADDRESS *VramBaseAddress, OUT UINTN *VramSize)
EFI_STATUS LcdPlatformSetMode(IN UINT32 ModeNumber)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
@ EfiBltVideoFill
@ PixelBltOnly
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * Mode
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * Info