]> git.proxmox.com Git - mirror_edk2.git/blame - UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutput.c
SecurityPkg: Support CcMeasurementProtocol in DxeTpmMeasurementLib
[mirror_edk2.git] / UefiPayloadPkg / GraphicsOutputDxe / GraphicsOutput.c
CommitLineData
04af8bf2
DG
1/** @file\r
2 Implementation for a generic GOP driver.\r
3\r
4Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7\r
8**/\r
9\r
10#include "GraphicsOutput.h"\r
e5efcf8b 11CONST ACPI_ADR_DEVICE_PATH mGraphicsOutputAdrNode = {\r
04af8bf2
DG
12 {\r
13 ACPI_DEVICE_PATH,\r
14 ACPI_ADR_DP,\r
15 { sizeof (ACPI_ADR_DEVICE_PATH), 0 },\r
16 },\r
17 ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0)\r
18};\r
19\r
e5efcf8b 20EFI_PEI_GRAPHICS_DEVICE_INFO_HOB mDefaultGraphicsDeviceInfo = {\r
04af8bf2
DG
21 MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT8, MAX_UINT8\r
22};\r
23\r
24//\r
25// The driver should only start on one graphics controller.\r
26// So a global flag is used to remember that the driver is already started.\r
27//\r
e5efcf8b 28BOOLEAN mDriverStarted = FALSE;\r
04af8bf2
DG
29\r
30/**\r
31 Returns information for an available graphics mode that the graphics device\r
32 and the set of active video output devices supports.\r
33\r
34 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
35 @param ModeNumber The mode number to return information on.\r
36 @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.\r
37 @param Info A pointer to callee allocated buffer that returns information about ModeNumber.\r
38\r
39 @retval EFI_SUCCESS Valid mode information was returned.\r
40 @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.\r
41 @retval EFI_INVALID_PARAMETER ModeNumber is not valid.\r
42\r
43**/\r
44EFI_STATUS\r
45EFIAPI\r
46GraphicsOutputQueryMode (\r
47 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
48 IN UINT32 ModeNumber,\r
49 OUT UINTN *SizeOfInfo,\r
50 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
51 )\r
52{\r
e5efcf8b 53 if ((This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode)) {\r
04af8bf2
DG
54 return EFI_INVALID_PARAMETER;\r
55 }\r
56\r
57 *SizeOfInfo = This->Mode->SizeOfInfo;\r
58 *Info = AllocateCopyPool (*SizeOfInfo, This->Mode->Info);\r
59 return EFI_SUCCESS;\r
60}\r
61\r
62/**\r
63 Set the video device into the specified mode and clears the visible portions of\r
64 the output display to black.\r
65\r
66 @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
67 @param ModeNumber Abstraction that defines the current video mode.\r
68\r
69 @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.\r
70 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
71 @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.\r
72\r
73**/\r
74EFI_STATUS\r
75EFIAPI\r
76GraphicsOutputSetMode (\r
e5efcf8b
MK
77 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
78 IN UINT32 ModeNumber\r
79 )\r
04af8bf2 80{\r
e5efcf8b
MK
81 RETURN_STATUS Status;\r
82 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;\r
83 GRAPHICS_OUTPUT_PRIVATE_DATA *Private;\r
04af8bf2
DG
84\r
85 if (ModeNumber >= This->Mode->MaxMode) {\r
86 return EFI_UNSUPPORTED;\r
87 }\r
88\r
89 Private = GRAPHICS_OUTPUT_PRIVATE_FROM_THIS (This);\r
90\r
e5efcf8b
MK
91 Black.Blue = 0;\r
92 Black.Green = 0;\r
93 Black.Red = 0;\r
04af8bf2
DG
94 Black.Reserved = 0;\r
95\r
96 Status = FrameBufferBlt (\r
97 Private->FrameBufferBltLibConfigure,\r
98 &Black,\r
99 EfiBltVideoFill,\r
e5efcf8b
MK
100 0,\r
101 0,\r
102 0,\r
103 0,\r
04af8bf2
DG
104 This->Mode->Info->HorizontalResolution,\r
105 This->Mode->Info->VerticalResolution,\r
106 0\r
107 );\r
108 return RETURN_ERROR (Status) ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
109}\r
110\r
111/**\r
112 Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.\r
113\r
114 @param This Protocol instance pointer.\r
115 @param BltBuffer The data to transfer to the graphics screen.\r
116 Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL).\r
117 @param BltOperation The operation to perform when copying BltBuffer on to the graphics screen.\r
118 @param SourceX The X coordinate of source for the BltOperation.\r
119 @param SourceY The Y coordinate of source for the BltOperation.\r
120 @param DestinationX The X coordinate of destination for the BltOperation.\r
121 @param DestinationY The Y coordinate of destination for the BltOperation.\r
122 @param Width The width of a rectangle in the blt rectangle in pixels.\r
123 @param Height The height of a rectangle in the blt rectangle in pixels.\r
124 @param Delta Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation.\r
125 If a Delta of zero is used, the entire BltBuffer is being operated on.\r
126 If a subrectangle of the BltBuffer is being used then Delta\r
127 represents the number of bytes in a row of the BltBuffer.\r
128\r
129 @retval EFI_SUCCESS BltBuffer was drawn to the graphics screen.\r
130 @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
131 @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.\r
132\r
133**/\r
134EFI_STATUS\r
135EFIAPI\r
136GraphicsOutputBlt (\r
e5efcf8b
MK
137 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
138 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,\r
139 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
140 IN UINTN SourceX,\r
141 IN UINTN SourceY,\r
142 IN UINTN DestinationX,\r
143 IN UINTN DestinationY,\r
144 IN UINTN Width,\r
145 IN UINTN Height,\r
146 IN UINTN Delta OPTIONAL\r
04af8bf2
DG
147 )\r
148{\r
e5efcf8b
MK
149 RETURN_STATUS Status;\r
150 EFI_TPL Tpl;\r
151 GRAPHICS_OUTPUT_PRIVATE_DATA *Private;\r
04af8bf2
DG
152\r
153 Private = GRAPHICS_OUTPUT_PRIVATE_FROM_THIS (This);\r
154 //\r
155 // We have to raise to TPL_NOTIFY, so we make an atomic write to the frame buffer.\r
156 // We would not want a timer based event (Cursor, ...) to come in while we are\r
157 // doing this operation.\r
158 //\r
e5efcf8b 159 Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
04af8bf2
DG
160 Status = FrameBufferBlt (\r
161 Private->FrameBufferBltLibConfigure,\r
162 BltBuffer,\r
163 BltOperation,\r
e5efcf8b
MK
164 SourceX,\r
165 SourceY,\r
166 DestinationX,\r
167 DestinationY,\r
168 Width,\r
169 Height,\r
04af8bf2
DG
170 Delta\r
171 );\r
172 gBS->RestoreTPL (Tpl);\r
173\r
174 return RETURN_ERROR (Status) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;\r
175}\r
176\r
e5efcf8b 177CONST GRAPHICS_OUTPUT_PRIVATE_DATA mGraphicsOutputInstanceTemplate = {\r
04af8bf2
DG
178 GRAPHICS_OUTPUT_PRIVATE_DATA_SIGNATURE, // Signature\r
179 NULL, // GraphicsOutputHandle\r
180 {\r
181 GraphicsOutputQueryMode,\r
182 GraphicsOutputSetMode,\r
183 GraphicsOutputBlt,\r
184 NULL // Mode\r
185 },\r
186 {\r
187 1, // MaxMode\r
188 0, // Mode\r
189 NULL, // Info\r
190 sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), // SizeOfInfo\r
191 0, // FrameBufferBase\r
192 0 // FrameBufferSize\r
193 },\r
194 NULL, // DevicePath\r
195 NULL, // PciIo\r
196 0, // PciAttributes\r
197 NULL, // FrameBufferBltLibConfigure\r
198 0 // FrameBufferBltLibConfigureSize\r
199};\r
200\r
201/**\r
202 Test whether the Controller can be managed by the driver.\r
203\r
204 @param This Driver Binding protocol instance pointer.\r
205 @param Controller The PCI controller.\r
206 @param RemainingDevicePath Optional parameter use to pick a specific child\r
207 device to start.\r
208\r
209 @retval EFI_SUCCESS The driver can manage the video device.\r
210 @retval other The driver cannot manage the video device.\r
211**/\r
212EFI_STATUS\r
213EFIAPI\r
214GraphicsOutputDriverBindingSupported (\r
e5efcf8b
MK
215 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
216 IN EFI_HANDLE Controller,\r
217 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
04af8bf2
DG
218 )\r
219{\r
e5efcf8b
MK
220 EFI_STATUS Status;\r
221 EFI_PCI_IO_PROTOCOL *PciIo;\r
222 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
04af8bf2
DG
223\r
224 //\r
225 // Since there is only one GraphicsInfo HOB, the driver only manages one video device.\r
226 //\r
227 if (mDriverStarted) {\r
228 return EFI_ALREADY_STARTED;\r
229 }\r
230\r
231 //\r
232 // Test the PCI I/O Protocol\r
233 //\r
234 Status = gBS->OpenProtocol (\r
235 Controller,\r
236 &gEfiPciIoProtocolGuid,\r
e5efcf8b 237 (VOID **)&PciIo,\r
04af8bf2
DG
238 This->DriverBindingHandle,\r
239 Controller,\r
240 EFI_OPEN_PROTOCOL_BY_DRIVER\r
241 );\r
242 if (Status == EFI_ALREADY_STARTED) {\r
243 Status = EFI_SUCCESS;\r
244 }\r
e5efcf8b 245\r
04af8bf2
DG
246 if (EFI_ERROR (Status)) {\r
247 return Status;\r
248 }\r
e5efcf8b 249\r
04af8bf2
DG
250 gBS->CloseProtocol (\r
251 Controller,\r
252 &gEfiPciIoProtocolGuid,\r
253 This->DriverBindingHandle,\r
254 Controller\r
255 );\r
256\r
257 //\r
258 // Test the DevicePath protocol\r
259 //\r
260 Status = gBS->OpenProtocol (\r
261 Controller,\r
262 &gEfiDevicePathProtocolGuid,\r
e5efcf8b 263 (VOID **)&DevicePath,\r
04af8bf2
DG
264 This->DriverBindingHandle,\r
265 Controller,\r
266 EFI_OPEN_PROTOCOL_BY_DRIVER\r
267 );\r
268 if (Status == EFI_ALREADY_STARTED) {\r
269 Status = EFI_SUCCESS;\r
270 }\r
e5efcf8b 271\r
04af8bf2
DG
272 if (EFI_ERROR (Status)) {\r
273 return Status;\r
274 }\r
e5efcf8b 275\r
04af8bf2
DG
276 gBS->CloseProtocol (\r
277 Controller,\r
278 &gEfiDevicePathProtocolGuid,\r
279 This->DriverBindingHandle,\r
280 Controller\r
281 );\r
282\r
283 if ((RemainingDevicePath == NULL) ||\r
284 IsDevicePathEnd (RemainingDevicePath) ||\r
e5efcf8b
MK
285 (CompareMem (RemainingDevicePath, &mGraphicsOutputAdrNode, sizeof (mGraphicsOutputAdrNode)) == 0))\r
286 {\r
04af8bf2
DG
287 return EFI_SUCCESS;\r
288 } else {\r
289 return EFI_INVALID_PARAMETER;\r
290 }\r
291}\r
292\r
293/**\r
294 Start the video controller.\r
295\r
296 @param This Driver Binding protocol instance pointer.\r
297 @param ControllerHandle The PCI controller.\r
298 @param RemainingDevicePath Optional parameter use to pick a specific child\r
299 device to start.\r
300\r
301 @retval EFI_SUCCESS The driver starts to manage the video device.\r
302 @retval other The driver cannot manage the video device.\r
303**/\r
304EFI_STATUS\r
305EFIAPI\r
306GraphicsOutputDriverBindingStart (\r
e5efcf8b
MK
307 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
308 IN EFI_HANDLE Controller,\r
309 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
04af8bf2
DG
310 )\r
311{\r
e5efcf8b
MK
312 EFI_STATUS Status;\r
313 RETURN_STATUS ReturnStatus;\r
314 GRAPHICS_OUTPUT_PRIVATE_DATA *Private;\r
315 EFI_PCI_IO_PROTOCOL *PciIo;\r
316 EFI_DEVICE_PATH *PciDevicePath;\r
317 PCI_TYPE00 Pci;\r
318 UINT8 Index;\r
319 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources;\r
320 VOID *HobStart;\r
321 EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;\r
322 EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *DeviceInfo;\r
323 EFI_PHYSICAL_ADDRESS FrameBufferBase;\r
04af8bf2
DG
324\r
325 FrameBufferBase = 0;\r
326\r
327 HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);\r
328 ASSERT ((HobStart != NULL) && (GET_GUID_HOB_DATA_SIZE (HobStart) == sizeof (EFI_PEI_GRAPHICS_INFO_HOB)));\r
e5efcf8b 329 GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *)(GET_GUID_HOB_DATA (HobStart));\r
04af8bf2
DG
330\r
331 HobStart = GetFirstGuidHob (&gEfiGraphicsDeviceInfoHobGuid);\r
332 if ((HobStart == NULL) || (GET_GUID_HOB_DATA_SIZE (HobStart) < sizeof (*DeviceInfo))) {\r
333 //\r
334 // Use default device infomation when the device info HOB doesn't exist\r
335 //\r
336 DeviceInfo = &mDefaultGraphicsDeviceInfo;\r
337 DEBUG ((DEBUG_INFO, "[%a]: GraphicsDeviceInfo HOB doesn't exist!\n", gEfiCallerBaseName));\r
338 } else {\r
e5efcf8b
MK
339 DeviceInfo = (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *)(GET_GUID_HOB_DATA (HobStart));\r
340 DEBUG ((\r
341 DEBUG_INFO,\r
342 "[%a]: GraphicsDeviceInfo HOB:\n"\r
343 " VendorId = %04x, DeviceId = %04x,\n"\r
344 " RevisionId = %02x, BarIndex = %x,\n"\r
345 " SubsystemVendorId = %04x, SubsystemId = %04x\n",\r
346 gEfiCallerBaseName,\r
347 DeviceInfo->VendorId,\r
348 DeviceInfo->DeviceId,\r
349 DeviceInfo->RevisionId,\r
350 DeviceInfo->BarIndex,\r
351 DeviceInfo->SubsystemVendorId,\r
352 DeviceInfo->SubsystemId\r
353 ));\r
04af8bf2
DG
354 }\r
355\r
356 //\r
357 // Open the PCI I/O Protocol\r
358 //\r
359 Status = gBS->OpenProtocol (\r
360 Controller,\r
361 &gEfiPciIoProtocolGuid,\r
e5efcf8b 362 (VOID **)&PciIo,\r
04af8bf2
DG
363 This->DriverBindingHandle,\r
364 Controller,\r
365 EFI_OPEN_PROTOCOL_BY_DRIVER\r
366 );\r
367 if (Status == EFI_ALREADY_STARTED) {\r
368 Status = EFI_SUCCESS;\r
369 }\r
e5efcf8b 370\r
04af8bf2
DG
371 ASSERT_EFI_ERROR (Status);\r
372\r
373 Status = gBS->OpenProtocol (\r
374 Controller,\r
375 &gEfiDevicePathProtocolGuid,\r
e5efcf8b 376 (VOID **)&PciDevicePath,\r
04af8bf2
DG
377 This->DriverBindingHandle,\r
378 Controller,\r
379 EFI_OPEN_PROTOCOL_BY_DRIVER\r
380 );\r
381 if (Status == EFI_ALREADY_STARTED) {\r
382 Status = EFI_SUCCESS;\r
383 }\r
e5efcf8b 384\r
04af8bf2
DG
385 ASSERT_EFI_ERROR (Status);\r
386\r
387 //\r
388 // Read the PCI Class Code from the PCI Device\r
389 //\r
390 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (Pci), &Pci);\r
391 if (!EFI_ERROR (Status)) {\r
392 if (!IS_PCI_DISPLAY (&Pci) || (\r
e5efcf8b
MK
393 ((DeviceInfo->VendorId != MAX_UINT16) && (DeviceInfo->VendorId != Pci.Hdr.VendorId)) ||\r
394 ((DeviceInfo->DeviceId != MAX_UINT16) && (DeviceInfo->DeviceId != Pci.Hdr.DeviceId)) ||\r
395 ((DeviceInfo->RevisionId != MAX_UINT8) && (DeviceInfo->RevisionId != Pci.Hdr.RevisionID)) ||\r
396 ((DeviceInfo->SubsystemVendorId != MAX_UINT16) && (DeviceInfo->SubsystemVendorId != Pci.Device.SubsystemVendorID)) ||\r
397 ((DeviceInfo->SubsystemId != MAX_UINT16) && (DeviceInfo->SubsystemId != Pci.Device.SubsystemID))\r
398 )\r
04af8bf2 399 )\r
e5efcf8b 400 {\r
04af8bf2
DG
401 //\r
402 // It's not a video device, or device infomation doesn't match.\r
403 //\r
404 Status = EFI_UNSUPPORTED;\r
405 } else {\r
406 //\r
407 // If it's a video device and device information matches, use the BarIndex\r
408 // from device information, or any BAR if BarIndex is not specified\r
409 // whose size >= the frame buffer size from GraphicsInfo HOB.\r
410 // Store the new frame buffer base.\r
411 //\r
412 for (Index = 0; Index < MAX_PCI_BAR; Index++) {\r
413 if ((DeviceInfo->BarIndex != MAX_UINT8) && (DeviceInfo->BarIndex != Index)) {\r
414 continue;\r
415 }\r
e5efcf8b
MK
416\r
417 Status = PciIo->GetBarAttributes (PciIo, Index, NULL, (VOID **)&Resources);\r
04af8bf2 418 if (!EFI_ERROR (Status)) {\r
e5efcf8b
MK
419 DEBUG ((\r
420 DEBUG_INFO,\r
421 "[%a]: BAR[%d]: Base = %lx, Length = %lx\n",\r
422 gEfiCallerBaseName,\r
423 Index,\r
424 Resources->AddrRangeMin,\r
425 Resources->AddrLen\r
426 ));\r
04af8bf2 427 if ((Resources->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) &&\r
e5efcf8b 428 (Resources->Len == (UINT16)(sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3)) &&\r
04af8bf2
DG
429 (Resources->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) &&\r
430 (Resources->AddrLen >= GraphicsInfo->FrameBufferSize)\r
e5efcf8b
MK
431 )\r
432 {\r
04af8bf2
DG
433 if (FrameBufferBase == 0) {\r
434 FrameBufferBase = Resources->AddrRangeMin;\r
435 }\r
e5efcf8b 436\r
04af8bf2
DG
437 if (DeviceInfo->BarIndex == MAX_UINT8) {\r
438 if (Resources->AddrRangeMin == GraphicsInfo->FrameBufferBase) {\r
439 FrameBufferBase = Resources->AddrRangeMin;\r
440 break;\r
441 }\r
442 } else {\r
443 break;\r
444 }\r
445 }\r
446 }\r
447 }\r
e5efcf8b 448\r
04af8bf2
DG
449 if (Index == MAX_PCI_BAR) {\r
450 Status = EFI_UNSUPPORTED;\r
451 } else {\r
452 DEBUG ((DEBUG_INFO, "[%a]: ... matched!\n", gEfiCallerBaseName));\r
453 }\r
454 }\r
455 }\r
456\r
457 if (EFI_ERROR (Status)) {\r
458 goto CloseProtocols;\r
459 }\r
460\r
461 if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {\r
462 return EFI_SUCCESS;\r
463 }\r
464\r
465 Private = AllocateCopyPool (sizeof (mGraphicsOutputInstanceTemplate), &mGraphicsOutputInstanceTemplate);\r
466 if (Private == NULL) {\r
467 Status = EFI_OUT_OF_RESOURCES;\r
468 goto CloseProtocols;\r
469 }\r
470\r
471 Private->GraphicsOutputMode.FrameBufferBase = FrameBufferBase;\r
472 Private->GraphicsOutputMode.FrameBufferSize = GraphicsInfo->FrameBufferSize;\r
e5efcf8b 473 Private->GraphicsOutputMode.Info = &GraphicsInfo->GraphicsMode;\r
04af8bf2
DG
474\r
475 //\r
476 // Fix up Mode pointer in GraphicsOutput\r
477 //\r
478 Private->GraphicsOutput.Mode = &Private->GraphicsOutputMode;\r
479\r
480 //\r
481 // Set attributes\r
482 //\r
483 Status = PciIo->Attributes (\r
484 PciIo,\r
485 EfiPciIoAttributeOperationGet,\r
486 0,\r
487 &Private->PciAttributes\r
488 );\r
489 if (!EFI_ERROR (Status)) {\r
490 Status = PciIo->Attributes (\r
491 PciIo,\r
492 EfiPciIoAttributeOperationEnable,\r
493 EFI_PCI_DEVICE_ENABLE,\r
494 NULL\r
495 );\r
496 }\r
497\r
498 if (EFI_ERROR (Status)) {\r
499 goto FreeMemory;\r
500 }\r
501\r
502 //\r
503 // Create the FrameBufferBltLib configuration.\r
504 //\r
505 ReturnStatus = FrameBufferBltConfigure (\r
e5efcf8b 506 (VOID *)(UINTN)Private->GraphicsOutput.Mode->FrameBufferBase,\r
04af8bf2
DG
507 Private->GraphicsOutput.Mode->Info,\r
508 Private->FrameBufferBltLibConfigure,\r
509 &Private->FrameBufferBltLibConfigureSize\r
510 );\r
511 if (ReturnStatus == RETURN_BUFFER_TOO_SMALL) {\r
512 Private->FrameBufferBltLibConfigure = AllocatePool (Private->FrameBufferBltLibConfigureSize);\r
513 if (Private->FrameBufferBltLibConfigure != NULL) {\r
514 ReturnStatus = FrameBufferBltConfigure (\r
e5efcf8b 515 (VOID *)(UINTN)Private->GraphicsOutput.Mode->FrameBufferBase,\r
04af8bf2
DG
516 Private->GraphicsOutput.Mode->Info,\r
517 Private->FrameBufferBltLibConfigure,\r
518 &Private->FrameBufferBltLibConfigureSize\r
519 );\r
520 }\r
521 }\r
e5efcf8b 522\r
04af8bf2
DG
523 if (RETURN_ERROR (ReturnStatus)) {\r
524 Status = EFI_OUT_OF_RESOURCES;\r
525 goto RestorePciAttributes;\r
526 }\r
527\r
e5efcf8b 528 Private->DevicePath = AppendDevicePathNode (PciDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&mGraphicsOutputAdrNode);\r
04af8bf2
DG
529 if (Private->DevicePath == NULL) {\r
530 Status = EFI_OUT_OF_RESOURCES;\r
531 goto RestorePciAttributes;\r
532 }\r
533\r
534 Status = gBS->InstallMultipleProtocolInterfaces (\r
535 &Private->GraphicsOutputHandle,\r
e5efcf8b
MK
536 &gEfiGraphicsOutputProtocolGuid,\r
537 &Private->GraphicsOutput,\r
538 &gEfiDevicePathProtocolGuid,\r
539 Private->DevicePath,\r
04af8bf2
DG
540 NULL\r
541 );\r
542\r
543 if (!EFI_ERROR (Status)) {\r
544 Status = gBS->OpenProtocol (\r
545 Controller,\r
546 &gEfiPciIoProtocolGuid,\r
e5efcf8b 547 (VOID **)&Private->PciIo,\r
04af8bf2
DG
548 This->DriverBindingHandle,\r
549 Private->GraphicsOutputHandle,\r
550 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
551 );\r
552 if (!EFI_ERROR (Status)) {\r
553 mDriverStarted = TRUE;\r
554 } else {\r
555 gBS->UninstallMultipleProtocolInterfaces (\r
556 Private->GraphicsOutputHandle,\r
e5efcf8b
MK
557 &gEfiGraphicsOutputProtocolGuid,\r
558 &Private->GraphicsOutput,\r
559 &gEfiDevicePathProtocolGuid,\r
560 Private->DevicePath,\r
04af8bf2
DG
561 NULL\r
562 );\r
563 }\r
564 }\r
565\r
566RestorePciAttributes:\r
567 if (EFI_ERROR (Status)) {\r
568 //\r
569 // Restore original PCI attributes\r
570 //\r
571 PciIo->Attributes (\r
572 PciIo,\r
573 EfiPciIoAttributeOperationSet,\r
574 Private->PciAttributes,\r
575 NULL\r
576 );\r
577 }\r
578\r
579FreeMemory:\r
580 if (EFI_ERROR (Status)) {\r
581 if (Private != NULL) {\r
582 if (Private->DevicePath != NULL) {\r
583 FreePool (Private->DevicePath);\r
584 }\r
e5efcf8b 585\r
04af8bf2
DG
586 if (Private->FrameBufferBltLibConfigure != NULL) {\r
587 FreePool (Private->FrameBufferBltLibConfigure);\r
588 }\r
e5efcf8b 589\r
04af8bf2
DG
590 FreePool (Private);\r
591 }\r
592 }\r
593\r
594CloseProtocols:\r
595 if (EFI_ERROR (Status)) {\r
596 //\r
597 // Close the PCI I/O Protocol\r
598 //\r
599 gBS->CloseProtocol (\r
600 Controller,\r
601 &gEfiDevicePathProtocolGuid,\r
602 This->DriverBindingHandle,\r
603 Controller\r
604 );\r
605\r
606 //\r
607 // Close the PCI I/O Protocol\r
608 //\r
609 gBS->CloseProtocol (\r
610 Controller,\r
611 &gEfiPciIoProtocolGuid,\r
612 This->DriverBindingHandle,\r
613 Controller\r
614 );\r
615 }\r
e5efcf8b 616\r
04af8bf2
DG
617 return Status;\r
618}\r
619\r
620/**\r
621 Stop the video controller.\r
622\r
623 @param This Driver Binding protocol instance pointer.\r
624 @param Controller The PCI controller.\r
625 @param NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
626 @param ChildHandleBuffer An array of child handles to be freed. May be NULL\r
627 if NumberOfChildren is 0.\r
628\r
629 @retval EFI_SUCCESS The device was stopped.\r
630 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
631**/\r
632EFI_STATUS\r
633EFIAPI\r
634GraphicsOutputDriverBindingStop (\r
e5efcf8b
MK
635 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
636 IN EFI_HANDLE Controller,\r
637 IN UINTN NumberOfChildren,\r
638 IN EFI_HANDLE *ChildHandleBuffer\r
04af8bf2
DG
639 )\r
640{\r
e5efcf8b
MK
641 EFI_STATUS Status;\r
642 EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;\r
643 GRAPHICS_OUTPUT_PRIVATE_DATA *Private;\r
04af8bf2
DG
644\r
645 if (NumberOfChildren == 0) {\r
04af8bf2
DG
646 //\r
647 // Close the PCI I/O Protocol\r
648 //\r
649 Status = gBS->CloseProtocol (\r
650 Controller,\r
651 &gEfiPciIoProtocolGuid,\r
652 This->DriverBindingHandle,\r
653 Controller\r
654 );\r
655 ASSERT_EFI_ERROR (Status);\r
656\r
657 Status = gBS->CloseProtocol (\r
658 Controller,\r
659 &gEfiDevicePathProtocolGuid,\r
660 This->DriverBindingHandle,\r
661 Controller\r
662 );\r
663 ASSERT_EFI_ERROR (Status);\r
664 return EFI_SUCCESS;\r
665 }\r
666\r
667 ASSERT (NumberOfChildren == 1);\r
668 Status = gBS->OpenProtocol (\r
669 ChildHandleBuffer[0],\r
670 &gEfiGraphicsOutputProtocolGuid,\r
e5efcf8b 671 (VOID **)&Gop,\r
04af8bf2
DG
672 This->DriverBindingHandle,\r
673 ChildHandleBuffer[0],\r
674 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
675 );\r
676 if (EFI_ERROR (Status)) {\r
677 return Status;\r
678 }\r
679\r
680 Private = GRAPHICS_OUTPUT_PRIVATE_FROM_THIS (Gop);\r
681\r
682 Status = gBS->CloseProtocol (\r
683 Controller,\r
684 &gEfiPciIoProtocolGuid,\r
685 This->DriverBindingHandle,\r
686 Private->GraphicsOutputHandle\r
687 );\r
688 ASSERT_EFI_ERROR (Status);\r
689 //\r
690 // Remove the GOP protocol interface from the system\r
691 //\r
692 Status = gBS->UninstallMultipleProtocolInterfaces (\r
693 Private->GraphicsOutputHandle,\r
e5efcf8b
MK
694 &gEfiGraphicsOutputProtocolGuid,\r
695 &Private->GraphicsOutput,\r
696 &gEfiDevicePathProtocolGuid,\r
697 Private->DevicePath,\r
04af8bf2
DG
698 NULL\r
699 );\r
700 if (!EFI_ERROR (Status)) {\r
701 //\r
702 // Restore original PCI attributes\r
703 //\r
704 Status = Private->PciIo->Attributes (\r
705 Private->PciIo,\r
706 EfiPciIoAttributeOperationSet,\r
707 Private->PciAttributes,\r
708 NULL\r
709 );\r
710 ASSERT_EFI_ERROR (Status);\r
711\r
712 FreePool (Private->DevicePath);\r
713 FreePool (Private->FrameBufferBltLibConfigure);\r
714 mDriverStarted = FALSE;\r
715 } else {\r
716 Status = gBS->OpenProtocol (\r
717 Controller,\r
718 &gEfiPciIoProtocolGuid,\r
e5efcf8b 719 (VOID **)&Private->PciIo,\r
04af8bf2
DG
720 This->DriverBindingHandle,\r
721 Private->GraphicsOutputHandle,\r
722 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
723 );\r
724 ASSERT_EFI_ERROR (Status);\r
725 }\r
e5efcf8b 726\r
04af8bf2
DG
727 return Status;\r
728}\r
729\r
e5efcf8b 730EFI_DRIVER_BINDING_PROTOCOL mGraphicsOutputDriverBinding = {\r
04af8bf2
DG
731 GraphicsOutputDriverBindingSupported,\r
732 GraphicsOutputDriverBindingStart,\r
733 GraphicsOutputDriverBindingStop,\r
734 0x10,\r
735 NULL,\r
736 NULL\r
737};\r
738\r
739/**\r
740 The Entry Point for GraphicsOutput driver.\r
741\r
742 It installs DriverBinding, ComponentName and ComponentName2 protocol if there is\r
743 GraphicsInfo HOB passed from Graphics PEIM.\r
744\r
745 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
746 @param[in] SystemTable A pointer to the EFI System Table.\r
747\r
748 @retval EFI_SUCCESS The entry point is executed successfully.\r
749 @retval other Some error occurs when executing this entry point.\r
750\r
751**/\r
752EFI_STATUS\r
753EFIAPI\r
754InitializeGraphicsOutput (\r
e5efcf8b
MK
755 IN EFI_HANDLE ImageHandle,\r
756 IN EFI_SYSTEM_TABLE *SystemTable\r
04af8bf2
DG
757 )\r
758{\r
e5efcf8b
MK
759 EFI_STATUS Status;\r
760 VOID *HobStart;\r
04af8bf2
DG
761\r
762 HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);\r
763\r
764 if ((HobStart == NULL) || (GET_GUID_HOB_DATA_SIZE (HobStart) < sizeof (EFI_PEI_GRAPHICS_INFO_HOB))) {\r
765 return EFI_NOT_FOUND;\r
766 }\r
767\r
768 Status = EfiLibInstallDriverBindingComponentName2 (\r
769 ImageHandle,\r
770 SystemTable,\r
771 &mGraphicsOutputDriverBinding,\r
772 ImageHandle,\r
773 &mGraphicsOutputComponentName,\r
774 &mGraphicsOutputComponentName2\r
775 );\r
776 ASSERT_EFI_ERROR (Status);\r
777\r
778 return Status;\r
779}\r