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