summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c')
-rw-r--r--MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c1536
1 files changed, 768 insertions, 768 deletions
diff --git a/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c
index 2259d6d4ea..22b5be5314 100644
--- a/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c
+++ b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c
@@ -1,768 +1,768 @@
-/** @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 ((DEBUG_INFO, "[%a]: GraphicsDeviceInfo HOB doesn't exist!\n", gEfiCallerBaseName));
- } else {
- DeviceInfo = (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *)(GET_GUID_HOB_DATA (HobStart));
- DEBUG ((
- DEBUG_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 ((
- DEBUG_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 ((DEBUG_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;
-}
+/** @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 ((DEBUG_INFO, "[%a]: GraphicsDeviceInfo HOB doesn't exist!\n", gEfiCallerBaseName));
+ } else {
+ DeviceInfo = (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *)(GET_GUID_HOB_DATA (HobStart));
+ DEBUG ((
+ DEBUG_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 ((
+ DEBUG_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 ((DEBUG_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;
+}