git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10414 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			332 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Implements EFI Driver Binding Protocol and VGA Mini Port Protocol for VGA Mini Port Driver.
 | |
| 
 | |
| Copyright (c) 2006 - 2009, 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;
 | |
| }
 | |
|   
 |