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