Home | History | Annotate | Download | only in Wpce791
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     21 
     23 
     24 Module Name:
     25 
     26     LpcDriver.c
     27 
     28 Abstract:
     29 
     30     EFI Lpc Driver for a Generic PC Platform
     31 
     32 
     33 
     34 --*/
     35 
     36 #include "LpcDriver.h"
     37 #include "IndustryStandard/Pci22.h"
     38 
     39 //
     40 // This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
     41 //
     42 
     43 //
     44 //  Lpc Driver Global Variables
     45 //
     46 
     47 EFI_DRIVER_BINDING_PROTOCOL gLpcDriver = {
     48   LpcDriverSupported,
     49   LpcDriverStart,
     50   LpcDriverStop,
     51   0x10,
     52   NULL,
     53   NULL
     54 };
     55 
     56 LPC_DEV mLpc = {
     57   LPC_DEV_SIGNATURE,
     58   NULL,
     59   {
     60     IsaDeviceEnumerate,
     61     IsaDeviceSetPower,
     62     IsaGetCurrentResource,
     63     IsaGetPossibleResource,
     64     IsaSetResource,
     65     IsaEnableDevice,
     66     IsaInitDevice,
     67     LpcInterfaceInit
     68   },
     69   NULL
     70 };
     71 
     72 BOOLEAN  InitExecuted = FALSE;
     73 
     74 /**
     75     the entry point of the Lpc driver
     76 
     77 **/
     78 EFI_STATUS
     79 EFIAPI
     80 LpcDriverEntryPoint(
     81   IN EFI_HANDLE           ImageHandle,
     82   IN EFI_SYSTEM_TABLE     *SystemTable
     83   )
     84 {
     85 
     86 
     87   return EfiLibInstallDriverBinding (ImageHandle, SystemTable, &gLpcDriver, ImageHandle);
     88 }
     89 
     90 /**
     91 
     92   ControllerDriver Protocol Method
     93 
     94 **/
     95 EFI_STATUS
     96 EFIAPI
     97 LpcDriverSupported (
     98   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
     99   IN EFI_HANDLE                     Controller,
    100   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
    101   )
    102 {
    103   EFI_STATUS                Status;
    104   EFI_PCI_IO_PROTOCOL       *PciIo;
    105   EFI_DEVICE_PATH_PROTOCOL  *IsaBridgeDevicePath;
    106 
    107   ACPI_HID_DEVICE_PATH      *AcpiNode;
    108   PCI_DEVICE_PATH           *PciNode;
    109   PCI_TYPE00                Pci;
    110 
    111   //
    112   // Get the ISA bridge's Device Path and test it
    113   // the following code is specific
    114   //
    115   Status = gBS->OpenProtocol (
    116                   Controller,
    117                   &gEfiDevicePathProtocolGuid,
    118                   (VOID **)&IsaBridgeDevicePath,
    119                   This->DriverBindingHandle,
    120                   Controller,
    121                   EFI_OPEN_PROTOCOL_BY_DRIVER
    122                   );
    123 
    124   if (EFI_ERROR (Status)) {
    125     return Status;
    126   }
    127 
    128   Status = EFI_SUCCESS;
    129   AcpiNode =  (ACPI_HID_DEVICE_PATH *)IsaBridgeDevicePath;
    130   if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
    131       AcpiNode->Header.SubType != ACPI_DP ||
    132       DevicePathNodeLength (&AcpiNode->Header) != sizeof(ACPI_HID_DEVICE_PATH) ||
    133       AcpiNode -> HID != EISA_PNP_ID(0x0A03) ||
    134       AcpiNode -> UID != 0 ) {
    135     Status = EFI_UNSUPPORTED;
    136   } else {
    137     //
    138     // Get the next node
    139     //
    140     IsaBridgeDevicePath = NextDevicePathNode (IsaBridgeDevicePath);
    141     PciNode  = (PCI_DEVICE_PATH *)IsaBridgeDevicePath;
    142     if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
    143         PciNode->Header.SubType != HW_PCI_DP ||
    144         DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH) ||
    145         PciNode -> Function != 0x00 ||
    146         PciNode -> Device != 0x1f ) {
    147       Status = EFI_UNSUPPORTED;
    148     }
    149   }
    150 
    151   gBS->CloseProtocol (
    152          Controller,
    153          &gEfiDevicePathProtocolGuid,
    154          This->DriverBindingHandle,
    155          Controller
    156          );
    157 
    158   if (EFI_ERROR (Status)) {
    159     return EFI_UNSUPPORTED;
    160   }
    161 
    162   //
    163   // Get PciIo protocol instance
    164   //
    165   Status = gBS->OpenProtocol (
    166                   Controller,
    167                   &gEfiPciIoProtocolGuid,
    168                   (VOID **)&PciIo,
    169                   This->DriverBindingHandle,
    170                   Controller,
    171                   EFI_OPEN_PROTOCOL_BY_DRIVER
    172                   );
    173 
    174   if (EFI_ERROR(Status)) {
    175     return Status;
    176   }
    177 
    178   Status = PciIo->Pci.Read (
    179                         PciIo,
    180                         EfiPciIoWidthUint32,
    181                         0,
    182                         sizeof(Pci) / sizeof(UINT32),
    183                         &Pci
    184                         );
    185 
    186   if (!EFI_ERROR (Status)) {
    187     Status = EFI_SUCCESS; //TODO: force return success as temp solution EFI_UNSUPPORTED;
    188     if ((Pci.Hdr.Command & 0x03) == 0x03) {
    189       if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
    190         //
    191         // See if this is a standard PCI to ISA Bridge from the Base Code
    192         // and Class Code
    193         //
    194         if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
    195           Status = EFI_SUCCESS;
    196         } else {
    197         }
    198 
    199         //
    200         // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
    201         //
    202         if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
    203             Pci.Hdr.VendorId == 0x8086 &&
    204             Pci.Hdr.DeviceId == 0x7110) {
    205           Status = EFI_SUCCESS;
    206         } else {
    207         }
    208       } else {
    209       }
    210     }
    211     else {
    212     }
    213   }
    214 
    215   gBS->CloseProtocol (
    216          Controller,
    217          &gEfiPciIoProtocolGuid,
    218          This->DriverBindingHandle,
    219          Controller
    220          );
    221   return Status;
    222 }
    223 
    224 
    225 /**
    226   Install EFI_ISA_ACPI_PROTOCOL
    227 
    228 **/
    229 EFI_STATUS
    230 EFIAPI
    231 LpcDriverStart (
    232   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    233   IN EFI_HANDLE                     Controller,
    234   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
    235   )
    236 {
    237   EFI_STATUS             Status;
    238   EFI_PCI_IO_PROTOCOL    *PciIo;
    239 
    240   //
    241   // Get Pci IO
    242   //
    243   Status = gBS->OpenProtocol (
    244                   Controller,
    245                   &gEfiPciIoProtocolGuid,
    246                   (VOID **)&PciIo,
    247                   This->DriverBindingHandle,
    248                   Controller,
    249                   EFI_OPEN_PROTOCOL_BY_DRIVER
    250                   );
    251 
    252   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    253     return Status;
    254   }
    255 
    256   mLpc.PciIo = PciIo;
    257 
    258   //
    259   // Install IsaAcpi interface, the Sio interface is not installed!
    260   //
    261   Status = gBS->InstallMultipleProtocolInterfaces (
    262                   &Controller,
    263                   &gEfiIsaAcpiProtocolGuid,
    264                   &mLpc.IsaAcpi,
    265                   NULL
    266                   );
    267   return Status;
    268 }
    269 
    270 
    271 EFI_STATUS
    272 EFIAPI
    273 LpcDriverStop (
    274   IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
    275   IN  EFI_HANDLE                     Controller,
    276   IN  UINTN                          NumberOfChildren,
    277   IN  EFI_HANDLE                     *ChildHandleBuffer
    278   )
    279 {
    280   EFI_STATUS             Status;
    281   EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;
    282   LPC_DEV                *LpcDev;
    283 
    284   //
    285   // Get EFI_ISA_ACPI_PROTOCOL interface
    286   //
    287   Status = gBS->OpenProtocol (
    288                   Controller,
    289                   &gEfiIsaAcpiProtocolGuid,
    290                   (VOID **)&IsaAcpi,
    291                   This->DriverBindingHandle,
    292                   Controller,
    293                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    294                   );
    295   if (EFI_ERROR (Status)) {
    296     return Status;
    297   }
    298 
    299   LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
    300 
    301   //
    302   // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
    303   //
    304   Status = gBS->UninstallProtocolInterface (
    305                   Controller,
    306                   &gEfiIsaAcpiProtocolGuid,
    307                   &LpcDev->IsaAcpi
    308                   );
    309   if (EFI_ERROR (Status)) {
    310     return Status;
    311   }
    312 
    313   gBS->CloseProtocol (
    314          Controller,
    315          &gEfiPciIoProtocolGuid,
    316          This->DriverBindingHandle,
    317          Controller
    318          );
    319 
    320   return EFI_SUCCESS;
    321 }
    322 
    323 VOID
    324 LpcIoRead8 (
    325   IN  UINT16  Port,
    326   OUT UINT8   *Data
    327   )
    328 {
    329   mLpc.PciIo->Io.Read(
    330                    mLpc.PciIo,
    331                    EfiPciWidthUint8,
    332                    EFI_PCI_IO_PASS_THROUGH_BAR,
    333                    Port,
    334                    1,
    335                    Data
    336                    );
    337 }
    338 
    339 VOID
    340 LpcIoWrite8 (
    341   IN  UINT16  Port,
    342   IN  UINT8   Data
    343   )
    344 {
    345   mLpc.PciIo->Io.Write(
    346                    mLpc.PciIo,
    347                    EfiPciWidthUint8,
    348                    EFI_PCI_IO_PASS_THROUGH_BAR,
    349                    Port,
    350                    1,
    351                    &Data
    352                    );
    353 }
    354 
    355