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   LPC_DEV                *LpcDev;
    240 
    241 
    242   LpcDev = NULL;
    243 
    244   //
    245   // Get Pci IO
    246   //
    247   Status = gBS->OpenProtocol (
    248                   Controller,
    249                   &gEfiPciIoProtocolGuid,
    250                   (VOID **)&PciIo,
    251                   This->DriverBindingHandle,
    252                   Controller,
    253                   EFI_OPEN_PROTOCOL_BY_DRIVER
    254                   );
    255 
    256   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    257     return Status;
    258   }
    259 
    260   mLpc.PciIo = PciIo;
    261 
    262   //
    263   // Install IsaAcpi interface, the Sio interface is not installed!
    264   //
    265   Status = gBS->InstallMultipleProtocolInterfaces (
    266                   &Controller,
    267                   &gEfiIsaAcpiProtocolGuid,
    268                   &mLpc.IsaAcpi,
    269                   NULL
    270                   );
    271   return Status;
    272 }
    273 
    274 
    275 EFI_STATUS
    276 EFIAPI
    277 LpcDriverStop (
    278   IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
    279   IN  EFI_HANDLE                     Controller,
    280   IN  UINTN                          NumberOfChildren,
    281   IN  EFI_HANDLE                     *ChildHandleBuffer
    282   )
    283 {
    284   EFI_STATUS             Status;
    285   EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;
    286   LPC_DEV                *LpcDev;
    287 
    288   //
    289   // Get EFI_ISA_ACPI_PROTOCOL interface
    290   //
    291   Status = gBS->OpenProtocol (
    292                   Controller,
    293                   &gEfiIsaAcpiProtocolGuid,
    294                   (VOID **)&IsaAcpi,
    295                   This->DriverBindingHandle,
    296                   Controller,
    297                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    298                   );
    299   if (EFI_ERROR (Status)) {
    300     return Status;
    301   }
    302 
    303   LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
    304 
    305   //
    306   // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
    307   //
    308   Status = gBS->UninstallProtocolInterface (
    309                   Controller,
    310                   &gEfiIsaAcpiProtocolGuid,
    311                   &LpcDev->IsaAcpi
    312                   );
    313   if (EFI_ERROR (Status)) {
    314     return Status;
    315   }
    316 
    317   gBS->CloseProtocol (
    318          Controller,
    319          &gEfiPciIoProtocolGuid,
    320          This->DriverBindingHandle,
    321          Controller
    322          );
    323 
    324   return EFI_SUCCESS;
    325 }
    326 
    327 VOID
    328 LpcIoRead8 (
    329   IN  UINT16  Port,
    330   OUT UINT8   *Data
    331   )
    332 {
    333   mLpc.PciIo->Io.Read(
    334                    mLpc.PciIo,
    335                    EfiPciWidthUint8,
    336                    EFI_PCI_IO_PASS_THROUGH_BAR,
    337                    Port,
    338                    1,
    339                    Data
    340                    );
    341 }
    342 
    343 VOID
    344 LpcIoWrite8 (
    345   IN  UINT16  Port,
    346   IN  UINT8   Data
    347   )
    348 {
    349   mLpc.PciIo->Io.Write(
    350                    mLpc.PciIo,
    351                    EfiPciWidthUint8,
    352                    EFI_PCI_IO_PASS_THROUGH_BAR,
    353                    Port,
    354                    1,
    355                    &Data
    356                    );
    357 }
    358 
    359