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