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