CloverBootloader/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c
2019-09-03 12:58:42 +03:00

730 lines
25 KiB
C

/** @file
Implementation for a generic GOP driver.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "GraphicsOutput.h"
CONST ACPI_ADR_DEVICE_PATH mGraphicsOutputAdrNode = {
{
ACPI_DEVICE_PATH,
ACPI_ADR_DP,
{ sizeof (ACPI_ADR_DEVICE_PATH), 0 },
},
ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0)
};
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB mDefaultGraphicsDeviceInfo = {
MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT8, MAX_UINT8
};
//
// The driver should only start on one graphics controller.
// So a global flag is used to remember that the driver is already started.
//
BOOLEAN mDriverStarted = FALSE;
/**
Returns information for an available graphics mode that the graphics device
and the set of active video output devices supports.
@param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
@param ModeNumber The mode number to return information on.
@param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
@param Info A pointer to callee allocated buffer that returns information about ModeNumber.
@retval EFI_SUCCESS Valid mode information was returned.
@retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
@retval EFI_INVALID_PARAMETER ModeNumber is not valid.
**/
EFI_STATUS
EFIAPI
GraphicsOutputQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
{
if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
return EFI_INVALID_PARAMETER;
}
*SizeOfInfo = This->Mode->SizeOfInfo;
*Info = AllocateCopyPool (*SizeOfInfo, This->Mode->Info);
return EFI_SUCCESS;
}
/**
Set the video device into the specified mode and clears the visible portions of
the output display to black.
@param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
@param ModeNumber Abstraction that defines the current video mode.
@retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.
@retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
@retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
**/
EFI_STATUS
EFIAPI
GraphicsOutputSetMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
)
{
RETURN_STATUS Status;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
GRAPHICS_OUTPUT_PRIVATE_DATA *Private;
if (ModeNumber >= This->Mode->MaxMode) {
return EFI_UNSUPPORTED;
}
Private = GRAPHICS_OUTPUT_PRIVATE_FROM_THIS (This);
Black.Blue = 0;
Black.Green = 0;
Black.Red = 0;
Black.Reserved = 0;
Status = FrameBufferBlt (
Private->FrameBufferBltLibConfigure,
&Black,
EfiBltVideoFill,
0, 0,
0, 0,
This->Mode->Info->HorizontalResolution,
This->Mode->Info->VerticalResolution,
0
);
return RETURN_ERROR (Status) ? EFI_DEVICE_ERROR : EFI_SUCCESS;
}
/**
Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.
@param This Protocol instance pointer.
@param BltBuffer The data to transfer to the graphics screen.
Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL).
@param BltOperation The operation to perform when copying BltBuffer on to the graphics screen.
@param SourceX The X coordinate of source for the BltOperation.
@param SourceY The Y coordinate of source for the BltOperation.
@param DestinationX The X coordinate of destination for the BltOperation.
@param DestinationY The Y coordinate of destination for the BltOperation.
@param Width The width of a rectangle in the blt rectangle in pixels.
@param Height The height of a rectangle in the blt rectangle in pixels.
@param Delta Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation.
If a Delta of zero is used, the entire BltBuffer is being operated on.
If a subrectangle of the BltBuffer is being used then Delta
represents the number of bytes in a row of the BltBuffer.
@retval EFI_SUCCESS BltBuffer was drawn to the graphics screen.
@retval EFI_INVALID_PARAMETER BltOperation is not valid.
@retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
**/
EFI_STATUS
EFIAPI
GraphicsOutputBlt (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN 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 OPTIONAL
)
{
RETURN_STATUS Status;
EFI_TPL Tpl;
GRAPHICS_OUTPUT_PRIVATE_DATA *Private;
Private = GRAPHICS_OUTPUT_PRIVATE_FROM_THIS (This);
//
// We have to raise to TPL_NOTIFY, so we make an atomic write to the frame buffer.
// We would not want a timer based event (Cursor, ...) to come in while we are
// doing this operation.
//
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
Status = FrameBufferBlt (
Private->FrameBufferBltLibConfigure,
BltBuffer,
BltOperation,
SourceX, SourceY,
DestinationX, DestinationY, Width, Height,
Delta
);
gBS->RestoreTPL (Tpl);
return RETURN_ERROR (Status) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
}
CONST GRAPHICS_OUTPUT_PRIVATE_DATA mGraphicsOutputInstanceTemplate = {
GRAPHICS_OUTPUT_PRIVATE_DATA_SIGNATURE, // Signature
NULL, // GraphicsOutputHandle
{
GraphicsOutputQueryMode,
GraphicsOutputSetMode,
GraphicsOutputBlt,
NULL // Mode
},
{
1, // MaxMode
0, // Mode
NULL, // Info
sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), // SizeOfInfo
0, // FrameBufferBase
0 // FrameBufferSize
},
NULL, // DevicePath
NULL, // PciIo
0, // PciAttributes
NULL, // FrameBufferBltLibConfigure
0 // FrameBufferBltLibConfigureSize
};
/**
Test whether the Controller can be managed by the driver.
@param This Driver Binding protocol instance pointer.
@param Controller The PCI controller.
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS The driver can manage the video device.
@retval other The driver cannot manage the video device.
**/
EFI_STATUS
EFIAPI
GraphicsOutputDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
//
// Since there is only one GraphicsInfo HOB, the driver only manages one video device.
//
if (mDriverStarted) {
return EFI_ALREADY_STARTED;
}
//
// Test the PCI I/O Protocol
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
Status = EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
//
// Test the DevicePath protocol
//
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &DevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
Status = EFI_SUCCESS;
}
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
if ((RemainingDevicePath == NULL) ||
IsDevicePathEnd (RemainingDevicePath) ||
CompareMem (RemainingDevicePath, &mGraphicsOutputAdrNode, sizeof (mGraphicsOutputAdrNode)) == 0) {
return EFI_SUCCESS;
} else {
return EFI_INVALID_PARAMETER;
}
}
/**
Start the video controller.
@param This Driver Binding protocol instance pointer.
@param ControllerHandle The PCI controller.
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS The driver starts to manage the video device.
@retval other The driver cannot manage the video device.
**/
EFI_STATUS
EFIAPI
GraphicsOutputDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
RETURN_STATUS ReturnStatus;
GRAPHICS_OUTPUT_PRIVATE_DATA *Private;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_DEVICE_PATH *PciDevicePath;
PCI_TYPE00 Pci;
UINT8 Index;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources;
VOID *HobStart;
EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *DeviceInfo;
EFI_PHYSICAL_ADDRESS FrameBufferBase;
FrameBufferBase = 0;
HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);
ASSERT ((HobStart != NULL) && (GET_GUID_HOB_DATA_SIZE (HobStart) == sizeof (EFI_PEI_GRAPHICS_INFO_HOB)));
GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *) (GET_GUID_HOB_DATA (HobStart));
HobStart = GetFirstGuidHob (&gEfiGraphicsDeviceInfoHobGuid);
if ((HobStart == NULL) || (GET_GUID_HOB_DATA_SIZE (HobStart) < sizeof (*DeviceInfo))) {
//
// Use default device infomation when the device info HOB doesn't exist
//
DeviceInfo = &mDefaultGraphicsDeviceInfo;
DEBUG ((EFI_D_INFO, "[%a]: GraphicsDeviceInfo HOB doesn't exist!\n", gEfiCallerBaseName));
} else {
DeviceInfo = (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *) (GET_GUID_HOB_DATA (HobStart));
DEBUG ((EFI_D_INFO, "[%a]: GraphicsDeviceInfo HOB:\n"
" VendorId = %04x, DeviceId = %04x,\n"
" RevisionId = %02x, BarIndex = %x,\n"
" SubsystemVendorId = %04x, SubsystemId = %04x\n",
gEfiCallerBaseName,
DeviceInfo->VendorId, DeviceInfo->DeviceId,
DeviceInfo->RevisionId, DeviceInfo->BarIndex,
DeviceInfo->SubsystemVendorId, DeviceInfo->SubsystemId));
}
//
// Open the PCI I/O Protocol
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
Status = EFI_SUCCESS;
}
ASSERT_EFI_ERROR (Status);
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &PciDevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED) {
Status = EFI_SUCCESS;
}
ASSERT_EFI_ERROR (Status);
//
// Read the PCI Class Code from the PCI Device
//
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (Pci), &Pci);
if (!EFI_ERROR (Status)) {
if (!IS_PCI_DISPLAY (&Pci) || (
((DeviceInfo->VendorId != MAX_UINT16) && (DeviceInfo->VendorId != Pci.Hdr.VendorId)) ||
((DeviceInfo->DeviceId != MAX_UINT16) && (DeviceInfo->DeviceId != Pci.Hdr.DeviceId)) ||
((DeviceInfo->RevisionId != MAX_UINT8) && (DeviceInfo->RevisionId != Pci.Hdr.RevisionID)) ||
((DeviceInfo->SubsystemVendorId != MAX_UINT16) && (DeviceInfo->SubsystemVendorId != Pci.Device.SubsystemVendorID)) ||
((DeviceInfo->SubsystemId != MAX_UINT16) && (DeviceInfo->SubsystemId != Pci.Device.SubsystemID))
)
) {
//
// It's not a video device, or device infomation doesn't match.
//
Status = EFI_UNSUPPORTED;
} else {
//
// If it's a video device and device information matches, use the BarIndex
// from device information, or any BAR if BarIndex is not specified
// whose size >= the frame buffer size from GraphicsInfo HOB.
// Store the new frame buffer base.
//
for (Index = 0; Index < MAX_PCI_BAR; Index++) {
if ((DeviceInfo->BarIndex != MAX_UINT8) && (DeviceInfo->BarIndex != Index)) {
continue;
}
Status = PciIo->GetBarAttributes (PciIo, Index, NULL, (VOID**) &Resources);
if (!EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "[%a]: BAR[%d]: Base = %lx, Length = %lx\n",
gEfiCallerBaseName, Index, Resources->AddrRangeMin, Resources->AddrLen));
if ((Resources->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) &&
(Resources->Len == (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3)) &&
(Resources->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) &&
(Resources->AddrLen >= GraphicsInfo->FrameBufferSize)
) {
FrameBufferBase = Resources->AddrRangeMin;
DEBUG ((EFI_D_INFO, "[%a]: ... matched!\n", gEfiCallerBaseName));
break;
}
}
}
if (Index == MAX_PCI_BAR) {
Status = EFI_UNSUPPORTED;
}
}
}
if (EFI_ERROR (Status)) {
goto CloseProtocols;
}
if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
return EFI_SUCCESS;
}
Private = AllocateCopyPool (sizeof (mGraphicsOutputInstanceTemplate), &mGraphicsOutputInstanceTemplate);
if (Private == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto CloseProtocols;
}
Private->GraphicsOutputMode.FrameBufferBase = FrameBufferBase;
Private->GraphicsOutputMode.FrameBufferSize = GraphicsInfo->FrameBufferSize;
Private->GraphicsOutputMode.Info = &GraphicsInfo->GraphicsMode;
//
// Fix up Mode pointer in GraphicsOutput
//
Private->GraphicsOutput.Mode = &Private->GraphicsOutputMode;
//
// Set attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationGet,
0,
&Private->PciAttributes
);
if (!EFI_ERROR (Status)) {
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
}
if (EFI_ERROR (Status)) {
goto FreeMemory;
}
//
// Create the FrameBufferBltLib configuration.
//
ReturnStatus = FrameBufferBltConfigure (
(VOID *) (UINTN) Private->GraphicsOutput.Mode->FrameBufferBase,
Private->GraphicsOutput.Mode->Info,
Private->FrameBufferBltLibConfigure,
&Private->FrameBufferBltLibConfigureSize
);
if (ReturnStatus == RETURN_BUFFER_TOO_SMALL) {
Private->FrameBufferBltLibConfigure = AllocatePool (Private->FrameBufferBltLibConfigureSize);
if (Private->FrameBufferBltLibConfigure != NULL) {
ReturnStatus = FrameBufferBltConfigure (
(VOID *) (UINTN) Private->GraphicsOutput.Mode->FrameBufferBase,
Private->GraphicsOutput.Mode->Info,
Private->FrameBufferBltLibConfigure,
&Private->FrameBufferBltLibConfigureSize
);
}
}
if (RETURN_ERROR (ReturnStatus)) {
Status = EFI_OUT_OF_RESOURCES;
goto RestorePciAttributes;
}
Private->DevicePath = AppendDevicePathNode (PciDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &mGraphicsOutputAdrNode);
if (Private->DevicePath == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto RestorePciAttributes;
}
Status = gBS->InstallMultipleProtocolInterfaces (
&Private->GraphicsOutputHandle,
&gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput,
&gEfiDevicePathProtocolGuid, Private->DevicePath,
NULL
);
if (!EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &Private->PciIo,
This->DriverBindingHandle,
Private->GraphicsOutputHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
if (!EFI_ERROR (Status)) {
mDriverStarted = TRUE;
} else {
gBS->UninstallMultipleProtocolInterfaces (
Private->GraphicsOutputHandle,
&gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput,
&gEfiDevicePathProtocolGuid, Private->DevicePath,
NULL
);
}
}
RestorePciAttributes:
if (EFI_ERROR (Status)) {
//
// Restore original PCI attributes
//
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
Private->PciAttributes,
NULL
);
}
FreeMemory:
if (EFI_ERROR (Status)) {
if (Private != NULL) {
if (Private->DevicePath != NULL) {
FreePool (Private->DevicePath);
}
if (Private->FrameBufferBltLibConfigure != NULL) {
FreePool (Private->FrameBufferBltLibConfigure);
}
FreePool (Private);
}
}
CloseProtocols:
if (EFI_ERROR (Status)) {
//
// Close the PCI I/O Protocol
//
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
//
// Close the PCI I/O Protocol
//
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
}
return Status;
}
/**
Stop the video controller.
@param This Driver Binding protocol instance pointer.
@param Controller The PCI controller.
@param NumberOfChildren The number of child device handles in ChildHandleBuffer.
@param ChildHandleBuffer An array of child handles to be freed. May be NULL
if NumberOfChildren is 0.
@retval EFI_SUCCESS The device was stopped.
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
**/
EFI_STATUS
EFIAPI
GraphicsOutputDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
GRAPHICS_OUTPUT_PRIVATE_DATA *Private;
if (NumberOfChildren == 0) {
//
// Close the PCI I/O Protocol
//
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
ASSERT_EFI_ERROR (Status);
Status = gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
ASSERT (NumberOfChildren == 1);
Status = gBS->OpenProtocol (
ChildHandleBuffer[0],
&gEfiGraphicsOutputProtocolGuid,
(VOID **) &Gop,
This->DriverBindingHandle,
ChildHandleBuffer[0],
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Private = GRAPHICS_OUTPUT_PRIVATE_FROM_THIS (Gop);
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Private->GraphicsOutputHandle
);
ASSERT_EFI_ERROR (Status);
//
// Remove the GOP protocol interface from the system
//
Status = gBS->UninstallMultipleProtocolInterfaces (
Private->GraphicsOutputHandle,
&gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput,
&gEfiDevicePathProtocolGuid, Private->DevicePath,
NULL
);
if (!EFI_ERROR (Status)) {
//
// Restore original PCI attributes
//
Status = Private->PciIo->Attributes (
Private->PciIo,
EfiPciIoAttributeOperationSet,
Private->PciAttributes,
NULL
);
ASSERT_EFI_ERROR (Status);
FreePool (Private->DevicePath);
FreePool (Private->FrameBufferBltLibConfigure);
mDriverStarted = FALSE;
} else {
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &Private->PciIo,
This->DriverBindingHandle,
Private->GraphicsOutputHandle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
ASSERT_EFI_ERROR (Status);
}
return Status;
}
EFI_DRIVER_BINDING_PROTOCOL mGraphicsOutputDriverBinding = {
GraphicsOutputDriverBindingSupported,
GraphicsOutputDriverBindingStart,
GraphicsOutputDriverBindingStop,
0x10,
NULL,
NULL
};
/**
The Entry Point for GraphicsOutput driver.
It installs DriverBinding, ComponentName and ComponentName2 protocol if there is
GraphicsInfo HOB passed from Graphics PEIM.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializeGraphicsOutput (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
VOID *HobStart;
HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);
if ((HobStart == NULL) || (GET_GUID_HOB_DATA_SIZE (HobStart) < sizeof (EFI_PEI_GRAPHICS_INFO_HOB))) {
return EFI_NOT_FOUND;
}
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&mGraphicsOutputDriverBinding,
ImageHandle,
&mGraphicsOutputComponentName,
&mGraphicsOutputComponentName2
);
ASSERT_EFI_ERROR (Status);
return Status;
}