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