| /** @file | |
| Implements EFI Driver Binding Protocol and VGA Mini Port Protocol for VGA Mini Port Driver. | |
| Copyright (c) 2006 - 2018, 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 "VgaMiniPort.h" | |
| // | |
| // EFI Driver Binding Protocol Instance | |
| // | |
| // This driver has a version value of 0x00000000. This is the | |
| // lowest possible priority for a driver. This is done on purpose to help | |
| // the developers of UGA drivers. This driver can bind if no UGA driver | |
| // is present, so a console is available. Then, when a UGA driver is loaded | |
| // this driver can be disconnected, and the UGA driver can be connected. | |
| // As long as the UGA driver has a version value greater than 0x00000000, it | |
| // will be connected first and will block this driver from connecting. | |
| // | |
| EFI_DRIVER_BINDING_PROTOCOL gPciVgaMiniPortDriverBinding = { | |
| PciVgaMiniPortDriverBindingSupported, | |
| PciVgaMiniPortDriverBindingStart, | |
| PciVgaMiniPortDriverBindingStop, | |
| 0x00000000, | |
| NULL, | |
| NULL | |
| }; | |
| /** | |
| Entrypoint of VGA Mini Port Driver. | |
| This function is the entrypoint of UVGA Mini Port Driver. It installs Driver Binding | |
| Protocols together with Component Name Protocols. | |
| @param ImageHandle The firmware allocated handle for the EFI image. | |
| @param SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The entry point is executed successfully. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PciVgaMiniPortDriverEntryPoint ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = EfiLibInstallDriverBindingComponentName2 ( | |
| ImageHandle, | |
| SystemTable, | |
| &gPciVgaMiniPortDriverBinding, | |
| ImageHandle, | |
| &gPciVgaMiniPortComponentName, | |
| &gPciVgaMiniPortComponentName2 | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| Check whether VGA Mini Port driver supports this device. | |
| @param This The driver binding protocol. | |
| @param Controller The controller handle to check. | |
| @param RemainingDevicePath The remaining device path. | |
| @retval EFI_SUCCESS The driver supports this controller. | |
| @retval EFI_UNSUPPORTED This device isn't supported. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PciVgaMiniPortDriverBindingSupported ( | |
| 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; | |
| // | |
| // 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 VGA 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)) { | |
| goto Done; | |
| } | |
| Status = EFI_UNSUPPORTED; | |
| // | |
| // See if the device is an enabled VGA device. | |
| // Most systems can only have on VGA device on at a time. | |
| // | |
| if (((Pci.Hdr.Command & 0x03) == 0x03) && IS_PCI_VGA (&Pci)) { | |
| Status = EFI_SUCCESS; | |
| } | |
| Done: | |
| gBS->CloseProtocol ( | |
| Controller, | |
| &gEfiPciIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| Controller | |
| ); | |
| return Status; | |
| } | |
| /** | |
| Starts the VGA device with this driver. | |
| This function consumes PCI I/O Protocol, and installs VGA Mini Port Protocol | |
| onto the VGA device handle. | |
| @param This The driver binding instance. | |
| @param Controller The controller to check. | |
| @param RemainingDevicePath The remaining device patch. | |
| @retval EFI_SUCCESS The controller is controlled by the driver. | |
| @retval EFI_ALREADY_STARTED The controller is already controlled by the driver. | |
| @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PciVgaMiniPortDriverBindingStart ( | |
| 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_VGA_MINI_PORT_DEV *PciVgaMiniPortPrivate; | |
| PciVgaMiniPortPrivate = NULL; | |
| PciIo = NULL; | |
| // | |
| // 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)) { | |
| goto Done; | |
| } | |
| // | |
| // Allocate the private device structure | |
| // | |
| PciVgaMiniPortPrivate = AllocateZeroPool (sizeof (PCI_VGA_MINI_PORT_DEV)); | |
| ASSERT (PciVgaMiniPortPrivate != NULL); | |
| // | |
| // Initialize the private device structure | |
| // | |
| PciVgaMiniPortPrivate->Signature = PCI_VGA_MINI_PORT_DEV_SIGNATURE; | |
| PciVgaMiniPortPrivate->Handle = Controller; | |
| PciVgaMiniPortPrivate->PciIo = PciIo; | |
| PciVgaMiniPortPrivate->VgaMiniPort.SetMode = PciVgaMiniPortSetMode; | |
| PciVgaMiniPortPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000; | |
| PciVgaMiniPortPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4; | |
| PciVgaMiniPortPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5; | |
| PciVgaMiniPortPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR; | |
| PciVgaMiniPortPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; | |
| PciVgaMiniPortPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; | |
| PciVgaMiniPortPrivate->VgaMiniPort.MaxMode = 1; | |
| // | |
| // Install VGA Mini Port Protocol | |
| // | |
| Status = gBS->InstallMultipleProtocolInterfaces ( | |
| &Controller, | |
| &gEfiVgaMiniPortProtocolGuid, | |
| &PciVgaMiniPortPrivate->VgaMiniPort, | |
| NULL | |
| ); | |
| Done: | |
| if (EFI_ERROR (Status)) { | |
| gBS->CloseProtocol ( | |
| Controller, | |
| &gEfiPciIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| Controller | |
| ); | |
| if (PciVgaMiniPortPrivate != NULL) { | |
| FreePool (PciVgaMiniPortPrivate); | |
| } | |
| } | |
| return Status; | |
| } | |
| /** | |
| Stop the VGA device with this driver. | |
| This function uninstalls VGA Mini Port Protocol from the VGA device handle, | |
| and closes PCI I/O Protocol. | |
| @param This The driver binding protocol. | |
| @param Controller The controller to release. | |
| @param NumberOfChildren The child number that opened controller | |
| BY_CHILD. | |
| @param ChildHandleBuffer The array of child handle. | |
| @retval EFI_SUCCESS The controller or children are stopped. | |
| @retval EFI_DEVICE_ERROR Failed to stop the driver. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PciVgaMiniPortDriverBindingStop ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
| IN EFI_HANDLE Controller, | |
| IN UINTN NumberOfChildren, | |
| IN EFI_HANDLE *ChildHandleBuffer | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; | |
| PCI_VGA_MINI_PORT_DEV *PciVgaMiniPortPrivate; | |
| Status = gBS->OpenProtocol ( | |
| Controller, | |
| &gEfiVgaMiniPortProtocolGuid, | |
| (VOID **) &VgaMiniPort, | |
| This->DriverBindingHandle, | |
| Controller, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| PciVgaMiniPortPrivate = PCI_VGA_MINI_PORT_DEV_FROM_THIS (VgaMiniPort); | |
| Status = gBS->UninstallProtocolInterface ( | |
| Controller, | |
| &gEfiVgaMiniPortProtocolGuid, | |
| &PciVgaMiniPortPrivate->VgaMiniPort | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| gBS->CloseProtocol ( | |
| Controller, | |
| &gEfiPciIoProtocolGuid, | |
| This->DriverBindingHandle, | |
| Controller | |
| ); | |
| FreePool (PciVgaMiniPortPrivate); | |
| return EFI_SUCCESS; | |
| } | |
| // | |
| // VGA Mini Port Protocol Functions | |
| // | |
| /** | |
| Sets the text display mode of a VGA controller. | |
| This function implements EFI_VGA_MINI_PORT_PROTOCOL.SetMode(). | |
| If ModeNumber exceeds the valid range, then EFI_UNSUPPORTED is returned. | |
| Otherwise, EFI_SUCCESS is directly returned without real operation. | |
| @param This Protocol instance pointer. | |
| @param ModeNumber Mode number. 0 - 80x25 1-80x50 | |
| @retval EFI_SUCCESS The mode was set | |
| @retval EFI_UNSUPPORTED ModeNumber is not supported. | |
| @retval EFI_DEVICE_ERROR The device is not functioning properly. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| PciVgaMiniPortSetMode ( | |
| IN EFI_VGA_MINI_PORT_PROTOCOL *This, | |
| IN UINTN ModeNumber | |
| ) | |
| { | |
| if (ModeNumber > This->MaxMode) { | |
| return EFI_UNSUPPORTED; | |
| } | |
| return EFI_SUCCESS; | |
| } | |