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