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