]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Bhyve/BhyveRfbDxe/GopScreen.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / Bhyve / BhyveRfbDxe / GopScreen.c
CommitLineData
656419f9
RC
1/*++ @file\r
2\r
3Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
4Copyright (c) 2015, Nahanni Systems, Inc.\r
5Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
6Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.\r
7\r
8SPDX-License-Identifier: BSD-2-Clause-Patent\r
9\r
10Module Name:\r
11\r
12 EmuGopScreen.c\r
13\r
14Abstract:\r
15\r
16 This file produces the graphics abstration of UGA. It is called by\r
17 EmuGopDriver.c file which deals with the EFI 1.1 driver model.\r
18 This file just does graphics.\r
19\r
20**/\r
21\r
22#include "Gop.h"\r
23#include <Library/FrameBufferBltLib.h>\r
24\r
ac0a286f 25EFI_EVENT mGopScreenExitBootServicesEvent;\r
656419f9 26\r
ac0a286f
MK
27GOP_MODE_DATA mGopModeData[] = {\r
28 { 0, 0, 32, 0 }, // Filled in with user-spec'd resolution\r
29 { 1024, 768, 32, 0 },\r
30 { 800, 600, 32, 0 },\r
31 { 640, 480, 32, 0 }\r
32};\r
656419f9
RC
33\r
34STATIC\r
35VOID\r
36BhyveGopCompleteModeInfo (\r
ac0a286f 37 IN GOP_MODE_DATA *ModeData,\r
656419f9
RC
38 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info\r
39 )\r
40{\r
41 Info->Version = 0;\r
42 if (ModeData->ColorDepth == 8) {\r
ac0a286f
MK
43 Info->PixelFormat = PixelBitMask;\r
44 Info->PixelInformation.RedMask = PIXEL_RED_MASK;\r
45 Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;\r
46 Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;\r
656419f9
RC
47 Info->PixelInformation.ReservedMask = 0;\r
48 } else if (ModeData->ColorDepth == 24) {\r
ac0a286f
MK
49 Info->PixelFormat = PixelBitMask;\r
50 Info->PixelInformation.RedMask = PIXEL24_RED_MASK;\r
51 Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;\r
52 Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;\r
656419f9
RC
53 Info->PixelInformation.ReservedMask = 0;\r
54 } else if (ModeData->ColorDepth == 32) {\r
ac0a286f
MK
55 DEBUG ((\r
56 DEBUG_INFO,\r
57 "%dx%d PixelBlueGreenRedReserved8BitPerColor\n",\r
58 ModeData->HorizontalResolution,\r
59 ModeData->VerticalResolution\r
60 ));\r
656419f9
RC
61 Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
62 }\r
ac0a286f 63\r
656419f9
RC
64 Info->PixelsPerScanLine = Info->HorizontalResolution;\r
65}\r
66\r
656419f9
RC
67/**\r
68 Returns information for an available graphics mode that the graphics device\r
69 and the set of active video output devices supports.\r
70\r
71 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
72 @param ModeNumber The mode number to return information on.\r
73 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.\r
74 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.\r
75\r
76 @retval EFI_SUCCESS Mode information returned.\r
77 @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.\r
78 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.\r
79 @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()\r
80 @retval EFI_INVALID_PARAMETER One of the input args was NULL.\r
81\r
82**/\r
83EFI_STATUS\r
84EFIAPI\r
85EmuGopQuerytMode (\r
86 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
87 IN UINT32 ModeNumber,\r
88 OUT UINTN *SizeOfInfo,\r
89 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
90 )\r
91{\r
92 GOP_PRIVATE_DATA *Private;\r
93 GOP_MODE_DATA *ModeData;\r
94\r
95 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
96\r
ac0a286f 97 if ((Info == NULL) || (SizeOfInfo == NULL) || ((UINTN)ModeNumber >= This->Mode->MaxMode)) {\r
656419f9
RC
98 return EFI_INVALID_PARAMETER;\r
99 }\r
100\r
101 *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
102 if (*Info == NULL) {\r
103 return EFI_OUT_OF_RESOURCES;\r
104 }\r
105\r
106 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
107\r
ac0a286f
MK
108 ModeData = &Private->ModeData[ModeNumber];\r
109 (*Info)->Version = 0;\r
656419f9
RC
110 (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
111 (*Info)->VerticalResolution = ModeData->VerticalResolution;\r
ac0a286f
MK
112 (*Info)->PixelFormat = PixelBitMask;\r
113 (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
114 BhyveGopCompleteModeInfo (ModeData, *Info);\r
656419f9
RC
115 return EFI_SUCCESS;\r
116}\r
117\r
656419f9
RC
118/**\r
119 Set the video device into the specified mode and clears the visible portions of\r
120 the output display to black.\r
121\r
122 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
123 @param ModeNumber Abstraction that defines the current video mode.\r
124\r
125 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.\r
126 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
127 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.\r
128\r
129**/\r
130\r
ac0a286f 131FRAME_BUFFER_CONFIGURE *fbconf;\r
656419f9
RC
132\r
133EFI_STATUS\r
134EFIAPI\r
135EmuGopSetMode (\r
136 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
137 IN UINT32 ModeNumber\r
138 )\r
139{\r
ac0a286f
MK
140 GOP_PRIVATE_DATA *Private;\r
141 GOP_MODE_DATA *ModeData;\r
142 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;\r
656419f9
RC
143 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
144\r
ac0a286f
MK
145 UINTN confsize = 0;\r
146\r
656419f9
RC
147 fbconf = NULL;\r
148\r
149 Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
150\r
151 if (ModeNumber >= This->Mode->MaxMode) {\r
152 // Tell bhyve that we are switching out of vesa\r
ac0a286f 153 BhyveSetGraphicsMode (Private, 0, 0, 0);\r
656419f9
RC
154 return EFI_UNSUPPORTED;\r
155 }\r
156\r
157 DEBUG ((DEBUG_INFO, "BHYVE GopSetMode %d\n", ModeNumber));\r
158\r
ac0a286f
MK
159 ModeData = &Private->ModeData[ModeNumber];\r
160 This->Mode->Mode = ModeNumber;\r
656419f9 161 Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
ac0a286f
MK
162 Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
163 Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;\r
656419f9
RC
164\r
165 Info = This->Mode->Info;\r
ac0a286f 166 BhyveGopCompleteModeInfo (ModeData, Info);\r
656419f9
RC
167\r
168 This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
ac0a286f
MK
169 This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
170 This->Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
171 This->Mode->FrameBufferBase = Private->GraphicsOutput.Mode->FrameBufferBase;\r
656419f9
RC
172\r
173 /*\r
174 This->Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution\r
175 * ((ModeData->ColorDepth + 7) / 8);\r
176 */\r
177 This->Mode->FrameBufferSize = Private->FbSize;\r
178 DEBUG ((DEBUG_INFO, "BHYVE GOP FrameBufferBase: 0x%x, FrameBufferSize: 0x%x\n", This->Mode->FrameBufferBase, This->Mode->FrameBufferSize));\r
179\r
ac0a286f
MK
180 BhyveSetGraphicsMode (Private, (UINT16)ModeData->HorizontalResolution, (UINT16)ModeData->VerticalResolution, (UINT16)ModeData->ColorDepth);\r
181\r
182 RETURN_STATUS ret = FrameBufferBltConfigure (\r
183 (VOID *)(UINTN)This->Mode->FrameBufferBase,\r
184 This->Mode->Info,\r
185 fbconf,\r
186 &confsize\r
187 );\r
188\r
189 if ((ret == EFI_BUFFER_TOO_SMALL) || (ret == EFI_INVALID_PARAMETER)) {\r
190 fbconf = AllocatePool (confsize);\r
191 ret = FrameBufferBltConfigure (\r
192 (VOID *)(UINTN)This->Mode->FrameBufferBase,\r
193 This->Mode->Info,\r
194 fbconf,\r
195 &confsize\r
196 );\r
197 ASSERT (ret == EFI_SUCCESS);\r
656419f9
RC
198 }\r
199\r
200 Fill.Red = 0;\r
201 Fill.Green = 0;\r
202 Fill.Blue = 0;\r
203 This->Blt (\r
204 This,\r
205 &Fill,\r
206 EfiBltVideoFill,\r
207 0,\r
208 0,\r
209 0,\r
210 0,\r
211 ModeData->HorizontalResolution,\r
212 ModeData->VerticalResolution,\r
213 ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
214 );\r
215 return EFI_SUCCESS;\r
216}\r
217\r
656419f9
RC
218/**\r
219 Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.\r
220\r
221 @param This Protocol instance pointer.\r
222 @param BltBuffer Buffer containing data to blit into video buffer. This\r
223 buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
224 @param BltOperation Operation to perform on BlitBuffer and video memory\r
225 @param SourceX X coordinate of source for the BltBuffer.\r
226 @param SourceY Y coordinate of source for the BltBuffer.\r
227 @param DestinationX X coordinate of destination for the BltBuffer.\r
228 @param DestinationY Y coordinate of destination for the BltBuffer.\r
229 @param Width Width of rectangle in BltBuffer in pixels.\r
230 @param Height Hight of rectangle in BltBuffer in pixels.\r
231 @param Delta OPTIONAL\r
232\r
233 @retval EFI_SUCCESS The Blt operation completed.\r
234 @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
60835c96 235 @retval EFI_DEVICE_ERROR A hardware error occurred writting to the video buffer.\r
656419f9
RC
236\r
237**/\r
238EFI_STATUS\r
239EFIAPI\r
240EmuGopBlt (\r
ac0a286f
MK
241 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
242 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
243 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
244 IN UINTN SourceX,\r
245 IN UINTN SourceY,\r
246 IN UINTN DestinationX,\r
247 IN UINTN DestinationY,\r
248 IN UINTN Width,\r
249 IN UINTN Height,\r
250 IN UINTN Delta OPTIONAL\r
656419f9
RC
251 )\r
252{\r
ac0a286f
MK
253 EFI_TPL OriginalTPL;\r
254 EFI_STATUS Status;\r
656419f9
RC
255\r
256 if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {\r
257 return EFI_INVALID_PARAMETER;\r
258 }\r
259\r
ac0a286f 260 if ((Width == 0) || (Height == 0)) {\r
656419f9
RC
261 return EFI_INVALID_PARAMETER;\r
262 }\r
263\r
264 //\r
265 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
266 // We would not want a timer based event (Cursor, ...) to come in while we are\r
267 // doing this operation.\r
268 //\r
269 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
270\r
271 switch (BltOperation) {\r
ac0a286f
MK
272 case EfiBltVideoToBltBuffer:\r
273 case EfiBltBufferToVideo:\r
274 case EfiBltVideoFill:\r
275 case EfiBltVideoToVideo:\r
276 Status = FrameBufferBlt (\r
277 fbconf,\r
278 BltBuffer,\r
279 BltOperation,\r
280 SourceX,\r
281 SourceY,\r
282 DestinationX,\r
283 DestinationY,\r
284 Width,\r
285 Height,\r
286 Delta\r
287 );\r
288 break;\r
289\r
290 default:\r
291 Status = EFI_INVALID_PARAMETER;\r
292 ASSERT (FALSE);\r
656419f9
RC
293 }\r
294\r
295 gBS->RestoreTPL (OriginalTPL);\r
296\r
297 return Status;\r
298}\r
299\r
656419f9
RC
300//\r
301// Construction and Destruction functions\r
302//\r
303\r
304EFI_STATUS\r
305EmuGopConstructor (\r
ac0a286f 306 GOP_PRIVATE_DATA *Private\r
656419f9
RC
307 )\r
308{\r
309 // Set mode 0 to be the requested resolution\r
ac0a286f
MK
310 mGopModeData[0].HorizontalResolution = PcdGet32 (PcdVideoHorizontalResolution);\r
311 mGopModeData[0].VerticalResolution = PcdGet32 (PcdVideoVerticalResolution);\r
656419f9
RC
312\r
313 Private->ModeData = mGopModeData;\r
314\r
ac0a286f
MK
315 Private->GraphicsOutput.QueryMode = EmuGopQuerytMode;\r
316 Private->GraphicsOutput.SetMode = EmuGopSetMode;\r
317 Private->GraphicsOutput.Blt = EmuGopBlt;\r
656419f9
RC
318\r
319 //\r
320 // Allocate buffer for Graphics Output Protocol mode information\r
321 //\r
322 Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));\r
323 if (Private->GraphicsOutput.Mode == NULL) {\r
324 return EFI_OUT_OF_RESOURCES;\r
325 }\r
ac0a286f 326\r
656419f9
RC
327 Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
328 if (Private->GraphicsOutput.Mode->Info == NULL) {\r
329 return EFI_OUT_OF_RESOURCES;\r
330 }\r
331\r
656419f9
RC
332 DEBUG ((DEBUG_INFO, "BHYVE Gop Constructor\n"));\r
333\r
ac0a286f 334 Private->GraphicsOutput.Mode->MaxMode = sizeof (mGopModeData) / sizeof (GOP_MODE_DATA);\r
656419f9
RC
335 //\r
336 // Till now, we have no idea about the window size.\r
337 //\r
ac0a286f
MK
338 Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALID_MODE_NUMBER;\r
339 Private->GraphicsOutput.Mode->Info->Version = 0;\r
656419f9 340 Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;\r
ac0a286f
MK
341 Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
342 Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBitMask;\r
343 Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
344 Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS)Private->FbAddr;\r
345 Private->GraphicsOutput.Mode->FrameBufferSize = Private->FbSize;\r
656419f9
RC
346\r
347 return EFI_SUCCESS;\r
348}\r
349\r
656419f9
RC
350EFI_STATUS\r
351EmuGopDestructor (\r
ac0a286f 352 GOP_PRIVATE_DATA *Private\r
656419f9
RC
353 )\r
354{\r
355 //\r
356 // Free graphics output protocol occupied resource\r
357 //\r
358 if (Private->GraphicsOutput.Mode != NULL) {\r
359 if (Private->GraphicsOutput.Mode->Info != NULL) {\r
360 FreePool (Private->GraphicsOutput.Mode->Info);\r
361 }\r
ac0a286f 362\r
656419f9
RC
363 FreePool (Private->GraphicsOutput.Mode);\r
364 Private->GraphicsOutput.Mode = NULL;\r
365 }\r
366\r
367 return EFI_SUCCESS;\r
368}\r
369\r
656419f9
RC
370VOID\r
371EFIAPI\r
372ShutdownGopEvent (\r
373 IN EFI_EVENT Event,\r
374 IN VOID *Context\r
375 )\r
ac0a286f 376\r
656419f9
RC
377/*++\r
378\r
379Routine Description:\r
380\r
381 This is the UGA screen's callback notification function for exit-boot-services.\r
382 All we do here is call EmuGopDestructor().\r
383\r
384Arguments:\r
385\r
386 Event - not used\r
387 Context - pointer to the Private structure.\r
388\r
389Returns:\r
390\r
391 None.\r
392\r
393**/\r
394{\r
395 EmuGopDestructor (Context);\r
396}\r