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.
8 SPDX-License-Identifier: BSD-2-Clause-Patent
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.
23 #include <Library/FrameBufferBltLib.h>
25 EFI_EVENT mGopScreenExitBootServicesEvent
;
27 GOP_MODE_DATA mGopModeData
[] = {
28 { 0, 0, 32, 0 }, // Filled in with user-spec'd resolution
36 BhyveGopCompleteModeInfo (
37 IN GOP_MODE_DATA
*ModeData
,
38 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
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) {
57 "%dx%d PixelBlueGreenRedReserved8BitPerColor\n",
58 ModeData
->HorizontalResolution
,
59 ModeData
->VerticalResolution
61 Info
->PixelFormat
= PixelBlueGreenRedReserved8BitPerColor
;
64 Info
->PixelsPerScanLine
= Info
->HorizontalResolution
;
68 Returns information for an available graphics mode that the graphics device
69 and the set of active video output devices supports.
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.
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.
86 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
88 OUT UINTN
*SizeOfInfo
,
89 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
92 GOP_PRIVATE_DATA
*Private
;
93 GOP_MODE_DATA
*ModeData
;
95 Private
= GOP_PRIVATE_DATA_FROM_THIS (This
);
97 if ((Info
== NULL
) || (SizeOfInfo
== NULL
) || ((UINTN
)ModeNumber
>= This
->Mode
->MaxMode
)) {
98 return EFI_INVALID_PARAMETER
;
101 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
103 return EFI_OUT_OF_RESOURCES
;
106 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
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
);
119 Set the video device into the specified mode and clears the visible portions of
120 the output display to black.
122 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
123 @param ModeNumber Abstraction that defines the current video mode.
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.
131 FRAME_BUFFER_CONFIGURE
*fbconf
;
136 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
140 GOP_PRIVATE_DATA
*Private
;
141 GOP_MODE_DATA
*ModeData
;
142 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill
;
143 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
149 Private
= GOP_PRIVATE_DATA_FROM_THIS (This
);
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
;
157 DEBUG ((DEBUG_INFO
, "BHYVE GopSetMode %d\n", ModeNumber
));
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
;
165 Info
= This
->Mode
->Info
;
166 BhyveGopCompleteModeInfo (ModeData
, Info
);
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
;
174 This->Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution
175 * ((ModeData->ColorDepth + 7) / 8);
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
));
180 BhyveSetGraphicsMode (Private
, (UINT16
)ModeData
->HorizontalResolution
, (UINT16
)ModeData
->VerticalResolution
, (UINT16
)ModeData
->ColorDepth
);
182 RETURN_STATUS ret
= FrameBufferBltConfigure (
183 (VOID
*)(UINTN
)This
->Mode
->FrameBufferBase
,
189 if ((ret
== EFI_BUFFER_TOO_SMALL
) || (ret
== EFI_INVALID_PARAMETER
)) {
190 fbconf
= AllocatePool (confsize
);
191 ret
= FrameBufferBltConfigure (
192 (VOID
*)(UINTN
)This
->Mode
->FrameBufferBase
,
197 ASSERT (ret
== EFI_SUCCESS
);
211 ModeData
->HorizontalResolution
,
212 ModeData
->VerticalResolution
,
213 ModeData
->HorizontalResolution
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
219 Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.
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
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.
241 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
242 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer OPTIONAL
,
243 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
246 IN UINTN DestinationX
,
247 IN UINTN DestinationY
,
250 IN UINTN Delta OPTIONAL
256 if ((UINT32
)BltOperation
>= EfiGraphicsOutputBltOperationMax
) {
257 return EFI_INVALID_PARAMETER
;
260 if ((Width
== 0) || (Height
== 0)) {
261 return EFI_INVALID_PARAMETER
;
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.
269 OriginalTPL
= gBS
->RaiseTPL (TPL_NOTIFY
);
271 switch (BltOperation
) {
272 case EfiBltVideoToBltBuffer
:
273 case EfiBltBufferToVideo
:
274 case EfiBltVideoFill
:
275 case EfiBltVideoToVideo
:
276 Status
= FrameBufferBlt (
291 Status
= EFI_INVALID_PARAMETER
;
295 gBS
->RestoreTPL (OriginalTPL
);
301 // Construction and Destruction functions
306 GOP_PRIVATE_DATA
*Private
309 // Set mode 0 to be the requested resolution
310 mGopModeData
[0].HorizontalResolution
= PcdGet32 (PcdVideoHorizontalResolution
);
311 mGopModeData
[0].VerticalResolution
= PcdGet32 (PcdVideoVerticalResolution
);
313 Private
->ModeData
= mGopModeData
;
315 Private
->GraphicsOutput
.QueryMode
= EmuGopQuerytMode
;
316 Private
->GraphicsOutput
.SetMode
= EmuGopSetMode
;
317 Private
->GraphicsOutput
.Blt
= EmuGopBlt
;
320 // Allocate buffer for Graphics Output Protocol mode information
322 Private
->GraphicsOutput
.Mode
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
));
323 if (Private
->GraphicsOutput
.Mode
== NULL
) {
324 return EFI_OUT_OF_RESOURCES
;
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
;
332 DEBUG ((DEBUG_INFO
, "BHYVE Gop Constructor\n"));
334 Private
->GraphicsOutput
.Mode
->MaxMode
= sizeof (mGopModeData
) / sizeof (GOP_MODE_DATA
);
336 // Till now, we have no idea about the window size.
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
;
352 GOP_PRIVATE_DATA
*Private
356 // Free graphics output protocol occupied resource
358 if (Private
->GraphicsOutput
.Mode
!= NULL
) {
359 if (Private
->GraphicsOutput
.Mode
->Info
!= NULL
) {
360 FreePool (Private
->GraphicsOutput
.Mode
->Info
);
363 FreePool (Private
->GraphicsOutput
.Mode
);
364 Private
->GraphicsOutput
.Mode
= NULL
;
381 This is the UGA screen's callback notification function for exit-boot-services.
382 All we do here is call EmuGopDestructor().
387 Context - pointer to the Private structure.
395 EmuGopDestructor (Context
);