]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/QemuVideoDxe/Gop.c
bd49ee91391fb6e995465b8868a5eb258e9c5ff8
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Gop.c
1 /** @file
2 Graphics Output Protocol functions for the QEMU video controller.
3
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5
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
10
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.
13
14 **/
15
16 #include "Qemu.h"
17 #include <IndustryStandard/Acpi.h>
18 #include <Library/BltLib.h>
19
20 STATIC
21 VOID
22 QemuVideoCompleteModeInfo (
23 IN QEMU_VIDEO_MODE_DATA *ModeData,
24 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info
25 )
26 {
27 Info->Version = 0;
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;
43 }
44 Info->PixelsPerScanLine = Info->HorizontalResolution;
45 }
46
47
48 STATIC
49 EFI_STATUS
50 QemuVideoCompleteModeData (
51 IN QEMU_VIDEO_PRIVATE_DATA *Private,
52 OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
53 )
54 {
55 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
56 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc;
57 QEMU_VIDEO_MODE_DATA *ModeData;
58
59 ModeData = &Private->ModeData[Mode->Mode];
60 Info = Mode->Info;
61 QemuVideoCompleteModeInfo (ModeData, Info);
62
63 Private->PciIo->GetBarAttributes (
64 Private->PciIo,
65 0,
66 NULL,
67 (VOID**) &FrameBufDesc
68 );
69
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));
74
75 return EFI_SUCCESS;
76 }
77
78
79 //
80 // Graphics Output Protocol Member Functions
81 //
82 EFI_STATUS
83 EFIAPI
84 QemuVideoGraphicsOutputQueryMode (
85 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
86 IN UINT32 ModeNumber,
87 OUT UINTN *SizeOfInfo,
88 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
89 )
90 /*++
91
92 Routine Description:
93
94 Graphics Output protocol interface to query video mode
95
96 Arguments:
97 This - Protocol instance pointer.
98 ModeNumber - The mode number to return information on.
99 Info - Caller allocated buffer that returns information about ModeNumber.
100 SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
101
102 Returns:
103 EFI_SUCCESS - Mode information returned.
104 EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
105 EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
106 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
107 EFI_INVALID_PARAMETER - One of the input args was NULL.
108
109 --*/
110 {
111 QEMU_VIDEO_PRIVATE_DATA *Private;
112 QEMU_VIDEO_MODE_DATA *ModeData;
113
114 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
115
116 if (Private->HardwareNeedsStarting) {
117 return EFI_NOT_STARTED;
118 }
119
120 if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
121 return EFI_INVALID_PARAMETER;
122 }
123
124 *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
125 if (*Info == NULL) {
126 return EFI_OUT_OF_RESOURCES;
127 }
128
129 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
130
131 ModeData = &Private->ModeData[ModeNumber];
132 (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
133 (*Info)->VerticalResolution = ModeData->VerticalResolution;
134 QemuVideoCompleteModeInfo (ModeData, *Info);
135
136 return EFI_SUCCESS;
137 }
138
139 EFI_STATUS
140 EFIAPI
141 QemuVideoGraphicsOutputSetMode (
142 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
143 IN UINT32 ModeNumber
144 )
145 /*++
146
147 Routine Description:
148
149 Graphics Output protocol interface to set video mode
150
151 Arguments:
152 This - Protocol instance pointer.
153 ModeNumber - The mode number to be set.
154
155 Returns:
156 EFI_SUCCESS - Graphics mode was changed.
157 EFI_DEVICE_ERROR - The device had an error and could not complete the request.
158 EFI_UNSUPPORTED - ModeNumber is not supported by this device.
159
160 --*/
161 {
162 QEMU_VIDEO_PRIVATE_DATA *Private;
163 QEMU_VIDEO_MODE_DATA *ModeData;
164 // UINTN Count;
165
166 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
167
168 if (ModeNumber >= This->Mode->MaxMode) {
169 return EFI_UNSUPPORTED;
170 }
171
172 ModeData = &Private->ModeData[ModeNumber];
173
174 if (Private->LineBuffer) {
175 gBS->FreePool (Private->LineBuffer);
176 }
177
178 Private->LineBuffer = NULL;
179 Private->LineBuffer = AllocatePool (4 * ModeData->HorizontalResolution);
180 if (Private->LineBuffer == NULL) {
181 return EFI_OUT_OF_RESOURCES;
182 }
183
184 switch (Private->Variant) {
185 case QEMU_VIDEO_CIRRUS_5430:
186 case QEMU_VIDEO_CIRRUS_5446:
187 InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->ModeNumber]);
188 break;
189 default:
190 ASSERT (FALSE);
191 gBS->FreePool (Private->LineBuffer);
192 Private->LineBuffer = NULL;
193 return EFI_DEVICE_ERROR;
194 }
195
196 This->Mode->Mode = ModeNumber;
197 This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
198 This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
199 This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
200
201 QemuVideoCompleteModeData (Private, This->Mode);
202
203 BltLibConfigure (
204 (VOID*)(UINTN) This->Mode->FrameBufferBase,
205 This->Mode->Info
206 );
207
208 Private->HardwareNeedsStarting = FALSE;
209
210 return EFI_SUCCESS;
211 }
212
213 EFI_STATUS
214 EFIAPI
215 QemuVideoGraphicsOutputBlt (
216 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
217 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
218 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
219 IN UINTN SourceX,
220 IN UINTN SourceY,
221 IN UINTN DestinationX,
222 IN UINTN DestinationY,
223 IN UINTN Width,
224 IN UINTN Height,
225 IN UINTN Delta
226 )
227 /*++
228
229 Routine Description:
230
231 Graphics Output protocol instance to block transfer for CirrusLogic device
232
233 Arguments:
234
235 This - Pointer to Graphics Output protocol instance
236 BltBuffer - The data to transfer to screen
237 BltOperation - The operation to perform
238 SourceX - The X coordinate of the source for BltOperation
239 SourceY - The Y coordinate of the source for BltOperation
240 DestinationX - The X coordinate of the destination for BltOperation
241 DestinationY - The Y coordinate of the destination for BltOperation
242 Width - The width of a rectangle in the blt rectangle in pixels
243 Height - The height of a rectangle in the blt rectangle in pixels
244 Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
245 If a Delta of 0 is used, the entire BltBuffer will be operated on.
246 If a subrectangle of the BltBuffer is used, then Delta represents
247 the number of bytes in a row of the BltBuffer.
248
249 Returns:
250
251 EFI_INVALID_PARAMETER - Invalid parameter passed in
252 EFI_SUCCESS - Blt operation success
253
254 --*/
255 {
256 EFI_STATUS Status;
257 EFI_TPL OriginalTPL;
258
259 //
260 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
261 // We would not want a timer based event (Cursor, ...) to come in while we are
262 // doing this operation.
263 //
264 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
265
266 switch (BltOperation) {
267 case EfiBltVideoToBltBuffer:
268 case EfiBltBufferToVideo:
269 case EfiBltVideoFill:
270 case EfiBltVideoToVideo:
271 Status = BltLibGopBlt (
272 BltBuffer,
273 BltOperation,
274 SourceX,
275 SourceY,
276 DestinationX,
277 DestinationY,
278 Width,
279 Height,
280 Delta
281 );
282 break;
283
284 default:
285 Status = EFI_INVALID_PARAMETER;
286 ASSERT (FALSE);
287 }
288
289 gBS->RestoreTPL (OriginalTPL);
290
291 return Status;
292 }
293
294 EFI_STATUS
295 QemuVideoGraphicsOutputConstructor (
296 QEMU_VIDEO_PRIVATE_DATA *Private
297 )
298 {
299 EFI_STATUS Status;
300 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
301
302
303 GraphicsOutput = &Private->GraphicsOutput;
304 GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
305 GraphicsOutput->SetMode = QemuVideoGraphicsOutputSetMode;
306 GraphicsOutput->Blt = QemuVideoGraphicsOutputBlt;
307
308 //
309 // Initialize the private data
310 //
311 Status = gBS->AllocatePool (
312 EfiBootServicesData,
313 sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
314 (VOID **) &Private->GraphicsOutput.Mode
315 );
316 if (EFI_ERROR (Status)) {
317 return Status;
318 }
319 Status = gBS->AllocatePool (
320 EfiBootServicesData,
321 sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
322 (VOID **) &Private->GraphicsOutput.Mode->Info
323 );
324 if (EFI_ERROR (Status)) {
325 return Status;
326 }
327 Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
328 Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
329 Private->HardwareNeedsStarting = TRUE;
330 Private->LineBuffer = NULL;
331
332 //
333 // Initialize the hardware
334 //
335 GraphicsOutput->SetMode (GraphicsOutput, 0);
336 DrawLogo (
337 Private,
338 Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
339 Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
340 );
341
342 return EFI_SUCCESS;
343 }
344
345 EFI_STATUS
346 QemuVideoGraphicsOutputDestructor (
347 QEMU_VIDEO_PRIVATE_DATA *Private
348 )
349 /*++
350
351 Routine Description:
352
353 Arguments:
354
355 Returns:
356
357 None
358
359 --*/
360 {
361 if (Private->GraphicsOutput.Mode != NULL) {
362 if (Private->GraphicsOutput.Mode->Info != NULL) {
363 gBS->FreePool (Private->GraphicsOutput.Mode->Info);
364 }
365 gBS->FreePool (Private->GraphicsOutput.Mode);
366 }
367
368 return EFI_SUCCESS;
369 }
370
371