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