]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/EmuGopDxe/GopScreen.c
BeagleBoardPkg/PrePi: base GCD memory space size on CPU's PA range
[mirror_edk2.git] / EmulatorPkg / EmuGopDxe / GopScreen.c
CommitLineData
79e4f2a5
RN
1/*++ @file\r
2\r
ce8c1d92 3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
79e4f2a5
RN
4Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13Module Name:\r
14\r
15 EmuGopScreen.c\r
16\r
17Abstract:\r
18\r
19 This file produces the graphics abstration of UGA. It is called by\r
20 EmuGopDriver.c file which deals with the EFI 1.1 driver model.\r
21 This file just does graphics.\r
22\r
23**/\r
24\r
25#include "Gop.h"\r
26\r
27\r
28EFI_EVENT mGopScreenExitBootServicesEvent;\r
29\r
30GOP_MODE_DATA mGopModeData[] = {\r
31 { 800, 600, 0, 0 },\r
32 { 640, 480, 0, 0 },\r
33 { 720, 400, 0, 0 },\r
34 {1024, 768, 0, 0 },\r
35 {1280, 1024, 0, 0 }\r
36 };\r
37\r
38\r
39/**\r
40 Returns information for an available graphics mode that the graphics device\r
41 and the set of active video output devices supports.\r
42\r
43 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
44 @param ModeNumber The mode number to return information on.\r
45 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.\r
46 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.\r
47\r
48 @retval EFI_SUCCESS Mode information returned.\r
49 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.\r
50 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.\r
51 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()\r
52 @retval EFI_INVALID_PARAMETER One of the input args was NULL.\r
53\r
54**/\r
55EFI_STATUS\r
56EFIAPI\r
57EmuGopQuerytMode (\r
58 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
59 IN UINT32 ModeNumber,\r
60 OUT UINTN *SizeOfInfo,\r
61 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
62 )\r
63{\r
64 GOP_PRIVATE_DATA *Private;\r
65\r
66 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
67\r
68 if (Info == NULL || SizeOfInfo == NULL || (UINTN) ModeNumber >= This->Mode->MaxMode) {\r
69 return EFI_INVALID_PARAMETER;\r
70 }\r
71\r
72 *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
73 if (*Info == NULL) {\r
74 return EFI_OUT_OF_RESOURCES;\r
75 }\r
76\r
77 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
78\r
79 (*Info)->Version = 0;\r
80 (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;\r
81 (*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution;\r
82 (*Info)->PixelFormat = PixelBltOnly;\r
83 (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
84\r
85 return EFI_SUCCESS;\r
86}\r
87\r
88\r
89\r
90/**\r
91 Set the video device into the specified mode and clears the visible portions of\r
92 the output display to black.\r
93\r
94 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
95 @param ModeNumber Abstraction that defines the current video mode.\r
96\r
97 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.\r
98 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
99 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.\r
100\r
101**/\r
102EFI_STATUS\r
103EFIAPI\r
104EmuGopSetMode (\r
105 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
106 IN UINT32 ModeNumber\r
107 )\r
108{\r
109 EFI_STATUS Status;\r
110 GOP_PRIVATE_DATA *Private;\r
111 GOP_MODE_DATA *ModeData;\r
112 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;\r
113\r
114 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
115\r
116 if (ModeNumber >= This->Mode->MaxMode) {\r
117 return EFI_UNSUPPORTED;\r
118 }\r
119\r
120 ModeData = &Private->ModeData[ModeNumber];\r
121 This->Mode->Mode = ModeNumber;\r
122 Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
123 Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
124 Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;\r
125\r
126 if (Private->HardwareNeedsStarting) {\r
127 Status = EmuGopStartWindow (\r
128 Private,\r
129 ModeData->HorizontalResolution,\r
130 ModeData->VerticalResolution,\r
131 ModeData->ColorDepth,\r
132 ModeData->RefreshRate\r
133 );\r
134 if (EFI_ERROR (Status)) {\r
135 return EFI_DEVICE_ERROR;\r
136 }\r
137\r
138 Private->HardwareNeedsStarting = FALSE;\r
139 }\r
140\r
141\r
142 Status = Private->EmuGraphicsWindow->Size(\r
143 Private->EmuGraphicsWindow,\r
144 ModeData->HorizontalResolution,\r
145 ModeData->VerticalResolution\r
146 );\r
147\r
148\r
ce8c1d92
RN
149 Fill.Red = 0;\r
150 Fill.Green = 0;\r
151 Fill.Blue = 0;\r
79e4f2a5
RN
152 This->Blt (\r
153 This,\r
154 &Fill,\r
155 EfiBltVideoFill,\r
156 0,\r
157 0,\r
158 0,\r
159 0,\r
160 ModeData->HorizontalResolution,\r
161 ModeData->VerticalResolution,\r
162 ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
163 );\r
164 return EFI_SUCCESS;\r
165}\r
166\r
167\r
168\r
169/**\r
170 Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.\r
171\r
172 @param This Protocol instance pointer.\r
173 @param BltBuffer Buffer containing data to blit into video buffer. This\r
174 buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
175 @param BltOperation Operation to perform on BlitBuffer and video memory\r
176 @param SourceX X coordinate of source for the BltBuffer.\r
177 @param SourceY Y coordinate of source for the BltBuffer.\r
178 @param DestinationX X coordinate of destination for the BltBuffer.\r
179 @param DestinationY Y coordinate of destination for the BltBuffer.\r
180 @param Width Width of rectangle in BltBuffer in pixels.\r
181 @param Height Hight of rectangle in BltBuffer in pixels.\r
182 @param Delta OPTIONAL\r
183\r
184 @retval EFI_SUCCESS The Blt operation completed.\r
185 @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
186 @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.\r
187\r
188**/\r
189EFI_STATUS\r
190EFIAPI\r
191EmuGopBlt (\r
192 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
193 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
194 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
195 IN UINTN SourceX,\r
196 IN UINTN SourceY,\r
197 IN UINTN DestinationX,\r
198 IN UINTN DestinationY,\r
199 IN UINTN Width,\r
200 IN UINTN Height,\r
201 IN UINTN Delta OPTIONAL\r
202 )\r
203{\r
204 GOP_PRIVATE_DATA *Private;\r
205 EFI_TPL OriginalTPL;\r
206 EFI_STATUS Status;\r
207 EMU_GRAPHICS_WINDOWS__BLT_ARGS GopBltArgs;\r
208\r
209 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
210\r
211 if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {\r
212 return EFI_INVALID_PARAMETER;\r
213 }\r
214\r
215 if (Width == 0 || Height == 0) {\r
216 return EFI_INVALID_PARAMETER;\r
217 }\r
218 //\r
219 // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
220 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r
221 // the number of bytes in each row can be computed.\r
222 //\r
223 if (Delta == 0) {\r
224 Delta = Width * sizeof (EFI_UGA_PIXEL);\r
225 }\r
226\r
227 //\r
228 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
229 // We would not want a timer based event (Cursor, ...) to come in while we are\r
230 // doing this operation.\r
231 //\r
232 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
233\r
234 //\r
235 // Pack UGA Draw protocol parameters to EMU_GRAPHICS_WINDOWS__BLT_ARGS structure to adapt to\r
236 // GopBlt() API of Unix UGA IO protocol.\r
237 //\r
238 GopBltArgs.DestinationX = DestinationX;\r
239 GopBltArgs.DestinationY = DestinationY;\r
240 GopBltArgs.Height = Height;\r
241 GopBltArgs.Width = Width;\r
242 GopBltArgs.SourceX = SourceX;\r
243 GopBltArgs.SourceY = SourceY;\r
244 GopBltArgs.Delta = Delta;\r
245 Status = Private->EmuGraphicsWindow->Blt (\r
246 Private->EmuGraphicsWindow,\r
247 (EFI_UGA_PIXEL *)BltBuffer,\r
248 (EFI_UGA_BLT_OPERATION)BltOperation,\r
249 &GopBltArgs\r
250 );\r
251\r
252 gBS->RestoreTPL (OriginalTPL);\r
253\r
254 return Status;\r
255}\r
256\r
257\r
258//\r
259// Construction and Destruction functions\r
260//\r
261\r
262EFI_STATUS\r
263EmuGopSupported (\r
264 IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk\r
265 )\r
266{\r
267 //\r
268 // Check to see if the IO abstraction represents a device type we support.\r
269 //\r
270 // This would be replaced a check of PCI subsystem ID, etc.\r
271 //\r
272 if (!CompareGuid (EmuIoThunk->Protocol, &gEmuGraphicsWindowProtocolGuid)) {\r
273 return EFI_UNSUPPORTED;\r
274 }\r
275\r
276 return EFI_SUCCESS;\r
277}\r
278\r
279\r
280EFI_STATUS\r
281EmuGopStartWindow (\r
282 IN GOP_PRIVATE_DATA *Private,\r
283 IN UINT32 HorizontalResolution,\r
284 IN UINT32 VerticalResolution,\r
285 IN UINT32 ColorDepth,\r
286 IN UINT32 RefreshRate\r
287 )\r
288{\r
289 EFI_STATUS Status;\r
290\r
291 //\r
292 // Register to be notified on exit boot services so we can destroy the window.\r
293 //\r
294 Status = gBS->CreateEvent (\r
295 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
296 TPL_CALLBACK,\r
297 ShutdownGopEvent,\r
298 Private,\r
299 &mGopScreenExitBootServicesEvent\r
300 );\r
301\r
302 Status = Private->EmuIoThunk->Open (Private->EmuIoThunk);\r
303 if (!EFI_ERROR (Status)) {\r
304 Private->EmuGraphicsWindow = Private->EmuIoThunk->Interface;\r
305\r
306 // Register callback to support RegisterKeyNotify()\r
307 Status = Private->EmuGraphicsWindow->RegisterKeyNotify (\r
308 Private->EmuGraphicsWindow,\r
309 GopPrivateMakeCallbackFunction,\r
310 GopPrivateBreakCallbackFunction,\r
311 Private\r
312 );\r
313 ASSERT_EFI_ERROR (Status);\r
314 }\r
315 return Status;\r
316}\r
317\r
318EFI_STATUS\r
319EmuGopConstructor (\r
320 GOP_PRIVATE_DATA *Private\r
321 )\r
322{\r
323 Private->ModeData = mGopModeData;\r
324\r
325 Private->GraphicsOutput.QueryMode = EmuGopQuerytMode;\r
326 Private->GraphicsOutput.SetMode = EmuGopSetMode;\r
327 Private->GraphicsOutput.Blt = EmuGopBlt;\r
328\r
329 //\r
330 // Allocate buffer for Graphics Output Protocol mode information\r
331 //\r
332 Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));\r
333 if (Private->GraphicsOutput.Mode == NULL) {\r
334 return EFI_OUT_OF_RESOURCES;\r
335 }\r
336 Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
337 if (Private->GraphicsOutput.Mode->Info == NULL) {\r
338 return EFI_OUT_OF_RESOURCES;\r
339 }\r
340\r
341 Private->GraphicsOutput.Mode->MaxMode = sizeof(mGopModeData) / sizeof(GOP_MODE_DATA);\r
342 //\r
343 // Till now, we have no idea about the window size.\r
344 //\r
345 Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
346 Private->GraphicsOutput.Mode->Info->Version = 0;\r
347 Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;\r
348 Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
349 Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
350 Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
351 Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
352 Private->GraphicsOutput.Mode->FrameBufferSize = 0;\r
353\r
354 Private->HardwareNeedsStarting = TRUE;\r
355 Private->EmuGraphicsWindow = NULL;\r
356\r
357 EmuGopInitializeSimpleTextInForWindow (Private);\r
358\r
359 EmuGopInitializeSimplePointerForWindow (Private);\r
360\r
361 return EFI_SUCCESS;\r
362}\r
363\r
364\r
365\r
366EFI_STATUS\r
367EmuGopDestructor (\r
368 GOP_PRIVATE_DATA *Private\r
369 )\r
370{\r
371 if (!Private->HardwareNeedsStarting) {\r
372 Private->EmuIoThunk->Close (Private->EmuIoThunk);\r
373 Private->EmuGraphicsWindow = NULL;\r
374 }\r
375\r
376 //\r
377 // Free graphics output protocol occupied resource\r
378 //\r
379 if (Private->GraphicsOutput.Mode != NULL) {\r
380 if (Private->GraphicsOutput.Mode->Info != NULL) {\r
381 FreePool (Private->GraphicsOutput.Mode->Info);\r
382 }\r
383 FreePool (Private->GraphicsOutput.Mode);\r
384 }\r
385\r
386 return EFI_SUCCESS;\r
387}\r
388\r
389\r
390VOID\r
391EFIAPI\r
392ShutdownGopEvent (\r
393 IN EFI_EVENT Event,\r
394 IN VOID *Context\r
395 )\r
396/*++\r
397\r
398Routine Description:\r
399\r
400 This is the UGA screen's callback notification function for exit-boot-services.\r
401 All we do here is call EmuGopDestructor().\r
402\r
403Arguments:\r
404\r
405 Event - not used\r
406 Context - pointer to the Private structure.\r
407\r
408Returns:\r
409\r
410 None.\r
411\r
412**/\r
413{\r
414 EmuGopDestructor (Context);\r
415}\r
416\r