+++ /dev/null
-/** @file\r
- ConsoleOut Routines that speak VGA.\r
-\r
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "FbGop.h"\r
-\r
-EFI_PIXEL_BITMASK mPixelBitMask = {0x0000FF, 0x00FF00, 0xFF0000, 0x000000};\r
-\r
-//\r
-// Save controller attributes during first start\r
-//\r
-UINT64 mOriginalPciAttributes;\r
-BOOLEAN mPciAttributesSaved = FALSE;\r
-FRAME_BUFFER_INFO *mFrameBufferInfo;\r
-\r
-//\r
-// EFI Driver Binding Protocol Instance\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gFbGopDriverBinding = {\r
- FbGopDriverBindingSupported,\r
- FbGopDriverBindingStart,\r
- FbGopDriverBindingStop,\r
- 0x3,\r
- NULL,\r
- NULL\r
-};\r
-\r
-//\r
-// Native resolution in EDID DetailedTiming[0]\r
-//\r
-UINT32 mNativeModeHorizontal;\r
-UINT32 mNativeModeVertical;\r
-\r
-/**\r
- Supported.\r
-\r
- @param This Pointer to driver binding protocol\r
- @param Controller Controller handle to connect\r
- @param RemainingDevicePath A pointer to the remaining portion of a device\r
- path\r
-\r
- @retval EFI_STATUS EFI_SUCCESS:This controller can be managed by this\r
- driver, Otherwise, this controller cannot be\r
- managed by this driver\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- PCI_TYPE00 Pci;\r
- EFI_DEV_PATH *Node;\r
- UINT8 Index;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources;\r
-\r
- //\r
- // Open the IO Abstraction(s) needed to perform the supported test\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // See if this is a PCI Graphics Controller by looking at the Command register and\r
- // Class Code Register\r
- //\r
- Status = PciIo->Pci.Read (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- 0,\r
- sizeof (Pci) / sizeof (UINT32),\r
- &Pci\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- Status = EFI_UNSUPPORTED;\r
- if (IS_PCI_DISPLAY (&Pci) || IS_PCI_OLD_VGA (&Pci)) {\r
- //\r
- // Check if PCI BAR matches the framebuffer base\r
- //\r
- Status = EFI_UNSUPPORTED;\r
- for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
- Status = PciIo->GetBarAttributes (PciIo, Index, NULL, (VOID**) &Resources);\r
- if (!EFI_ERROR (Status)) {\r
- if ((Resources->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) &&\r
- (Resources->Len == (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3)) &&\r
- (Resources->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) &&\r
- (Resources->AddrRangeMin == mFrameBufferInfo->LinearFrameBuffer)) {\r
- DEBUG ((DEBUG_INFO, "Found matched framebuffer PCI BAR !\n"));\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // If this is a graphics controller,\r
- // go further check RemainingDevicePath\r
- //\r
- if (RemainingDevicePath != NULL) {\r
- Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
- //\r
- // Check if RemainingDevicePath is the End of Device Path Node,\r
- // if yes, return EFI_SUCCESS\r
- //\r
- if (!IsDevicePathEnd (Node)) {\r
- //\r
- // Verify RemainingDevicePath\r
- //\r
- if (Node->DevPath.Type != ACPI_DEVICE_PATH ||\r
- Node->DevPath.SubType != ACPI_ADR_DP ||\r
- DevicePathNodeLength(&Node->DevPath) < sizeof(ACPI_ADR_DEVICE_PATH)) {\r
- Status = EFI_UNSUPPORTED;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
-Done:\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Install Graphics Output Protocol onto VGA device handles.\r
-\r
- @param This Pointer to driver binding protocol\r
- @param Controller Controller handle to connect\r
- @param RemainingDevicePath A pointer to the remaining portion of a device\r
- path\r
-\r
- @return EFI_STATUS\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Supports;\r
-\r
- DEBUG ((DEBUG_INFO, "GOP START\n"));\r
-\r
- //\r
- // Initialize local variables\r
- //\r
- PciIo = NULL;\r
- ParentDevicePath = NULL;\r
-\r
- //\r
- // Prepare for status code\r
- //\r
- Status = gBS->HandleProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ParentDevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Open the IO Abstraction(s) needed\r
- //\r
- Status = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
- );\r
- if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Save original PCI attributes\r
- //\r
- if (!mPciAttributesSaved) {\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationGet,\r
- 0,\r
- &mOriginalPciAttributes\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- mPciAttributesSaved = TRUE;\r
- }\r
-\r
- //\r
- // Get supported PCI attributes\r
- //\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationSupported,\r
- 0,\r
- &Supports\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
- if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE,\r
- ParentDevicePath\r
- );\r
- //\r
- // Enable the device and make sure VGA cycles are being forwarded to this VGA device\r
- //\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_DEVICE_ENABLE,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_RESOURCE_CONFLICT,\r
- ParentDevicePath\r
- );\r
- goto Done;\r
- }\r
-\r
- if (RemainingDevicePath != NULL) {\r
- if (IsDevicePathEnd (RemainingDevicePath)) {\r
- //\r
- // If RemainingDevicePath is the End of Device Path Node,\r
- // don't create any child device and return EFI_SUCCESS\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
- }\r
-\r
- //\r
- // Create child handle and install GraphicsOutputProtocol on it\r
- //\r
- Status = FbGopChildHandleInstall (\r
- This,\r
- Controller,\r
- PciIo,\r
- NULL,\r
- ParentDevicePath,\r
- RemainingDevicePath\r
- );\r
-\r
-Done:\r
- if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE,\r
- ParentDevicePath\r
- );\r
-\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_PROGRESS_CODE,\r
- EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED,\r
- ParentDevicePath\r
- );\r
- if (!HasChildHandle (Controller)) {\r
- if (mPciAttributesSaved) {\r
- //\r
- // Restore original PCI attributes\r
- //\r
- PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationSet,\r
- mOriginalPciAttributes,\r
- NULL\r
- );\r
- }\r
- }\r
- //\r
- // Release PCI I/O Protocols on the controller handle.\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Stop.\r
-\r
- @param This Pointer to driver binding protocol\r
- @param Controller Controller handle to connect\r
- @param NumberOfChildren Number of children handle created by this driver\r
- @param ChildHandleBuffer Buffer containing child handle created\r
-\r
- @retval EFI_SUCCESS Driver disconnected successfully from controller\r
- @retval EFI_UNSUPPORTED Cannot find FB_VIDEO_DEV structure\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN AllChildrenStopped;\r
- UINTN Index;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- AllChildrenStopped = TRUE;\r
-\r
- if (NumberOfChildren == 0) {\r
- //\r
- // Close PCI I/O protocol on the controller handle\r
- //\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-\r
- for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- FbGopChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]);\r
-\r
- if (EFI_ERROR (Status)) {\r
- AllChildrenStopped = FALSE;\r
- }\r
- }\r
-\r
- if (!AllChildrenStopped) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- if (!HasChildHandle (Controller)) {\r
- if (mPciAttributesSaved) {\r
- Status = gBS->HandleProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Restore original PCI attributes\r
- //\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationSet,\r
- mOriginalPciAttributes,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- }\r
-\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Install child handles if the Handle supports MBR format.\r
-\r
- @param This Calling context.\r
- @param ParentHandle Parent Handle\r
- @param ParentPciIo Parent PciIo interface\r
- @param ParentLegacyBios Parent LegacyBios interface\r
- @param ParentDevicePath Parent Device Path\r
- @param RemainingDevicePath Remaining Device Path\r
-\r
- @retval EFI_SUCCESS If a child handle was added\r
- @retval other A child handle was not added\r
-\r
-**/\r
-EFI_STATUS\r
-FbGopChildHandleInstall (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE ParentHandle,\r
- IN EFI_PCI_IO_PROTOCOL *ParentPciIo,\r
- IN VOID *ParentLegacyBios,\r
- IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FB_VIDEO_DEV *FbGopPrivate;\r
- PCI_TYPE00 Pci;\r
- ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
-\r
- //\r
- // Allocate the private device structure for video device\r
- //\r
- FbGopPrivate = (FB_VIDEO_DEV *) AllocateZeroPool (\r
- sizeof (FB_VIDEO_DEV)\r
- );\r
- if (NULL == FbGopPrivate) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- //\r
- // See if this is a VGA compatible controller or not\r
- //\r
- Status = ParentPciIo->Pci.Read (\r
- ParentPciIo,\r
- EfiPciIoWidthUint32,\r
- 0,\r
- sizeof (Pci) / sizeof (UINT32),\r
- &Pci\r
- );\r
- if (EFI_ERROR (Status)) {\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,\r
- ParentDevicePath\r
- );\r
- goto Done;\r
- }\r
-\r
- //\r
- // Initialize the child private structure\r
- //\r
- FbGopPrivate->Signature = FB_VIDEO_DEV_SIGNATURE;\r
-\r
- //\r
- // Fill in Graphics Output specific mode structures\r
- //\r
- FbGopPrivate->ModeData = NULL;\r
-\r
- FbGopPrivate->VbeFrameBuffer = NULL;\r
-\r
- FbGopPrivate->EdidDiscovered.SizeOfEdid = 0;\r
- FbGopPrivate->EdidDiscovered.Edid = NULL;\r
- FbGopPrivate->EdidActive.SizeOfEdid = 0;\r
- FbGopPrivate->EdidActive.Edid = NULL;\r
-\r
- //\r
- // Fill in the Graphics Output Protocol\r
- //\r
- FbGopPrivate->GraphicsOutput.QueryMode = FbGopGraphicsOutputQueryMode;\r
- FbGopPrivate->GraphicsOutput.SetMode = FbGopGraphicsOutputSetMode;\r
-\r
-\r
- //\r
- // Allocate buffer for Graphics Output Protocol mode information\r
- //\r
- FbGopPrivate->GraphicsOutput.Mode = (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *) AllocatePool (\r
- sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE)\r
- );\r
- if (NULL == FbGopPrivate->GraphicsOutput.Mode) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- FbGopPrivate->GraphicsOutput.Mode->Info = (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) AllocatePool (\r
- sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)\r
- );\r
- if (NULL == FbGopPrivate->GraphicsOutput.Mode->Info) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Set Gop Device Path, here RemainingDevicePath will not be one End of Device Path Node.\r
- //\r
- if ((RemainingDevicePath == NULL) || (!IsDevicePathEnd (RemainingDevicePath))) {\r
- if (RemainingDevicePath == NULL) {\r
- ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
- AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
- AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
- AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
- SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
-\r
- FbGopPrivate->GopDevicePath = AppendDevicePathNode (\r
- ParentDevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
- );\r
- } else {\r
- FbGopPrivate->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
- }\r
-\r
- //\r
- // Creat child handle and device path protocol firstly\r
- //\r
- FbGopPrivate->Handle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &FbGopPrivate->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- FbGopPrivate->GopDevicePath,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
-\r
- //\r
- // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally\r
- //\r
- FbGopPrivate->PciIo = ParentPciIo;\r
-\r
- //\r
- // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output\r
- //\r
- Status = FbGopCheckForVbe (FbGopPrivate);\r
- DEBUG ((DEBUG_INFO, "FbGopCheckForVbe - %r\n", Status));\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_UNSUPPORTED;\r
- //goto Done;\r
- }\r
-\r
- //\r
- // Creat child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &FbGopPrivate->Handle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- &FbGopPrivate->GraphicsOutput,\r
- &gEfiEdidDiscoveredProtocolGuid,\r
- &FbGopPrivate->EdidDiscovered,\r
- &gEfiEdidActiveProtocolGuid,\r
- &FbGopPrivate->EdidActive,\r
- NULL\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Open the Parent Handle for the child\r
- //\r
- Status = gBS->OpenProtocol (\r
- ParentHandle,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &FbGopPrivate->PciIo,\r
- This->DriverBindingHandle,\r
- FbGopPrivate->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
- }\r
-\r
-Done:\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Free private data structure\r
- //\r
- FbGopDeviceReleaseResource (FbGopPrivate);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Deregister an video child handle and free resources.\r
-\r
- @param This Protocol instance pointer.\r
- @param Controller Video controller handle\r
- @param Handle Video child handle\r
-\r
- @return EFI_STATUS\r
-\r
-**/\r
-EFI_STATUS\r
-FbGopChildHandleUninstall (\r
- EFI_DRIVER_BINDING_PROTOCOL *This,\r
- EFI_HANDLE Controller,\r
- EFI_HANDLE Handle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
- FB_VIDEO_DEV *FbGopPrivate;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
-\r
- FbGopPrivate = NULL;\r
- GraphicsOutput = NULL;\r
- PciIo = NULL;\r
- Status = EFI_UNSUPPORTED;\r
-\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- (VOID **) &GraphicsOutput,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- FbGopPrivate = FB_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);\r
- }\r
-\r
- if (FbGopPrivate == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Close PCI I/O protocol that opened by child handle\r
- //\r
- Status = gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Handle\r
- );\r
-\r
- //\r
- // Uninstall protocols on child handle\r
- //\r
- Status = gBS->UninstallMultipleProtocolInterfaces (\r
- FbGopPrivate->Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- FbGopPrivate->GopDevicePath,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- &FbGopPrivate->GraphicsOutput,\r
- NULL\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- gBS->OpenProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- This->DriverBindingHandle,\r
- Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
- return Status;\r
- }\r
-\r
- //\r
- // Release all allocated resources\r
- //\r
- FbGopDeviceReleaseResource (FbGopPrivate);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Release resource for bios video instance.\r
-\r
- @param FbGopPrivate Video child device private data structure\r
-\r
-**/\r
-VOID\r
-FbGopDeviceReleaseResource (\r
- FB_VIDEO_DEV *FbGopPrivate\r
- )\r
-{\r
- if (FbGopPrivate == NULL) {\r
- return ;\r
- }\r
-\r
- //\r
- // Release all the resources occupied by the FB_VIDEO_DEV\r
- //\r
-\r
- //\r
- // Free VBE Frame Buffer\r
- //\r
- if (FbGopPrivate->VbeFrameBuffer != NULL) {\r
- FreePool (FbGopPrivate->VbeFrameBuffer);\r
- }\r
-\r
- //\r
- // Free mode data\r
- //\r
- if (FbGopPrivate->ModeData != NULL) {\r
- FreePool (FbGopPrivate->ModeData);\r
- }\r
-\r
- //\r
- // Free graphics output protocol occupied resource\r
- //\r
- if (FbGopPrivate->GraphicsOutput.Mode != NULL) {\r
- if (FbGopPrivate->GraphicsOutput.Mode->Info != NULL) {\r
- FreePool (FbGopPrivate->GraphicsOutput.Mode->Info);\r
- FbGopPrivate->GraphicsOutput.Mode->Info = NULL;\r
- }\r
- FreePool (FbGopPrivate->GraphicsOutput.Mode);\r
- FbGopPrivate->GraphicsOutput.Mode = NULL;\r
- }\r
-\r
- if (FbGopPrivate->GopDevicePath!= NULL) {\r
- FreePool (FbGopPrivate->GopDevicePath);\r
- }\r
-\r
- FreePool (FbGopPrivate);\r
-\r
- return ;\r
-}\r
-\r
-\r
-\r
-/**\r
- Check if all video child handles have been uninstalled.\r
-\r
- @param Controller Video controller handle\r
-\r
- @return TRUE Child handles exist.\r
- @return FALSE All video child handles have been uninstalled.\r
-\r
-**/\r
-BOOLEAN\r
-HasChildHandle (\r
- IN EFI_HANDLE Controller\r
- )\r
-{\r
- UINTN Index;\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
- UINTN EntryCount;\r
- BOOLEAN HasChild;\r
-\r
- EntryCount = 0;\r
- HasChild = FALSE;\r
- gBS->OpenProtocolInformation (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- &OpenInfoBuffer,\r
- &EntryCount\r
- );\r
- for (Index = 0; Index < EntryCount; Index++) {\r
- if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
- HasChild = TRUE;\r
- }\r
- }\r
-\r
- return HasChild;\r
-}\r
-\r
-/**\r
- Check for VBE device.\r
-\r
- @param FbGopPrivate Pointer to FB_VIDEO_DEV structure\r
-\r
- @retval EFI_SUCCESS VBE device found\r
-\r
-**/\r
-EFI_STATUS\r
-FbGopCheckForVbe (\r
- IN OUT FB_VIDEO_DEV *FbGopPrivate\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FB_VIDEO_MODE_DATA *ModeBuffer;\r
- FB_VIDEO_MODE_DATA *CurrentModeData;\r
- UINTN ModeNumber;\r
- UINTN BitsPerPixel;\r
- UINTN BytesPerScanLine;\r
- UINT32 HorizontalResolution;\r
- UINT32 VerticalResolution;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;\r
- FRAME_BUFFER_INFO *FbInfo;\r
-\r
- Status = EFI_SUCCESS;\r
-\r
- FbInfo = mFrameBufferInfo;\r
-\r
- //\r
- // Add mode to the list of available modes\r
- //\r
- VbeFrameBuffer = NULL;\r
- ModeBuffer = NULL;\r
-\r
- ModeNumber = 1;\r
- BitsPerPixel = FbInfo->BitsPerPixel;\r
- HorizontalResolution = FbInfo->HorizontalResolution;\r
- VerticalResolution = FbInfo->VerticalResolution;\r
- BytesPerScanLine = FbInfo->BytesPerScanLine;\r
-\r
- ModeBuffer = (FB_VIDEO_MODE_DATA *) AllocatePool (\r
- ModeNumber * sizeof (FB_VIDEO_MODE_DATA)\r
- );\r
- if (NULL == ModeBuffer) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- VbeFrameBuffer =\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocatePool (\r
- BytesPerScanLine * VerticalResolution\r
- );\r
- if (NULL == VbeFrameBuffer) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- if (FbGopPrivate->ModeData != NULL) {\r
- FreePool (FbGopPrivate->ModeData);\r
- }\r
-\r
- if (FbGopPrivate->VbeFrameBuffer != NULL) {\r
- FreePool (FbGopPrivate->VbeFrameBuffer);\r
- }\r
-\r
- CurrentModeData = &ModeBuffer[ModeNumber - 1];\r
- CurrentModeData->BytesPerScanLine = (UINT16)BytesPerScanLine;\r
-\r
- CurrentModeData->Red = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Red);\r
- CurrentModeData->Blue = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Blue);\r
- CurrentModeData->Green = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Green);\r
- CurrentModeData->Reserved = *(FB_VIDEO_COLOR_PLACEMENT *)&(FbInfo->Reserved);\r
-\r
- CurrentModeData->BitsPerPixel = (UINT32)BitsPerPixel;\r
- CurrentModeData->HorizontalResolution = HorizontalResolution;\r
- CurrentModeData->VerticalResolution = VerticalResolution;\r
- CurrentModeData->FrameBufferSize = CurrentModeData->BytesPerScanLine * CurrentModeData->VerticalResolution;\r
- CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN) FbInfo->LinearFrameBuffer;\r
- CurrentModeData->VbeModeNumber = 0;\r
- CurrentModeData->ColorDepth = 32;\r
- CurrentModeData->RefreshRate = 60;\r
-\r
- CurrentModeData->PixelFormat = PixelBitMask;\r
- if ((CurrentModeData->BitsPerPixel == 32) &&\r
- (CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)) {\r
- if ((CurrentModeData->Red.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Blue.Position == 16)) {\r
- CurrentModeData->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
- } else if ((CurrentModeData->Blue.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Red.Position == 16)) {\r
- CurrentModeData->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
- }\r
- }\r
-\r
- CopyMem (&(CurrentModeData->PixelBitMask), &mPixelBitMask, sizeof (EFI_PIXEL_BITMASK));\r
-\r
- FbGopPrivate->ModeData = ModeBuffer;\r
- FbGopPrivate->VbeFrameBuffer = VbeFrameBuffer;\r
-\r
- //\r
- // Assign Gop's Blt function\r
- //\r
- FbGopPrivate->GraphicsOutput.Blt = FbGopGraphicsOutputVbeBlt;\r
-\r
- FbGopPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
- FbGopPrivate->GraphicsOutput.Mode->Mode = 0;\r
- FbGopPrivate->GraphicsOutput.Mode->Info->Version = 0;\r
- FbGopPrivate->GraphicsOutput.Mode->Info->HorizontalResolution = HorizontalResolution;\r
- FbGopPrivate->GraphicsOutput.Mode->Info->VerticalResolution = VerticalResolution;\r
- FbGopPrivate->GraphicsOutput.Mode->Info->PixelFormat = CurrentModeData->PixelFormat;\r
- CopyMem (&(FbGopPrivate->GraphicsOutput.Mode->Info->PixelInformation), &mPixelBitMask, sizeof (EFI_PIXEL_BITMASK));\r
- FbGopPrivate->GraphicsOutput.Mode->Info->PixelsPerScanLine = (UINT32)(BytesPerScanLine * 8 / BitsPerPixel);\r
- FbGopPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- FbGopPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) CurrentModeData->LinearFrameBuffer;\r
- FbGopPrivate->GraphicsOutput.Mode->FrameBufferSize = CurrentModeData->FrameBufferSize;\r
-\r
- //\r
- // Find the best mode to initialize\r
- //\r
-\r
-Done:\r
- //\r
- // If there was an error, then free the mode structure\r
- //\r
- if (EFI_ERROR (Status)) {\r
-\r
- if (VbeFrameBuffer != NULL) {\r
- FreePool (VbeFrameBuffer);\r
- }\r
-\r
- if (ModeBuffer != NULL) {\r
- FreePool (ModeBuffer);\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-//\r
-// Graphics Output Protocol Member Functions for VESA BIOS Extensions\r
-//\r
-\r
-/**\r
- Graphics Output protocol interface to get video mode.\r
-\r
- @param This Protocol instance pointer.\r
- @param ModeNumber The mode number to return information on.\r
- @param SizeOfInfo A pointer to the size, in bytes, of the Info\r
- buffer.\r
- @param Info Caller allocated buffer that returns information\r
- about ModeNumber.\r
-\r
- @retval EFI_SUCCESS Mode information returned.\r
- @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the\r
- video mode.\r
- @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()\r
- @retval EFI_INVALID_PARAMETER One of the input args was NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopGraphicsOutputQueryMode (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN UINT32 ModeNumber,\r
- OUT UINTN *SizeOfInfo,\r
- OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
- )\r
-{\r
- FB_VIDEO_DEV *FbGopPrivate;\r
- FB_VIDEO_MODE_DATA *ModeData;\r
-\r
- FbGopPrivate = FB_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
-\r
- if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- *Info = (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) AllocatePool (\r
- sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)\r
- );\r
- if (NULL == *Info) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
-\r
- ModeData = &FbGopPrivate->ModeData[ModeNumber];\r
- (*Info)->Version = 0;\r
- (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
- (*Info)->VerticalResolution = ModeData->VerticalResolution;\r
- (*Info)->PixelFormat = ModeData->PixelFormat;\r
- CopyMem (&((*Info)->PixelInformation), &(ModeData->PixelBitMask), sizeof(ModeData->PixelBitMask));\r
-\r
- (*Info)->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Graphics Output protocol interface to set video mode.\r
-\r
- @param This Protocol instance pointer.\r
- @param ModeNumber The mode number to be set.\r
-\r
- @retval EFI_SUCCESS Graphics mode was changed.\r
- @retval EFI_DEVICE_ERROR The device had an error and could not complete the\r
- request.\r
- @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopGraphicsOutputSetMode (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,\r
- IN UINT32 ModeNumber\r
- )\r
-{\r
- FB_VIDEO_DEV *FbGopPrivate;\r
- FB_VIDEO_MODE_DATA *ModeData;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- FbGopPrivate = FB_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
-\r
- ModeData = &FbGopPrivate->ModeData[ModeNumber];\r
-\r
- if (ModeNumber >= This->Mode->MaxMode) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (ModeNumber == This->Mode->Mode) {\r
- //\r
- // Clear screen to black\r
- //\r
- ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- FbGopGraphicsOutputVbeBlt (\r
- This,\r
- &Background,\r
- EfiBltVideoFill,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- ModeData->HorizontalResolution,\r
- ModeData->VerticalResolution,\r
- 0\r
- );\r
- return EFI_SUCCESS;\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
-}\r
-\r
-/**\r
- Update physical frame buffer, copy 4 bytes block, then copy remaining bytes.\r
-\r
- @param PciIo The pointer of EFI_PCI_IO_PROTOCOL\r
- @param VbeBuffer The data to transfer to screen\r
- @param MemAddress Physical frame buffer base address\r
- @param DestinationX The X coordinate of the destination for BltOperation\r
- @param DestinationY The Y coordinate of the destination for BltOperation\r
- @param TotalBytes The total bytes of copy\r
- @param VbePixelWidth Bytes per pixel\r
- @param BytesPerScanLine Bytes per scan line\r
-\r
-**/\r
-VOID\r
-CopyVideoBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT8 *VbeBuffer,\r
- IN VOID *MemAddress,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN TotalBytes,\r
- IN UINT32 VbePixelWidth,\r
- IN UINTN BytesPerScanLine\r
- )\r
-{\r
- UINTN FrameBufferAddr;\r
- UINTN CopyBlockNum;\r
- UINTN RemainingBytes;\r
- UINTN UnalignedBytes;\r
- EFI_STATUS Status;\r
-\r
- FrameBufferAddr = (UINTN) MemAddress + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth;\r
-\r
- //\r
- // If TotalBytes is less than 4 bytes, only start byte copy.\r
- //\r
- if (TotalBytes < 4) {\r
- Status = PciIo->Mem.Write (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) FrameBufferAddr,\r
- TotalBytes,\r
- VbeBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- return;\r
- }\r
-\r
- //\r
- // If VbeBuffer is not 4-byte aligned, start byte copy.\r
- //\r
- UnalignedBytes = (4 - ((UINTN) VbeBuffer & 0x3)) & 0x3;\r
-\r
- if (UnalignedBytes != 0) {\r
- Status = PciIo->Mem.Write (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) FrameBufferAddr,\r
- UnalignedBytes,\r
- VbeBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- FrameBufferAddr += UnalignedBytes;\r
- VbeBuffer += UnalignedBytes;\r
- }\r
-\r
- //\r
- // Calculate 4-byte block count and remaining bytes.\r
- //\r
- CopyBlockNum = (TotalBytes - UnalignedBytes) >> 2;\r
- RemainingBytes = (TotalBytes - UnalignedBytes) & 3;\r
-\r
- //\r
- // Copy 4-byte block and remaining bytes to physical frame buffer.\r
- //\r
- if (CopyBlockNum != 0) {\r
- Status = PciIo->Mem.Write (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) FrameBufferAddr,\r
- CopyBlockNum,\r
- VbeBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- if (RemainingBytes != 0) {\r
- FrameBufferAddr += (CopyBlockNum << 2);\r
- VbeBuffer += (CopyBlockNum << 2);\r
- Status = PciIo->Mem.Write (\r
- PciIo,\r
- EfiPciIoWidthUint8,\r
- EFI_PCI_IO_PASS_THROUGH_BAR,\r
- (UINT64) FrameBufferAddr,\r
- RemainingBytes,\r
- VbeBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-}\r
-\r
-/**\r
- Worker function to block transfer for VBE device.\r
-\r
- @param FbGopPrivate Instance of FB_VIDEO_DEV\r
- @param BltBuffer The data to transfer to screen\r
- @param BltOperation The operation to perform\r
- @param SourceX The X coordinate of the source for BltOperation\r
- @param SourceY The Y coordinate of the source for BltOperation\r
- @param DestinationX The X coordinate of the destination for\r
- BltOperation\r
- @param DestinationY The Y coordinate of the destination for\r
- BltOperation\r
- @param Width The width of a rectangle in the blt rectangle in\r
- pixels\r
- @param Height The height of a rectangle in the blt rectangle in\r
- pixels\r
- @param Delta Not used for EfiBltVideoFill and\r
- EfiBltVideoToVideo operation. If a Delta of 0 is\r
- used, the entire BltBuffer will be operated on. If\r
- a subrectangle of the BltBuffer is used, then\r
- Delta represents the number of bytes in a row of\r
- the BltBuffer.\r
- @param Mode Mode data.\r
-\r
- @retval EFI_INVALID_PARAMETER Invalid parameter passed in\r
- @retval EFI_SUCCESS Blt operation success\r
-\r
-**/\r
-EFI_STATUS\r
-FbGopVbeBltWorker (\r
- IN FB_VIDEO_DEV *FbGopPrivate,\r
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
- IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta,\r
- IN FB_VIDEO_MODE_DATA *Mode\r
- )\r
-{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_TPL OriginalTPL;\r
- UINTN DstY;\r
- UINTN SrcY;\r
- UINTN DstX;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;\r
- VOID *MemAddress;\r
- EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;\r
- UINTN BytesPerScanLine;\r
- UINTN Index;\r
- UINT8 *VbeBuffer;\r
- UINT8 *VbeBuffer1;\r
- UINT8 *BltUint8;\r
- UINT32 VbePixelWidth;\r
- UINT32 Pixel;\r
- UINTN TotalBytes;\r
-\r
- PciIo = FbGopPrivate->PciIo;\r
-\r
- VbeFrameBuffer = FbGopPrivate->VbeFrameBuffer;\r
- MemAddress = Mode->LinearFrameBuffer;\r
- BytesPerScanLine = Mode->BytesPerScanLine;\r
- VbePixelWidth = Mode->BitsPerPixel / 8;\r
- BltUint8 = (UINT8 *) BltBuffer;\r
- TotalBytes = Width * VbePixelWidth;\r
-\r
- if (((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Width == 0 || Height == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // We need to fill the Virtual Screen buffer with the blt data.\r
- // The virtual screen is upside down, as the first row is the bottom row of\r
- // the image.\r
- //\r
- if (BltOperation == EfiBltVideoToBltBuffer) {\r
- //\r
- // Video to BltBuffer: Source is Video, destination is BltBuffer\r
- //\r
- if (SourceY + Height > Mode->VerticalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (SourceX + Width > Mode->HorizontalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- } else {\r
- //\r
- // BltBuffer to Video: Source is BltBuffer, destination is Video\r
- //\r
- if (DestinationY + Height > Mode->VerticalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (DestinationX + Width > Mode->HorizontalResolution) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // If Delta is zero, then the entire BltBuffer is being used, so Delta\r
- // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,\r
- // the number of bytes in each row can be computed.\r
- //\r
- if (Delta == 0) {\r
- Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);\r
- }\r
- //\r
- // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
- // We would not want a timer based event (Cursor, ...) to come in while we are\r
- // doing this operation.\r
- //\r
- OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
- switch (BltOperation) {\r
- case EfiBltVideoToBltBuffer:\r
- for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {\r
- Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- //\r
- // Shuffle the packed bytes in the hardware buffer to match EFI_GRAPHICS_OUTPUT_BLT_PIXEL\r
- //\r
- VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth));\r
- for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
- Pixel = VbeBuffer[0] | VbeBuffer[1] << 8 | VbeBuffer[2] << 16 | VbeBuffer[3] << 24;\r
- Blt->Red = (UINT8) ((Pixel >> Mode->Red.Position) & Mode->Red.Mask);\r
- Blt->Blue = (UINT8) ((Pixel >> Mode->Blue.Position) & Mode->Blue.Mask);\r
- Blt->Green = (UINT8) ((Pixel >> Mode->Green.Position) & Mode->Green.Mask);\r
- Blt->Reserved = 0;\r
- Blt++;\r
- VbeBuffer += VbePixelWidth;\r
- }\r
-\r
- }\r
- break;\r
-\r
- case EfiBltVideoToVideo:\r
- for (Index = 0; Index < Height; Index++) {\r
- if (DestinationY <= SourceY) {\r
- SrcY = SourceY + Index;\r
- DstY = DestinationY + Index;\r
- } else {\r
- SrcY = SourceY + Height - Index - 1;\r
- DstY = DestinationY + Height - Index - 1;\r
- }\r
-\r
- VbeBuffer = ((UINT8 *) VbeFrameBuffer + DstY * BytesPerScanLine + DestinationX * VbePixelWidth);\r
- VbeBuffer1 = ((UINT8 *) VbeFrameBuffer + SrcY * BytesPerScanLine + SourceX * VbePixelWidth);\r
-\r
- gBS->CopyMem (\r
- VbeBuffer,\r
- VbeBuffer1,\r
- TotalBytes\r
- );\r
-\r
- //\r
- // Update physical frame buffer.\r
- //\r
- CopyVideoBuffer (\r
- PciIo,\r
- VbeBuffer,\r
- MemAddress,\r
- DestinationX,\r
- DstY,\r
- TotalBytes,\r
- VbePixelWidth,\r
- BytesPerScanLine\r
- );\r
- }\r
- break;\r
-\r
- case EfiBltVideoFill:\r
- VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);\r
- Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltUint8;\r
- //\r
- // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer\r
- //\r
- Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
- (\r
- (Blt->Green & Mode->Green.Mask) <<\r
- Mode->Green.Position\r
- ) |\r
- ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);\r
-\r
- for (Index = 0; Index < Width; Index++) {\r
- gBS->CopyMem (\r
- VbeBuffer,\r
- &Pixel,\r
- VbePixelWidth\r
- );\r
- VbeBuffer += VbePixelWidth;\r
- }\r
-\r
- VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);\r
- for (DstY = DestinationY + 1; DstY < (Height + DestinationY); DstY++) {\r
- gBS->CopyMem (\r
- (VOID *) ((UINTN) VbeFrameBuffer + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),\r
- VbeBuffer,\r
- TotalBytes\r
- );\r
- }\r
-\r
- for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {\r
- //\r
- // Update physical frame buffer.\r
- //\r
- CopyVideoBuffer (\r
- PciIo,\r
- VbeBuffer,\r
- MemAddress,\r
- DestinationX,\r
- DstY,\r
- TotalBytes,\r
- VbePixelWidth,\r
- BytesPerScanLine\r
- );\r
- }\r
- break;\r
-\r
- case EfiBltBufferToVideo:\r
- for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {\r
- Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));\r
- VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));\r
- for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {\r
- //\r
- // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer\r
- //\r
- Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |\r
- ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) |\r
- ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);\r
- gBS->CopyMem (\r
- VbeBuffer,\r
- &Pixel,\r
- VbePixelWidth\r
- );\r
- Blt++;\r
- VbeBuffer += VbePixelWidth;\r
- }\r
-\r
- VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));\r
-\r
- //\r
- // Update physical frame buffer.\r
- //\r
- CopyVideoBuffer (\r
- PciIo,\r
- VbeBuffer,\r
- MemAddress,\r
- DestinationX,\r
- DstY,\r
- TotalBytes,\r
- VbePixelWidth,\r
- BytesPerScanLine\r
- );\r
- }\r
- break;\r
-\r
- default: ;\r
- }\r
-\r
- gBS->RestoreTPL (OriginalTPL);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Graphics Output protocol instance to block transfer for VBE device.\r
-\r
- @param This Pointer to Graphics Output protocol instance\r
- @param BltBuffer The data to transfer to screen\r
- @param BltOperation The operation to perform\r
- @param SourceX The X coordinate of the source for BltOperation\r
- @param SourceY The Y coordinate of the source for BltOperation\r
- @param DestinationX The X coordinate of the destination for\r
- BltOperation\r
- @param DestinationY The Y coordinate of the destination for\r
- BltOperation\r
- @param Width The width of a rectangle in the blt rectangle in\r
- pixels\r
- @param Height The height of a rectangle in the blt rectangle in\r
- pixels\r
- @param Delta Not used for EfiBltVideoFill and\r
- EfiBltVideoToVideo operation. If a Delta of 0 is\r
- used, the entire BltBuffer will be operated on. If\r
- a subrectangle of the BltBuffer is used, then\r
- Delta represents the number of bytes in a row of\r
- the BltBuffer.\r
-\r
- @retval EFI_INVALID_PARAMETER Invalid parameter passed in\r
- @retval EFI_SUCCESS Blt operation success\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopGraphicsOutputVbeBlt (\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
- IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL\r
- IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,\r
- IN UINTN SourceX,\r
- IN UINTN SourceY,\r
- IN UINTN DestinationX,\r
- IN UINTN DestinationY,\r
- IN UINTN Width,\r
- IN UINTN Height,\r
- IN UINTN Delta\r
- )\r
-{\r
- FB_VIDEO_DEV *FbGopPrivate;\r
- FB_VIDEO_MODE_DATA *Mode;\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- FbGopPrivate = FB_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);\r
- Mode = &FbGopPrivate->ModeData[This->Mode->Mode];\r
-\r
- return FbGopVbeBltWorker (\r
- FbGopPrivate,\r
- BltBuffer,\r
- BltOperation,\r
- SourceX,\r
- SourceY,\r
- DestinationX,\r
- DestinationY,\r
- Width,\r
- Height,\r
- Delta,\r
- Mode\r
- );\r
-}\r
-\r
-\r
-/**\r
- The user Entry Point for module UefiFbGop. The user code starts with this function.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
- @param[in] SystemTable A pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval other Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FbGopEntryPoint(\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HOB_GUID_TYPE *GuidHob;\r
-\r
- //\r
- // Find the frame buffer information guid hob\r
- //\r
- GuidHob = GetFirstGuidHob (&gUefiFrameBufferInfoGuid);\r
- if (GuidHob != NULL) {\r
- mFrameBufferInfo = (FRAME_BUFFER_INFO *)GET_GUID_HOB_DATA (GuidHob);\r
-\r
- //\r
- // Install driver model protocol(s).\r
- //\r
- Status = EfiLibInstallDriverBindingComponentName2 (\r
- ImageHandle,\r
- SystemTable,\r
- &gFbGopDriverBinding,\r
- ImageHandle,\r
- &gFbGopComponentName,\r
- &gFbGopComponentName2\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- } else {\r
- DEBUG ((DEBUG_ERROR, "No FrameBuffer information from coreboot. NO GOP driver !!!\n"));\r
- Status = EFI_ABORTED;\r
- }\r
- return Status;\r
-}\r
-\r