Home | History | Annotate | Download | only in VgaMiniPortDxe
      1 /** @file
      2   Implements EFI Driver Binding Protocol and VGA Mini Port Protocol for VGA Mini Port Driver.
      3 
      4 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "VgaMiniPort.h"
     16 
     17 //
     18 // EFI Driver Binding Protocol Instance
     19 //
     20 //   This driver has a version value of 0x00000000.  This is the
     21 //   lowest possible priority for a driver.  This is done on purpose to help
     22 //   the developers of UGA drivers.  This driver can bind if no UGA driver
     23 //   is present, so a console is available.  Then, when a UGA driver is loaded
     24 //   this driver can be disconnected, and the UGA driver can be connected.
     25 //   As long as the UGA driver has a version value greater than 0x00000000, it
     26 //   will be connected first and will block this driver from connecting.
     27 //
     28 EFI_DRIVER_BINDING_PROTOCOL gPciVgaMiniPortDriverBinding = {
     29   PciVgaMiniPortDriverBindingSupported,
     30   PciVgaMiniPortDriverBindingStart,
     31   PciVgaMiniPortDriverBindingStop,
     32   0x00000000,
     33   NULL,
     34   NULL
     35 };
     36 
     37 /**
     38   Entrypoint of VGA Mini Port Driver.
     39 
     40   This function is the entrypoint of UVGA Mini Port Driver. It installs Driver Binding
     41   Protocols together with Component Name Protocols.
     42 
     43   @param  ImageHandle       The firmware allocated handle for the EFI image.
     44   @param  SystemTable       A pointer to the EFI System Table.
     45 
     46   @retval EFI_SUCCESS       The entry point is executed successfully.
     47 
     48 **/
     49 EFI_STATUS
     50 EFIAPI
     51 PciVgaMiniPortDriverEntryPoint (
     52   IN EFI_HANDLE         ImageHandle,
     53   IN EFI_SYSTEM_TABLE   *SystemTable
     54   )
     55 {
     56   EFI_STATUS              Status;
     57 
     58   Status = EfiLibInstallDriverBindingComponentName2 (
     59              ImageHandle,
     60              SystemTable,
     61              &gPciVgaMiniPortDriverBinding,
     62              ImageHandle,
     63              &gPciVgaMiniPortComponentName,
     64              &gPciVgaMiniPortComponentName2
     65              );
     66   ASSERT_EFI_ERROR (Status);
     67 
     68   return EFI_SUCCESS;
     69 }
     70 
     71 
     72 /**
     73   Check whether VGA Mini Port driver supports this device.
     74 
     75   @param  This                   The driver binding protocol.
     76   @param  Controller             The controller handle to check.
     77   @param  RemainingDevicePath    The remaining device path.
     78 
     79   @retval EFI_SUCCESS            The driver supports this controller.
     80   @retval EFI_UNSUPPORTED        This device isn't supported.
     81 
     82 **/
     83 EFI_STATUS
     84 EFIAPI
     85 PciVgaMiniPortDriverBindingSupported (
     86   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
     87   IN EFI_HANDLE                   Controller,
     88   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
     89   )
     90 {
     91   EFI_STATUS          Status;
     92   EFI_PCI_IO_PROTOCOL *PciIo;
     93   PCI_TYPE00          Pci;
     94 
     95   //
     96   // Open the IO Abstraction(s) needed to perform the supported test
     97   //
     98   Status = gBS->OpenProtocol (
     99                   Controller,
    100                   &gEfiPciIoProtocolGuid,
    101                   (VOID **) &PciIo,
    102                   This->DriverBindingHandle,
    103                   Controller,
    104                   EFI_OPEN_PROTOCOL_BY_DRIVER
    105                   );
    106   if (EFI_ERROR (Status)) {
    107     return Status;
    108   }
    109   //
    110   // See if this is a PCI VGA Controller by looking at the Command register and
    111   // Class Code Register
    112   //
    113   Status = PciIo->Pci.Read (
    114                         PciIo,
    115                         EfiPciIoWidthUint32,
    116                         0,
    117                         sizeof (Pci) / sizeof (UINT32),
    118                         &Pci
    119                         );
    120   if (EFI_ERROR (Status)) {
    121     goto Done;
    122   }
    123 
    124   Status = EFI_UNSUPPORTED;
    125   //
    126   // See if the device is an enabled VGA device.
    127   // Most systems can only have on VGA device on at a time.
    128   //
    129   if (((Pci.Hdr.Command & 0x03) == 0x03) && IS_PCI_VGA (&Pci)) {
    130     Status = EFI_SUCCESS;
    131   }
    132 
    133 Done:
    134   gBS->CloseProtocol (
    135          Controller,
    136          &gEfiPciIoProtocolGuid,
    137          This->DriverBindingHandle,
    138          Controller
    139          );
    140 
    141   return Status;
    142 }
    143 
    144 
    145 /**
    146   Starts the VGA device with this driver.
    147 
    148   This function consumes PCI I/O Protocol, and installs VGA Mini Port Protocol
    149   onto the VGA device handle.
    150 
    151   @param  This                   The driver binding instance.
    152   @param  Controller             The controller to check.
    153   @param  RemainingDevicePath    The remaining device patch.
    154 
    155   @retval EFI_SUCCESS            The controller is controlled by the driver.
    156   @retval EFI_ALREADY_STARTED    The controller is already controlled by the driver.
    157   @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
    158 
    159 **/
    160 EFI_STATUS
    161 EFIAPI
    162 PciVgaMiniPortDriverBindingStart (
    163   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    164   IN EFI_HANDLE                   Controller,
    165   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
    166   )
    167 {
    168   EFI_STATUS            Status;
    169   EFI_PCI_IO_PROTOCOL   *PciIo;
    170   PCI_VGA_MINI_PORT_DEV *PciVgaMiniPortPrivate;
    171 
    172   PciVgaMiniPortPrivate = NULL;
    173   PciIo                 = NULL;
    174   //
    175   // Open the IO Abstraction(s) needed
    176   //
    177   Status = gBS->OpenProtocol (
    178                   Controller,
    179                   &gEfiPciIoProtocolGuid,
    180                   (VOID **) &PciIo,
    181                   This->DriverBindingHandle,
    182                   Controller,
    183                   EFI_OPEN_PROTOCOL_BY_DRIVER
    184                   );
    185   if (EFI_ERROR (Status)) {
    186     goto Done;
    187   }
    188   //
    189   // Allocate the private device structure
    190   //
    191   PciVgaMiniPortPrivate = AllocateZeroPool (sizeof (PCI_VGA_MINI_PORT_DEV));
    192   ASSERT (PciVgaMiniPortPrivate != NULL);
    193 
    194   //
    195   // Initialize the private device structure
    196   //
    197   PciVgaMiniPortPrivate->Signature = PCI_VGA_MINI_PORT_DEV_SIGNATURE;
    198   PciVgaMiniPortPrivate->Handle = Controller;
    199   PciVgaMiniPortPrivate->PciIo = PciIo;
    200 
    201   PciVgaMiniPortPrivate->VgaMiniPort.SetMode = PciVgaMiniPortSetMode;
    202   PciVgaMiniPortPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000;
    203   PciVgaMiniPortPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4;
    204   PciVgaMiniPortPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5;
    205   PciVgaMiniPortPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR;
    206   PciVgaMiniPortPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
    207   PciVgaMiniPortPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
    208   PciVgaMiniPortPrivate->VgaMiniPort.MaxMode = 1;
    209 
    210   //
    211   // Install VGA Mini Port Protocol
    212   //
    213   Status = gBS->InstallMultipleProtocolInterfaces (
    214                   &Controller,
    215                   &gEfiVgaMiniPortProtocolGuid,
    216                   &PciVgaMiniPortPrivate->VgaMiniPort,
    217                   NULL
    218                   );
    219 Done:
    220   if (EFI_ERROR (Status)) {
    221     gBS->CloseProtocol (
    222            Controller,
    223            &gEfiPciIoProtocolGuid,
    224            This->DriverBindingHandle,
    225            Controller
    226            );
    227     if (PciVgaMiniPortPrivate != NULL) {
    228       FreePool (PciVgaMiniPortPrivate);
    229     }
    230   }
    231 
    232   return Status;
    233 }
    234 
    235 
    236 /**
    237   Stop the VGA device with this driver.
    238 
    239   This function uninstalls VGA Mini Port Protocol from the VGA device handle,
    240   and closes PCI I/O Protocol.
    241 
    242   @param  This                   The driver binding protocol.
    243   @param  Controller             The controller to release.
    244   @param  NumberOfChildren       The child number that opened controller
    245                                  BY_CHILD.
    246   @param  ChildHandleBuffer      The array of child handle.
    247 
    248   @retval EFI_SUCCESS            The controller or children are stopped.
    249   @retval EFI_DEVICE_ERROR       Failed to stop the driver.
    250 
    251 **/
    252 EFI_STATUS
    253 EFIAPI
    254 PciVgaMiniPortDriverBindingStop (
    255   IN  EFI_DRIVER_BINDING_PROTOCOL     *This,
    256   IN  EFI_HANDLE                      Controller,
    257   IN  UINTN                           NumberOfChildren,
    258   IN  EFI_HANDLE                      *ChildHandleBuffer
    259   )
    260 {
    261   EFI_STATUS                  Status;
    262   EFI_VGA_MINI_PORT_PROTOCOL  *VgaMiniPort;
    263   PCI_VGA_MINI_PORT_DEV       *PciVgaMiniPortPrivate;
    264 
    265   Status = gBS->OpenProtocol (
    266                   Controller,
    267                   &gEfiVgaMiniPortProtocolGuid,
    268                   (VOID **) &VgaMiniPort,
    269                   This->DriverBindingHandle,
    270                   Controller,
    271                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    272                   );
    273   if (EFI_ERROR (Status)) {
    274     return Status;
    275   }
    276 
    277   PciVgaMiniPortPrivate = PCI_VGA_MINI_PORT_DEV_FROM_THIS (VgaMiniPort);
    278 
    279   Status = gBS->UninstallProtocolInterface (
    280                   Controller,
    281                   &gEfiVgaMiniPortProtocolGuid,
    282                   &PciVgaMiniPortPrivate->VgaMiniPort
    283                   );
    284   if (EFI_ERROR (Status)) {
    285     return Status;
    286   }
    287 
    288   gBS->CloseProtocol (
    289          Controller,
    290          &gEfiPciIoProtocolGuid,
    291          This->DriverBindingHandle,
    292          Controller
    293          );
    294 
    295   FreePool (PciVgaMiniPortPrivate);
    296 
    297   return EFI_SUCCESS;
    298 }
    299 //
    300 // VGA Mini Port Protocol Functions
    301 //
    302 
    303 /**
    304   Sets the text display mode of a VGA controller.
    305 
    306   This function implements EFI_VGA_MINI_PORT_PROTOCOL.SetMode().
    307   If ModeNumber exceeds the valid range, then EFI_UNSUPPORTED is returned.
    308   Otherwise, EFI_SUCCESS is directly returned without real operation.
    309 
    310   @param This                 Protocol instance pointer.
    311   @param ModeNumber           Mode number.  0 - 80x25   1-80x50
    312 
    313   @retval EFI_SUCCESS         The mode was set
    314   @retval EFI_UNSUPPORTED     ModeNumber is not supported.
    315   @retval EFI_DEVICE_ERROR    The device is not functioning properly.
    316 
    317 **/
    318 EFI_STATUS
    319 EFIAPI
    320 PciVgaMiniPortSetMode (
    321   IN  EFI_VGA_MINI_PORT_PROTOCOL  *This,
    322   IN  UINTN                       ModeNumber
    323   )
    324 {
    325   if (ModeNumber > This->MaxMode) {
    326     return EFI_UNSUPPORTED;
    327   }
    328 
    329   return EFI_SUCCESS;
    330 }
    331 
    332