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