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