TianoCore EDK2 master
Loading...
Searching...
No Matches
Gop.c
Go to the documentation of this file.
1
10#include "Qemu.h"
11
13
15VOID
16QemuVideoCompleteModeInfo (
17 IN QEMU_VIDEO_MODE_DATA *ModeData,
19 )
20{
21 Info->Version = 0;
22 if (ModeData->ColorDepth == 8) {
23 Info->PixelFormat = PixelBitMask;
24 Info->PixelInformation.RedMask = PIXEL_RED_MASK;
25 Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
26 Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
27 Info->PixelInformation.ReservedMask = 0;
28 } else if (ModeData->ColorDepth == 24) {
29 Info->PixelFormat = PixelBitMask;
30 Info->PixelInformation.RedMask = PIXEL24_RED_MASK;
31 Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;
32 Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;
33 Info->PixelInformation.ReservedMask = 0;
34 } else if (ModeData->ColorDepth == 32) {
35 DEBUG ((DEBUG_INFO, "PixelBlueGreenRedReserved8BitPerColor\n"));
36 Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
37 Info->PixelInformation.RedMask = 0;
38 Info->PixelInformation.GreenMask = 0;
39 Info->PixelInformation.BlueMask = 0;
40 Info->PixelInformation.ReservedMask = 0;
41 } else {
42 DEBUG ((DEBUG_ERROR, "%a: Invalid ColorDepth %u", __func__, ModeData->ColorDepth));
43 ASSERT (FALSE);
44 }
45
46 Info->PixelsPerScanLine = Info->HorizontalResolution;
47}
48
51QemuVideoCompleteModeData (
54 )
55{
58 QEMU_VIDEO_MODE_DATA *ModeData;
59 EFI_STATUS Status;
60
61 ModeData = &Private->ModeData[Mode->Mode];
62 Info = Mode->Info;
63 QemuVideoCompleteModeInfo (ModeData, Info);
64
65 Private->PciIo->GetBarAttributes (
66 Private->PciIo,
67 Private->FrameBufferVramBarIndex,
68 NULL,
69 (VOID **)&FrameBufDesc
70 );
71
72 Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
73 Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
74 Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);
75 Mode->FrameBufferSize = EFI_PAGES_TO_SIZE (
76 EFI_SIZE_TO_PAGES (Mode->FrameBufferSize)
77 );
78 DEBUG ((
79 DEBUG_INFO,
80 "FrameBufferBase: 0x%Lx, FrameBufferSize: 0x%Lx\n",
81 Mode->FrameBufferBase,
82 (UINT64)Mode->FrameBufferSize
83 ));
84
85 if (FeaturePcdGet (PcdRemapFrameBufferWriteCombine)) {
86 Status = gDS->SetMemorySpaceCapabilities (
87 FrameBufDesc->AddrRangeMin,
88 FrameBufDesc->AddrLen,
89 EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_XP
90 );
91 ASSERT_EFI_ERROR (Status);
92
93 Status = gDS->SetMemorySpaceAttributes (
94 FrameBufDesc->AddrRangeMin,
95 FrameBufDesc->AddrLen,
96 EFI_MEMORY_WC | EFI_MEMORY_XP
97 );
98 ASSERT_EFI_ERROR (Status);
99 }
100
101 FreePool (FrameBufDesc);
102 return EFI_SUCCESS;
103}
104
105//
106// Graphics Output Protocol Member Functions
107//
109EFIAPI
110QemuVideoGraphicsOutputQueryMode (
112 IN UINT32 ModeNumber,
113 OUT UINTN *SizeOfInfo,
115 )
116
117/*++
118
119Routine Description:
120
121 Graphics Output protocol interface to query video mode
122
123 Arguments:
124 This - Protocol instance pointer.
125 ModeNumber - The mode number to return information on.
126 Info - Caller allocated buffer that returns information about ModeNumber.
127 SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
128
129 Returns:
130 EFI_SUCCESS - Mode information returned.
131 EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
132 EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
133 EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
134 EFI_INVALID_PARAMETER - One of the input args was NULL.
135
136--*/
137{
139 QEMU_VIDEO_MODE_DATA *ModeData;
140
141 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
142
143 if ((Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode)) {
144 return EFI_INVALID_PARAMETER;
145 }
146
148 if (*Info == NULL) {
149 return EFI_OUT_OF_RESOURCES;
150 }
151
152 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
153
154 ModeData = &Private->ModeData[ModeNumber];
155 (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
156 (*Info)->VerticalResolution = ModeData->VerticalResolution;
157 QemuVideoCompleteModeInfo (ModeData, *Info);
158
159 return EFI_SUCCESS;
160}
161
163EFIAPI
164QemuVideoGraphicsOutputSetMode (
166 IN UINT32 ModeNumber
167 )
168
169/*++
170
171Routine Description:
172
173 Graphics Output protocol interface to set video mode
174
175 Arguments:
176 This - Protocol instance pointer.
177 ModeNumber - The mode number to be set.
178
179 Returns:
180 EFI_SUCCESS - Graphics mode was changed.
181 EFI_DEVICE_ERROR - The device had an error and could not complete the request.
182 EFI_UNSUPPORTED - ModeNumber is not supported by this device.
183
184--*/
185{
187 QEMU_VIDEO_MODE_DATA *ModeData;
188 RETURN_STATUS Status;
190
191 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
192
193 if (ModeNumber >= This->Mode->MaxMode) {
194 return EFI_UNSUPPORTED;
195 }
196
197 ModeData = &Private->ModeData[ModeNumber];
198
199 switch (Private->Variant) {
200 case QEMU_VIDEO_CIRRUS_5430:
201 case QEMU_VIDEO_CIRRUS_5446:
202 InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]);
203 break;
204 case QEMU_VIDEO_BOCHS_MMIO:
205 case QEMU_VIDEO_BOCHS:
206 InitializeBochsGraphicsMode (Private, ModeData);
207 break;
208 default:
209 ASSERT (FALSE);
210 return EFI_DEVICE_ERROR;
211 }
212
213 This->Mode->Mode = ModeNumber;
214 This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
215 This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
216 This->Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
217
218 QemuVideoCompleteModeData (Private, This->Mode);
219
220 //
221 // Re-initialize the frame buffer configure when mode changes.
222 //
223 Status = FrameBufferBltConfigure (
224 (VOID *)(UINTN)This->Mode->FrameBufferBase,
225 This->Mode->Info,
226 Private->FrameBufferBltConfigure,
227 &Private->FrameBufferBltConfigureSize
228 );
229 if (Status == RETURN_BUFFER_TOO_SMALL) {
230 //
231 // Frame buffer configure may be larger in new mode.
232 //
233 if (Private->FrameBufferBltConfigure != NULL) {
234 FreePool (Private->FrameBufferBltConfigure);
235 }
236
237 Private->FrameBufferBltConfigure =
238 AllocatePool (Private->FrameBufferBltConfigureSize);
239 ASSERT (Private->FrameBufferBltConfigure != NULL);
240
241 //
242 // Create the configuration for FrameBufferBltLib
243 //
244 Status = FrameBufferBltConfigure (
245 (VOID *)(UINTN)This->Mode->FrameBufferBase,
246 This->Mode->Info,
247 Private->FrameBufferBltConfigure,
248 &Private->FrameBufferBltConfigureSize
249 );
250 }
251
252 ASSERT (Status == RETURN_SUCCESS);
253
254 //
255 // Per UEFI Spec, need to clear the visible portions of the output display to black.
256 //
257 ZeroMem (&Black, sizeof (Black));
258 Status = FrameBufferBlt (
259 Private->FrameBufferBltConfigure,
260 &Black,
262 0,
263 0,
264 0,
265 0,
266 This->Mode->Info->HorizontalResolution,
267 This->Mode->Info->VerticalResolution,
268 0
269 );
270 ASSERT_RETURN_ERROR (Status);
271
272 return EFI_SUCCESS;
273}
274
276EFIAPI
277QemuVideoGraphicsOutputBlt (
279 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
281 IN UINTN SourceX,
282 IN UINTN SourceY,
283 IN UINTN DestinationX,
284 IN UINTN DestinationY,
285 IN UINTN Width,
286 IN UINTN Height,
287 IN UINTN Delta
288 )
289
290/*++
291
292Routine Description:
293
294 Graphics Output protocol instance to block transfer for CirrusLogic device
295
296Arguments:
297
298 This - Pointer to Graphics Output protocol instance
299 BltBuffer - The data to transfer to screen
300 BltOperation - The operation to perform
301 SourceX - The X coordinate of the source for BltOperation
302 SourceY - The Y coordinate of the source for BltOperation
303 DestinationX - The X coordinate of the destination for BltOperation
304 DestinationY - The Y coordinate of the destination for BltOperation
305 Width - The width of a rectangle in the blt rectangle in pixels
306 Height - The height of a rectangle in the blt rectangle in pixels
307 Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
308 If a Delta of 0 is used, the entire BltBuffer will be operated on.
309 If a subrectangle of the BltBuffer is used, then Delta represents
310 the number of bytes in a row of the BltBuffer.
311
312Returns:
313
314 EFI_INVALID_PARAMETER - Invalid parameter passed in
315 EFI_SUCCESS - Blt operation success
316
317--*/
318{
319 EFI_STATUS Status;
320 EFI_TPL OriginalTPL;
322
323 Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
324 //
325 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
326 // We would not want a timer based event (Cursor, ...) to come in while we are
327 // doing this operation.
328 //
329 OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
330
331 switch (BltOperation) {
334 case EfiBltVideoFill:
336 Status = FrameBufferBlt (
337 Private->FrameBufferBltConfigure,
338 BltBuffer,
339 BltOperation,
340 SourceX,
341 SourceY,
342 DestinationX,
343 DestinationY,
344 Width,
345 Height,
346 Delta
347 );
348 break;
349
350 default:
351 Status = EFI_INVALID_PARAMETER;
352 break;
353 }
354
355 gBS->RestoreTPL (OriginalTPL);
356
357 return Status;
358}
359
361QemuVideoGraphicsOutputConstructor (
363 )
364{
365 EFI_STATUS Status;
366 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
367
368 GraphicsOutput = &Private->GraphicsOutput;
369 GraphicsOutput->QueryMode = QemuVideoGraphicsOutputQueryMode;
370 GraphicsOutput->SetMode = QemuVideoGraphicsOutputSetMode;
371 GraphicsOutput->Blt = QemuVideoGraphicsOutputBlt;
372
373 //
374 // Initialize the private data
375 //
376 Status = gBS->AllocatePool (
379 (VOID **)&Private->GraphicsOutput.Mode
380 );
381 if (EFI_ERROR (Status)) {
382 return Status;
383 }
384
385 Status = gBS->AllocatePool (
388 (VOID **)&Private->GraphicsOutput.Mode->Info
389 );
390 if (EFI_ERROR (Status)) {
391 goto FreeMode;
392 }
393
394 Private->GraphicsOutput.Mode->MaxMode = (UINT32)Private->MaxMode;
395 Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
396 Private->FrameBufferBltConfigure = NULL;
397 Private->FrameBufferBltConfigureSize = 0;
398
399 //
400 // Initialize the hardware
401 //
402 Status = GraphicsOutput->SetMode (GraphicsOutput, 0);
403 if (EFI_ERROR (Status)) {
404 goto FreeInfo;
405 }
406
407 DrawLogo (
408 Private,
409 Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
410 Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
411 );
412
413 return EFI_SUCCESS;
414
415FreeInfo:
416 FreePool (Private->GraphicsOutput.Mode->Info);
417
418FreeMode:
419 FreePool (Private->GraphicsOutput.Mode);
420 Private->GraphicsOutput.Mode = NULL;
421
422 return Status;
423}
424
426QemuVideoGraphicsOutputDestructor (
428 )
429
430/*++
431
432Routine Description:
433
434Arguments:
435
436Returns:
437
438 None
439
440--*/
441{
442 if (Private->FrameBufferBltConfigure != NULL) {
443 FreePool (Private->FrameBufferBltConfigure);
444 }
445
446 if (Private->GraphicsOutput.Mode != NULL) {
447 if (Private->GraphicsOutput.Mode->Info != NULL) {
448 gBS->FreePool (Private->GraphicsOutput.Mode->Info);
449 }
450
451 gBS->FreePool (Private->GraphicsOutput.Mode);
452 }
453
454 return EFI_SUCCESS;
455}
UINT64 UINTN
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_DXE_SERVICES * gDS
VOID EFIAPI FreePool(IN VOID *Buffer)
RETURN_STATUS EFIAPI FrameBufferBlt(IN FRAME_BUFFER_CONFIGURE *Configure, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta)
RETURN_STATUS EFIAPI FrameBufferBltConfigure(IN VOID *FrameBuffer, IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN OUT FRAME_BUFFER_CONFIGURE *Configure, IN OUT UINTN *ConfigureSize)
#define NULL
Definition: Base.h:319
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define STATIC
Definition: Base.h:264
#define RETURN_SUCCESS
Definition: Base.h:1066
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_GRAPHICS_OUTPUT_BLT_OPERATION
@ EfiBltVideoToBltBuffer
@ EfiBltBufferToVideo
@ EfiBltVideoFill
@ EfiBltVideoToVideo
@ PixelBitMask
@ PixelBlueGreenRedReserved8BitPerColor
VOID DrawLogo(QEMU_VIDEO_PRIVATE_DATA *Private, UINTN ScreenWidth, UINTN ScreenHeight)
Definition: Driver.c:832
VOID InitializeCirrusGraphicsMode(QEMU_VIDEO_PRIVATE_DATA *Private, QEMU_VIDEO_CIRRUS_MODES *ModeData)
Definition: Driver.c:850
QEMU_VIDEO_CIRRUS_MODES QemuVideoCirrusModes[]
Definition: Initialize.c:139
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesData
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE * Mode
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * Info