2 Graphics Output Protocol functions for the QEMU video controller.
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <IndustryStandard/Acpi.h>
18 #include <Library/BltLib.h>
22 QemuVideoCompleteModeInfo (
23 IN QEMU_VIDEO_MODE_DATA
*ModeData
,
24 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
28 if (ModeData
->ColorDepth
== 8) {
29 Info
->PixelFormat
= PixelBitMask
;
30 Info
->PixelInformation
.RedMask
= PIXEL_RED_MASK
;
31 Info
->PixelInformation
.GreenMask
= PIXEL_GREEN_MASK
;
32 Info
->PixelInformation
.BlueMask
= PIXEL_BLUE_MASK
;
33 Info
->PixelInformation
.ReservedMask
= 0;
34 } else if (ModeData
->ColorDepth
== 24) {
35 Info
->PixelFormat
= PixelBitMask
;
36 Info
->PixelInformation
.RedMask
= PIXEL24_RED_MASK
;
37 Info
->PixelInformation
.GreenMask
= PIXEL24_GREEN_MASK
;
38 Info
->PixelInformation
.BlueMask
= PIXEL24_BLUE_MASK
;
39 Info
->PixelInformation
.ReservedMask
= 0;
40 } else if (ModeData
->ColorDepth
== 32) {
41 DEBUG ((EFI_D_INFO
, "PixelBlueGreenRedReserved8BitPerColor\n"));
42 Info
->PixelFormat
= PixelBlueGreenRedReserved8BitPerColor
;
44 Info
->PixelsPerScanLine
= Info
->HorizontalResolution
;
50 QemuVideoCompleteModeData (
51 IN QEMU_VIDEO_PRIVATE_DATA
*Private
,
52 OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
*Mode
55 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
56 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*FrameBufDesc
;
57 QEMU_VIDEO_MODE_DATA
*ModeData
;
59 ModeData
= &Private
->ModeData
[Mode
->Mode
];
61 QemuVideoCompleteModeInfo (ModeData
, Info
);
63 Private
->PciIo
->GetBarAttributes (
67 (VOID
**) &FrameBufDesc
70 Mode
->FrameBufferBase
= FrameBufDesc
->AddrRangeMin
;
71 Mode
->FrameBufferSize
= Info
->HorizontalResolution
* Info
->VerticalResolution
;
72 Mode
->FrameBufferSize
= Mode
->FrameBufferSize
* ((ModeData
->ColorDepth
+ 7) / 8);
73 DEBUG ((EFI_D_INFO
, "FrameBufferBase: 0x%x, FrameBufferSize: 0x%x\n", Mode
->FrameBufferBase
, Mode
->FrameBufferSize
));
75 FreePool (FrameBufDesc
);
81 // Graphics Output Protocol Member Functions
85 QemuVideoGraphicsOutputQueryMode (
86 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
88 OUT UINTN
*SizeOfInfo
,
89 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
95 Graphics Output protocol interface to query video mode
98 This - Protocol instance pointer.
99 ModeNumber - The mode number to return information on.
100 Info - Caller allocated buffer that returns information about ModeNumber.
101 SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
104 EFI_SUCCESS - Mode information returned.
105 EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
106 EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
107 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
108 EFI_INVALID_PARAMETER - One of the input args was NULL.
112 QEMU_VIDEO_PRIVATE_DATA
*Private
;
113 QEMU_VIDEO_MODE_DATA
*ModeData
;
115 Private
= QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This
);
117 if (Private
->HardwareNeedsStarting
) {
118 return EFI_NOT_STARTED
;
121 if (Info
== NULL
|| SizeOfInfo
== NULL
|| ModeNumber
>= This
->Mode
->MaxMode
) {
122 return EFI_INVALID_PARAMETER
;
125 *Info
= AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
));
127 return EFI_OUT_OF_RESOURCES
;
130 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
132 ModeData
= &Private
->ModeData
[ModeNumber
];
133 (*Info
)->HorizontalResolution
= ModeData
->HorizontalResolution
;
134 (*Info
)->VerticalResolution
= ModeData
->VerticalResolution
;
135 QemuVideoCompleteModeInfo (ModeData
, *Info
);
142 QemuVideoGraphicsOutputSetMode (
143 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
150 Graphics Output protocol interface to set video mode
153 This - Protocol instance pointer.
154 ModeNumber - The mode number to be set.
157 EFI_SUCCESS - Graphics mode was changed.
158 EFI_DEVICE_ERROR - The device had an error and could not complete the request.
159 EFI_UNSUPPORTED - ModeNumber is not supported by this device.
163 QEMU_VIDEO_PRIVATE_DATA
*Private
;
164 QEMU_VIDEO_MODE_DATA
*ModeData
;
167 Private
= QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This
);
169 if (ModeNumber
>= This
->Mode
->MaxMode
) {
170 return EFI_UNSUPPORTED
;
173 ModeData
= &Private
->ModeData
[ModeNumber
];
175 if (Private
->LineBuffer
) {
176 gBS
->FreePool (Private
->LineBuffer
);
179 Private
->LineBuffer
= NULL
;
180 Private
->LineBuffer
= AllocatePool (4 * ModeData
->HorizontalResolution
);
181 if (Private
->LineBuffer
== NULL
) {
182 return EFI_OUT_OF_RESOURCES
;
185 switch (Private
->Variant
) {
186 case QEMU_VIDEO_CIRRUS_5430
:
187 case QEMU_VIDEO_CIRRUS_5446
:
188 InitializeCirrusGraphicsMode (Private
, &QemuVideoCirrusModes
[ModeData
->ModeNumber
]);
190 case QEMU_VIDEO_BOCHS_MMIO
:
191 case QEMU_VIDEO_BOCHS
:
192 InitializeBochsGraphicsMode (Private
, &QemuVideoBochsModes
[ModeData
->ModeNumber
]);
196 gBS
->FreePool (Private
->LineBuffer
);
197 Private
->LineBuffer
= NULL
;
198 return EFI_DEVICE_ERROR
;
201 This
->Mode
->Mode
= ModeNumber
;
202 This
->Mode
->Info
->HorizontalResolution
= ModeData
->HorizontalResolution
;
203 This
->Mode
->Info
->VerticalResolution
= ModeData
->VerticalResolution
;
204 This
->Mode
->SizeOfInfo
= sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
206 QemuVideoCompleteModeData (Private
, This
->Mode
);
209 (VOID
*)(UINTN
) This
->Mode
->FrameBufferBase
,
213 Private
->HardwareNeedsStarting
= FALSE
;
220 QemuVideoGraphicsOutputBlt (
221 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
222 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL
*BltBuffer
, OPTIONAL
223 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation
,
226 IN UINTN DestinationX
,
227 IN UINTN DestinationY
,
236 Graphics Output protocol instance to block transfer for CirrusLogic device
240 This - Pointer to Graphics Output protocol instance
241 BltBuffer - The data to transfer to screen
242 BltOperation - The operation to perform
243 SourceX - The X coordinate of the source for BltOperation
244 SourceY - The Y coordinate of the source for BltOperation
245 DestinationX - The X coordinate of the destination for BltOperation
246 DestinationY - The Y coordinate of the destination for BltOperation
247 Width - The width of a rectangle in the blt rectangle in pixels
248 Height - The height of a rectangle in the blt rectangle in pixels
249 Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
250 If a Delta of 0 is used, the entire BltBuffer will be operated on.
251 If a subrectangle of the BltBuffer is used, then Delta represents
252 the number of bytes in a row of the BltBuffer.
256 EFI_INVALID_PARAMETER - Invalid parameter passed in
257 EFI_SUCCESS - Blt operation success
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
= BltLibGopBlt (
290 Status
= EFI_INVALID_PARAMETER
;
294 gBS
->RestoreTPL (OriginalTPL
);
300 QemuVideoGraphicsOutputConstructor (
301 QEMU_VIDEO_PRIVATE_DATA
*Private
305 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
308 GraphicsOutput
= &Private
->GraphicsOutput
;
309 GraphicsOutput
->QueryMode
= QemuVideoGraphicsOutputQueryMode
;
310 GraphicsOutput
->SetMode
= QemuVideoGraphicsOutputSetMode
;
311 GraphicsOutput
->Blt
= QemuVideoGraphicsOutputBlt
;
314 // Initialize the private data
316 Status
= gBS
->AllocatePool (
318 sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
),
319 (VOID
**) &Private
->GraphicsOutput
.Mode
321 if (EFI_ERROR (Status
)) {
324 Status
= gBS
->AllocatePool (
326 sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
),
327 (VOID
**) &Private
->GraphicsOutput
.Mode
->Info
329 if (EFI_ERROR (Status
)) {
332 Private
->GraphicsOutput
.Mode
->MaxMode
= (UINT32
) Private
->MaxMode
;
333 Private
->GraphicsOutput
.Mode
->Mode
= GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER
;
334 Private
->HardwareNeedsStarting
= TRUE
;
335 Private
->LineBuffer
= NULL
;
338 // Initialize the hardware
340 GraphicsOutput
->SetMode (GraphicsOutput
, 0);
343 Private
->ModeData
[Private
->GraphicsOutput
.Mode
->Mode
].HorizontalResolution
,
344 Private
->ModeData
[Private
->GraphicsOutput
.Mode
->Mode
].VerticalResolution
351 QemuVideoGraphicsOutputDestructor (
352 QEMU_VIDEO_PRIVATE_DATA
*Private
366 if (Private
->GraphicsOutput
.Mode
!= NULL
) {
367 if (Private
->GraphicsOutput
.Mode
->Info
!= NULL
) {
368 gBS
->FreePool (Private
->GraphicsOutput
.Mode
->Info
);
370 gBS
->FreePool (Private
->GraphicsOutput
.Mode
);