Nice. :) One of my motivations for BltLib was the hope that we could make a common GOP driver. Similar to what you are doing here it was for a platform that only supported a single video mode.
Another idea: What if we design a VideoModeSetLib? We could have a 'Null' driver that uses the GraphicsInfo HOB and supports a single mode. Or, a platform could provide a non-null library to allow setting other modes. For example, this might allow OVMF to use GraphicsOutputDxe. -Jordan On 2015-08-17 06:45:29, Ruiyu Ni wrote: > The driver consumes the GraphicsInfo HOB and produces GOP protocol. > > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ruiyu Ni <ruiyu...@intel.com> > Cc: Feng Tian <feng.t...@intel.com> > --- > MdeModulePkg/MdeModulePkg.dsc | 4 + > .../Console/GraphicsOutputDxe/ComponentName.c | 190 ++++++ > .../Console/GraphicsOutputDxe/GraphicsOutput.c | 659 > +++++++++++++++++++++ > .../Console/GraphicsOutputDxe/GraphicsOutput.h | 53 ++ > .../GraphicsOutputDxe/GraphicsOutputDxe.inf | 57 ++ > 5 files changed, 963 insertions(+) > create mode 100644 > MdeModulePkg/Universal/Console/GraphicsOutputDxe/ComponentName.c > create mode 100644 > MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c > create mode 100644 > MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.h > create mode 100644 > MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf > > diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc > index e475dc1..cd3e21e 100644 > --- a/MdeModulePkg/MdeModulePkg.dsc > +++ b/MdeModulePkg/MdeModulePkg.dsc > @@ -290,6 +290,10 @@ > MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf > MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf > MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf > + MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf { > + <LibraryClasses> > + BltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf > + } > MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf > MdeModulePkg/Universal/DebugPortDxe/DebugPortDxe.inf > MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf > diff --git a/MdeModulePkg/Universal/Console/GraphicsOutputDxe/ComponentName.c > b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/ComponentName.c > new file mode 100644 > index 0000000..9f1c79d > --- /dev/null > +++ b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/ComponentName.c > @@ -0,0 +1,190 @@ > +/** @file > + UEFI Component Name(2) protocol implementation for the generic GOP driver. > + > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> > +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BSD > License > +which accompanies this distribution. The full text of the license may be > found at > +http://opensource.org/licenses/bsd-license.php > + > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > + > +**/ > + > +#include <PiDxe.h> > +#include <Library/UefiLib.h> > + > +extern EFI_COMPONENT_NAME_PROTOCOL mGraphicsOutputComponentName; > +extern EFI_COMPONENT_NAME2_PROTOCOL mGraphicsOutputComponentName2; > + > +// > +// Driver name table for GraphicsOutput module. > +// It is shared by the implementation of ComponentName & ComponentName2 > Protocol. > +// > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE > mGraphicsOutputDriverNameTable[] = { > + { > + "eng;en", > + L"Generic Graphics Output Driver" > + }, > + { > + NULL, > + NULL > + } > +}; > + > +/** > + Retrieves a Unicode string that is the user readable name of the driver. > + > + This function retrieves the user readable name of a driver in the form of a > + Unicode string. If the driver specified by This has a user readable name in > + the language specified by Language, then a pointer to the driver name is > + returned in DriverName, and EFI_SUCCESS is returned. If the driver > specified > + by This does not support the language specified by Language, > + then EFI_UNSUPPORTED is returned. > + > + @param This[in] A pointer to the > EFI_COMPONENT_NAME2_PROTOCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + > + @param Language[in] A pointer to a Null-terminated ASCII string > + array indicating the language. This is the > + language of the driver name that the caller > is > + requesting, and it must match one of the > + languages specified in SupportedLanguages. > The > + number of languages supported by a driver is > up > + to the driver writer. Language is specified > + in RFC 4646 or ISO 639-2 language code > format. > + > + @param DriverName[out] A pointer to the Unicode string to return. > + This Unicode string is the name of the > + driver specified by This in the language > + specified by Language. > + > + @retval EFI_SUCCESS The Unicode string for the Driver specified > by > + This and the language specified by Language > was > + returned in DriverName. > + > + @retval EFI_INVALID_PARAMETER Language is NULL. > + > + @retval EFI_INVALID_PARAMETER DriverName is NULL. > + > + @retval EFI_UNSUPPORTED The driver specified by This does not support > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +GraphicsOutputComponentNameGetDriverName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN CHAR8 *Language, > + OUT CHAR16 **DriverName > + ) > +{ > + return LookupUnicodeString2 ( > + Language, > + This->SupportedLanguages, > + mGraphicsOutputDriverNameTable, > + DriverName, > + (BOOLEAN) (This == &mGraphicsOutputComponentName) > + ); > +} > + > +/** > + Retrieves a Unicode string that is the user readable name of the controller > + that is being managed by a driver. > + > + This function retrieves the user readable name of the controller specified > by > + ControllerHandle and ChildHandle in the form of a Unicode string. If the > + driver specified by This has a user readable name in the language > specified by > + Language, then a pointer to the controller name is returned in > ControllerName, > + and EFI_SUCCESS is returned. If the driver specified by This is not > currently > + managing the controller specified by ControllerHandle and ChildHandle, > + then EFI_UNSUPPORTED is returned. If the driver specified by This does not > + support the language specified by Language, then EFI_UNSUPPORTED is > returned. > + > + @param This[in] A pointer to the > EFI_COMPONENT_NAME2_PROTOCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + > + @param ControllerHandle[in] The handle of a controller that the driver > + specified by This is managing. This handle > + specifies the controller whose name is to be > + returned. > + > + @param ChildHandle[in] The handle of the child controller to > retrieve > + the name of. This is an optional parameter > that > + may be NULL. It will be NULL for device > + drivers. It will also be NULL for a bus > drivers > + that wish to retrieve the name of the bus > + controller. It will not be NULL for a bus > + driver that wishes to retrieve the name of a > + child controller. > + > + @param Language[in] A pointer to a Null-terminated ASCII string > + array indicating the language. This is the > + language of the driver name that the caller > is > + requesting, and it must match one of the > + languages specified in SupportedLanguages. > The > + number of languages supported by a driver is > up > + to the driver writer. Language is specified > in > + RFC 4646 or ISO 639-2 language code format. > + > + @param ControllerName[out] A pointer to the Unicode string to return. > + This Unicode string is the name of the > + controller specified by ControllerHandle and > + ChildHandle in the language specified by > + Language from the point of view of the driver > + specified by This. > + > + @retval EFI_SUCCESS The Unicode string for the user readable > name in > + the language specified by Language for the > + driver specified by This was returned in > + DriverName. > + > + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. > + > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid > + EFI_HANDLE. > + > + @retval EFI_INVALID_PARAMETER Language is NULL. > + > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. > + > + @retval EFI_UNSUPPORTED The driver specified by This is not currently > + managing the controller specified by > + ControllerHandle and ChildHandle. > + > + @retval EFI_UNSUPPORTED The driver specified by This does not support > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +GraphicsOutputComponentNameGetControllerName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_HANDLE ChildHandle > OPTIONAL, > + IN CHAR8 *Language, > + OUT CHAR16 **ControllerName > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +// > +// EFI Component Name Protocol > +// > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL > mGraphicsOutputComponentName = { > + GraphicsOutputComponentNameGetDriverName, > + GraphicsOutputComponentNameGetControllerName, > + "eng" > +}; > + > +// > +// EFI Component Name 2 Protocol > +// > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL > mGraphicsOutputComponentName2 = { > + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) > GraphicsOutputComponentNameGetDriverName, > + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) > GraphicsOutputComponentNameGetControllerName, > + "en" > +}; > diff --git > a/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c > b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c > new file mode 100644 > index 0000000..9c6b1b9 > --- /dev/null > +++ b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.c > @@ -0,0 +1,659 @@ > +/** @file > + Implementation for a generic GOP driver. > + > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> > +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BSD > License > +which accompanies this distribution. The full text of the license may be > found at > +http://opensource.org/licenses/bsd-license.php > + > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > + > +**/ > + > +#include "GraphicsOutput.h" > +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) > +}; > + > +/** > + 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 > + ) > +{ > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; > + > + if (ModeNumber >= This->Mode->MaxMode) { > + return EFI_UNSUPPORTED; > + } > + > + Black.Blue = 0; > + Black.Green = 0; > + Black.Red = 0; > + Black.Reserved = 0; > + return BltVideoFill ((VOID *) (UINTN) This->Mode->FrameBufferBase, > This->Mode->Info, &Black, 0, 0, This->Mode->Info->HorizontalResolution, > This->Mode->Info->VerticalResolution); > +} > + > +/** > + 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 > + ) > +{ > + EFI_STATUS Status; > + EFI_TPL Tpl; > + // > + // 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); > + > + switch (BltOperation) { > + case EfiBltVideoToBltBuffer: > + Status = BltVideoToBuffer ( > + (VOID *) (UINTN) This->Mode->FrameBufferBase, > + This->Mode->Info, > + BltBuffer, > + SourceX, > + SourceY, > + DestinationX, > + DestinationY, > + Width, > + Height, > + Delta > + ); > + break; > + > + case EfiBltVideoToVideo: > + Status = BltVideoToVideo ( > + (VOID *) (UINTN) This->Mode->FrameBufferBase, > + This->Mode->Info, > + SourceX, > + SourceY, > + DestinationX, > + DestinationY, > + Width, > + Height > + ); > + break; > + > + case EfiBltVideoFill: > + Status = BltVideoFill ( > + (VOID *) (UINTN) This->Mode->FrameBufferBase, > + This->Mode->Info, > + BltBuffer, > + DestinationX, > + DestinationY, > + Width, > + Height > + ); > + break; > + > + case EfiBltBufferToVideo: > + Status = BltBufferToVideo ( > + (VOID *) (UINTN) This->Mode->FrameBufferBase, > + This->Mode->Info, > + BltBuffer, > + SourceX, > + SourceY, > + DestinationX, > + DestinationY, > + Width, > + Height, > + Delta > + ); > + break; > + > + default: > + Status = EFI_INVALID_PARAMETER; > + break; > + } > + > + gBS->RestoreTPL (Tpl); > + > + return Status; > +} > + > +GRAPHICS_OUTPUT_PRIVATE_DATA mGraphicsOutputInstance = { > + NULL, // GraphicsOutputHandle > + { > + GraphicsOutputQueryMode, > + GraphicsOutputSetMode, > + GraphicsOutputBlt, > + &mGraphicsOutputInstance.GraphicsOutputMode > + }, > + { > + 1, // MaxMode > + 0, // Mode > + NULL, // Info > + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), // SizeOfInfo > + 0, // FrameBufferBase > + 0 // FrameBufferSize > + }, > + NULL, // DevicePath > + NULL, // PciIo > + 0 // PciAttributes > +}; > + > +/** > + 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 (mGraphicsOutputInstance.GraphicsOutputHandle != NULL) { > + 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; > + EFI_PCI_IO_PROTOCOL *PciIo; > + EFI_HANDLE Handle; > + EFI_DEVICE_PATH *PciDevicePath; > + PCI_TYPE00 Pci; > + UINT8 Index; > + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources; > + > + // > + // 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, > + OFFSET_OF (PCI_TYPE00, Hdr.ClassCode), > + sizeof (Pci.Hdr.ClassCode), > + &Pci.Hdr.ClassCode > + ); > + if (!EFI_ERROR (Status)) { > + if (!IS_PCI_DISPLAY (&Pci)) { > + Status = EFI_UNSUPPORTED; > + } else { > + // > + // If it's a video device, check whether the device's frame buffer > size matches the one in HOB. > + // And update the frame buffer base. > + // > + for (Index = 0; Index < MAX_PCI_BAR; Index++) { > + Status = PciIo->GetBarAttributes (PciIo, Index, NULL, (VOID**) > &Resources); > + if (!EFI_ERROR (Status)) { > + DEBUG ((EFI_D_INFO, "[GraphicsOutputDxe]: BAR[%d]: Base = %lx, > Length = %lx\n", 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 >= > mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferSize) { > + mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferBase = > Resources->AddrRangeMin; > + if (!EFI_ERROR (Status)) { > + DEBUG ((EFI_D_INFO, "[GraphicsOutputDxe]: ... matched!\n")); > + break; > + } > + } > + } > + } > + if (Index == MAX_PCI_BAR) { > + Status = EFI_UNSUPPORTED; > + } > + } > + } > + > + if (EFI_ERROR (Status)) { > + goto Error; > + } > + > + // > + // Set attributes > + // > + Status = PciIo->Attributes ( > + PciIo, > + EfiPciIoAttributeOperationGet, > + 0, > + &mGraphicsOutputInstance.PciAttributes > + ); > + if (!EFI_ERROR (Status)) { > + Status = PciIo->Attributes ( > + PciIo, > + EfiPciIoAttributeOperationEnable, > + EFI_PCI_DEVICE_ENABLE, > + NULL > + ); > + } > + > + if (EFI_ERROR (Status)) { > + goto Error; > + } > + > + if ((RemainingDevicePath != NULL) && IsDevicePathEnd > (RemainingDevicePath)) { > + return EFI_SUCCESS; > + } > + > + > + mGraphicsOutputInstance.DevicePath = AppendDevicePathNode (PciDevicePath, > (EFI_DEVICE_PATH_PROTOCOL *) &mGraphicsOutputAdrNode); > + ASSERT (mGraphicsOutputInstance.DevicePath != NULL); > + > + Handle = NULL; > + Status = gBS->InstallMultipleProtocolInterfaces ( > + &mGraphicsOutputInstance.GraphicsOutputHandle, > + &gEfiGraphicsOutputProtocolGuid, > &mGraphicsOutputInstance.GraphicsOutput, > + &gEfiDevicePathProtocolGuid, > mGraphicsOutputInstance.DevicePath, > + NULL > + ); > + > + if (!EFI_ERROR (Status)) { > + Status = gBS->OpenProtocol ( > + Controller, > + &gEfiPciIoProtocolGuid, > + (VOID **) &mGraphicsOutputInstance.PciIo, > + This->DriverBindingHandle, > + mGraphicsOutputInstance.GraphicsOutputHandle, > + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER > + ); > + if (EFI_ERROR (Status)) { > + gBS->UninstallMultipleProtocolInterfaces ( > + mGraphicsOutputInstance.GraphicsOutputHandle, > + &gEfiGraphicsOutputProtocolGuid, > &mGraphicsOutputInstance.GraphicsOutput, > + &gEfiDevicePathProtocolGuid, mGraphicsOutputInstance.DevicePath, > + NULL > + ); > + } > + } > + > + if (EFI_ERROR (Status)) { > + mGraphicsOutputInstance.GraphicsOutputHandle = NULL; > + // > + // Restore original PCI attributes > + // > + PciIo->Attributes ( > + PciIo, > + EfiPciIoAttributeOperationSet, > + mGraphicsOutputInstance.PciAttributes, > + NULL > + ); > + FreePool (mGraphicsOutputInstance.DevicePath); > + } > + > +Error: > + 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; > + > + if (NumberOfChildren == 0) { > + // > + // Restore original PCI attributes > + // > + Status = mGraphicsOutputInstance.PciIo->Attributes ( > + mGraphicsOutputInstance.PciIo, > + EfiPciIoAttributeOperationSet, > + > mGraphicsOutputInstance.PciAttributes, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > + > + // > + // 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); > + ASSERT (ChildHandleBuffer[0] == > mGraphicsOutputInstance.GraphicsOutputHandle); > + Status = gBS->CloseProtocol ( > + Controller, > + &gEfiPciIoProtocolGuid, > + This->DriverBindingHandle, > + mGraphicsOutputInstance.GraphicsOutputHandle > + ); > + ASSERT_EFI_ERROR (Status); > + // > + // Remove the GOP protocol interface from the system > + // > + Status = gBS->UninstallMultipleProtocolInterfaces ( > + mGraphicsOutputInstance.GraphicsOutputHandle, > + &gEfiGraphicsOutputProtocolGuid, > &mGraphicsOutputInstance.GraphicsOutput, > + &gEfiDevicePathProtocolGuid, > mGraphicsOutputInstance.DevicePath, > + NULL > + ); > + if (!EFI_ERROR (Status)) { > + mGraphicsOutputInstance.GraphicsOutputHandle = NULL; > + FreePool (mGraphicsOutputInstance.DevicePath); > + } else { > + Status = gBS->OpenProtocol ( > + Controller, > + &gEfiPciIoProtocolGuid, > + (VOID **) &mGraphicsOutputInstance.PciIo, > + This->DriverBindingHandle, > + mGraphicsOutputInstance.GraphicsOutputHandle, > + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER > + ); > + ASSERT_EFI_ERROR (Status); > + } > + return Status; > +} > + > +EFI_DRIVER_BINDING_PROTOCOL mGraphicsOutputDriverBinding = { > + GraphicsOutputDriverBindingSupported, > + GraphicsOutputDriverBindingStart, > + GraphicsOutputDriverBindingStop, > + 0xffffffff, > + 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; > + EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo; > + > + HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid); > + > + if ((HobStart == NULL) || (GET_GUID_HOB_DATA_SIZE (HobStart) != sizeof > (*GraphicsInfo))) { > + return EFI_NOT_FOUND; > + } > + > + GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *) (GET_GUID_HOB_DATA > (HobStart)); > + > + // > + // Cache in global data > + // > + DEBUG ((EFI_D_INFO, "FrameBuffer = %lx/%lx\n", > GraphicsInfo->FrameBufferBase, GraphicsInfo->FrameBufferSize)); > + mGraphicsOutputInstance.GraphicsOutputMode.Info = > &GraphicsInfo->GraphicsMode; > + mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferBase = > GraphicsInfo->FrameBufferBase; > + mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferSize = > GraphicsInfo->FrameBufferSize; > + > + Status = EfiLibInstallDriverBindingComponentName2 ( > + ImageHandle, > + SystemTable, > + &mGraphicsOutputDriverBinding, > + ImageHandle, > + &mGraphicsOutputComponentName, > + &mGraphicsOutputComponentName2 > + ); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > diff --git > a/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.h > b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.h > new file mode 100644 > index 0000000..68fc010 > --- /dev/null > +++ b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutput.h > @@ -0,0 +1,53 @@ > +/** @file > + Header file for a generic GOP driver. > + > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> > +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BSD > License > +which accompanies this distribution. The full text of the license may be > found at > +http://opensource.org/licenses/bsd-license.php > + > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. > + > + > +**/ > +#ifndef _GRAPHICS_OUTPUT_DXE_H_ > +#define _GRAPHICS_OUTPUT_DXE_H_ > +#include <PiDxe.h> > + > +#include <IndustryStandard/Pci.h> > +#include <IndustryStandard/Acpi.h> > +#include <Guid/GraphicsInfoHob.h> > +#include <Protocol/DriverBinding.h> > +#include <Protocol/PciIo.h> > +#include <Protocol/DevicePath.h> > +#include <Protocol/GraphicsOutput.h> > +#include <Protocol/ComponentName.h> > +#include <Protocol/ComponentName2.h> > + > +#include <Library/BaseLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/HobLib.h> > +#include <Library/DevicePathLib.h> > +#include <Library/BltLib.h> > +#include <Library/DebugLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/UefiLib.h> > + > +#define MAX_PCI_BAR 6 > + > + > +typedef struct { > + EFI_HANDLE GraphicsOutputHandle; > + EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; > + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GraphicsOutputMode; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + EFI_PCI_IO_PROTOCOL *PciIo; > + UINT64 PciAttributes; > +} GRAPHICS_OUTPUT_PRIVATE_DATA; > + > +extern EFI_COMPONENT_NAME_PROTOCOL mGraphicsOutputComponentName; > +extern EFI_COMPONENT_NAME2_PROTOCOL mGraphicsOutputComponentName2; > +#endif > diff --git > a/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf > b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf > new file mode 100644 > index 0000000..f578008 > --- /dev/null > +++ b/MdeModulePkg/Universal/Console/GraphicsOutputDxe/GraphicsOutputDxe.inf > @@ -0,0 +1,57 @@ > +## @file > +# This driver produces GraphicsOutput protocol based on the GraphicsInfo HOB > information. > +# > +# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the BSD > License > +# which accompanies this distribution. The full text of the license may be > found at > +# http://opensource.org/licenses/bsd-license.php > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > +# > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = GraphicsOutputDxe > + FILE_GUID = 20830080-CC28-4169-9836-7F42B8D0C8C9 > + MODULE_TYPE = UEFI_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = InitializeGraphicsOutput > + > +# > +# The following information is for reference only and not required by the > build tools. > +# > +# VALID_ARCHITECTURES = IA32 X64 > +# > + > +[Sources.common] > + GraphicsOutput.h > + GraphicsOutput.c > + ComponentName.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + > +[LibraryClasses] > + UefiDriverEntryPoint > + UefiBootServicesTableLib > + DxeServicesTableLib > + DebugLib > + MemoryAllocationLib > + BaseMemoryLib > + DevicePathLib > + BltLib > + UefiLib > + HobLib > + > +[Guids] > + gEfiGraphicsInfoHobGuid # HOB TO_START > + > +[Protocols] > + gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START > + gEfiDevicePathProtocolGuid # PROTOCOL BY_START > + gEfiPciIoProtocolGuid # PROTOCOL TO_START > -- > 1.9.5.msysgit.1 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel