]> git.proxmox.com Git - mirror_edk2.git/blame - PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.c
PcAtChipsetPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / PcAtChipsetPkg / IsaAcpiDxe / PcatIsaAcpi.c
CommitLineData
c860b463 1/** @file\r
2 EFI PCAT ISA ACPI Driver for a Generic PC Platform\r
c69dd9df 3\r
5a702acd 4Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
e1d302e5 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c69dd9df 6\r
c860b463 7**/\r
c69dd9df 8\r
9#include "PcatIsaAcpi.h"\r
10\r
11//\r
12// PcatIsaAcpi Driver Binding Protocol\r
13//\r
14EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding = {\r
15 PcatIsaAcpiDriverBindingSupported,\r
16 PcatIsaAcpiDriverBindingStart,\r
17 PcatIsaAcpiDriverBindingStop,\r
18 0xa,\r
19 NULL,\r
20 NULL\r
21};\r
22\r
18c97f53 23/**\r
24 the entry point of the PcatIsaAcpi driver.\r
25\r
26 @param ImageHandle Handle for driver image\r
27 @param SystemTable Point to EFI_SYSTEM_TABLE\r
28\r
619ad10f 29 @return Success or not for installing driver binding protocol\r
18c97f53 30**/\r
c69dd9df 31EFI_STATUS\r
32EFIAPI\r
33PcatIsaAcpiDriverEntryPoint (\r
34 IN EFI_HANDLE ImageHandle,\r
35 IN EFI_SYSTEM_TABLE *SystemTable\r
36 )\r
c69dd9df 37{\r
38 return EfiLibInstallDriverBindingComponentName2 (\r
5a702acd
LG
39 ImageHandle,\r
40 SystemTable,\r
c69dd9df 41 &gPcatIsaAcpiDriverBinding,\r
42 ImageHandle,\r
43 &gPcatIsaAcpiComponentName,\r
44 &gPcatIsaAcpiComponentName2\r
45 );\r
46}\r
47\r
18c97f53 48/**\r
49 ControllerDriver Protocol Method\r
50\r
5a702acd 51 @param This Driver Binding protocol instance pointer.\r
18c97f53 52 @param Controller Handle of device to test.\r
53 @param RemainingDevicePath Optional parameter use to pick a specific child\r
54 device to start.\r
55 @retval EFI_SUCCESS This driver supports this device.\r
56 @retval other This driver does not support this device.\r
57\r
58**/\r
c69dd9df 59EFI_STATUS\r
60EFIAPI\r
61PcatIsaAcpiDriverBindingSupported (\r
62 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
63 IN EFI_HANDLE Controller,\r
64 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
65 )\r
c69dd9df 66{\r
67 EFI_STATUS Status;\r
68 EFI_PCI_IO_PROTOCOL *PciIo;\r
69 PCI_TYPE00 Pci;\r
755e4d11 70 UINTN SegmentNumber;\r
71 UINTN BusNumber;\r
72 UINTN DeviceNumber;\r
73 UINTN FunctionNumber;\r
c69dd9df 74\r
75 //\r
76 // Get PciIo protocol instance\r
5a702acd 77 //\r
c69dd9df 78 Status = gBS->OpenProtocol (\r
5a702acd
LG
79 Controller,\r
80 &gEfiPciIoProtocolGuid,\r
9c83c97a 81 (VOID**)&PciIo,\r
c69dd9df 82 This->DriverBindingHandle,\r
83 Controller,\r
84 EFI_OPEN_PROTOCOL_BY_DRIVER\r
85 );\r
86 if (EFI_ERROR(Status)) {\r
87 return Status;\r
88 }\r
89\r
90 Status = PciIo->Pci.Read (\r
91 PciIo,\r
92 EfiPciIoWidthUint32,\r
93 0,\r
5a702acd 94 sizeof(Pci) / sizeof(UINT32),\r
c69dd9df 95 &Pci);\r
c860b463 96\r
c69dd9df 97 if (!EFI_ERROR (Status)) {\r
98 Status = EFI_UNSUPPORTED;\r
99 if ((Pci.Hdr.Command & 0x03) == 0x03) {\r
100 if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {\r
101 //\r
102 // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code\r
103 //\r
bc14bdb3 104 if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {\r
c69dd9df 105 Status = EFI_SUCCESS;\r
5a702acd 106 }\r
c69dd9df 107\r
108 //\r
109 // See if this is an Intel PCI to ISA bridge in Positive Decode Mode\r
110 //\r
5a702acd 111 if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&\r
755e4d11 112 Pci.Hdr.VendorId == 0x8086 ) {\r
113 //\r
5a702acd
LG
114 // See if this is on Function #0 to avoid false positives on\r
115 // PCI_CLASS_BRIDGE_OTHER that has the same value as\r
755e4d11 116 // PCI_CLASS_BRIDGE_ISA_PDECODE\r
117 //\r
118 Status = PciIo->GetLocation (\r
5a702acd
LG
119 PciIo,\r
120 &SegmentNumber,\r
121 &BusNumber,\r
122 &DeviceNumber,\r
755e4d11 123 &FunctionNumber\r
124 );\r
125 if (!EFI_ERROR (Status) && FunctionNumber == 0) {\r
126 Status = EFI_SUCCESS;\r
127 } else {\r
128 Status = EFI_UNSUPPORTED;\r
129 }\r
c69dd9df 130 }\r
5a702acd 131 }\r
c69dd9df 132 }\r
133 }\r
134\r
135 gBS->CloseProtocol (\r
5a702acd
LG
136 Controller,\r
137 &gEfiPciIoProtocolGuid,\r
138 This->DriverBindingHandle,\r
139 Controller\r
c69dd9df 140 );\r
5a702acd 141\r
c69dd9df 142 return Status;\r
143}\r
144\r
18c97f53 145/**\r
146 Install EFI_ISA_ACPI_PROTOCOL.\r
147\r
148 @param This Driver Binding protocol instance pointer.\r
149 @param ControllerHandle Handle of device to bind driver to.\r
150 @param RemainingDevicePath Optional parameter use to pick a specific child\r
151 device to start.\r
152\r
153 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
154 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
155 @retval other This driver does not support this device\r
156**/\r
c69dd9df 157EFI_STATUS\r
158EFIAPI\r
159PcatIsaAcpiDriverBindingStart (\r
160 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
161 IN EFI_HANDLE Controller,\r
162 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
163 )\r
c69dd9df 164{\r
165 EFI_STATUS Status;\r
166 EFI_PCI_IO_PROTOCOL *PciIo;\r
167 PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;\r
e0ee9d93 168 UINT64 Supports;\r
cb68247d 169 UINT64 OriginalAttributes;\r
e0ee9d93 170 BOOLEAN Enabled;\r
171\r
172 Enabled = FALSE;\r
173 Supports = 0;\r
c69dd9df 174 PcatIsaAcpiDev = NULL;\r
2d3a626e 175 OriginalAttributes = 0;\r
c69dd9df 176 //\r
177 // Open the PCI I/O Protocol Interface\r
178 //\r
179 PciIo = NULL;\r
180 Status = gBS->OpenProtocol (\r
5a702acd
LG
181 Controller,\r
182 &gEfiPciIoProtocolGuid,\r
9c83c97a 183 (VOID**)&PciIo,\r
5a702acd
LG
184 This->DriverBindingHandle,\r
185 Controller,\r
186 EFI_OPEN_PROTOCOL_BY_DRIVER\r
c69dd9df 187 );\r
188 if (EFI_ERROR (Status)) {\r
189 goto Done;\r
190 }\r
191\r
e0ee9d93 192 //\r
193 // Get supported PCI attributes\r
194 //\r
195 Status = PciIo->Attributes (\r
196 PciIo,\r
197 EfiPciIoAttributeOperationSupported,\r
198 0,\r
199 &Supports\r
200 );\r
201 if (EFI_ERROR (Status)) {\r
202 goto Done;\r
203 }\r
204\r
df6bd1b6 205 Supports &= (UINT64) (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
e0ee9d93 206 if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16)) {\r
207 Status = EFI_UNSUPPORTED;\r
208 goto Done;\r
cb68247d
RN
209 }\r
210\r
211 Status = PciIo->Attributes (\r
212 PciIo,\r
213 EfiPciIoAttributeOperationGet,\r
214 0,\r
215 &OriginalAttributes\r
216 );\r
217 if (EFI_ERROR (Status)) {\r
218 goto Done;\r
219 }\r
e0ee9d93 220\r
c69dd9df 221 Status = PciIo->Attributes (\r
5a702acd
LG
222 PciIo,\r
223 EfiPciIoAttributeOperationEnable,\r
224 EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,\r
225 NULL\r
c69dd9df 226 );\r
227 if (EFI_ERROR (Status)) {\r
228 goto Done;\r
229 }\r
cb68247d
RN
230\r
231 Enabled = TRUE;\r
c69dd9df 232 //\r
233 // Allocate memory for the PCAT ISA ACPI Device structure\r
234 //\r
235 PcatIsaAcpiDev = NULL;\r
236 Status = gBS->AllocatePool (\r
237 EfiBootServicesData,\r
238 sizeof(PCAT_ISA_ACPI_DEV),\r
9c83c97a 239 (VOID**)&PcatIsaAcpiDev\r
c69dd9df 240 );\r
241 if (EFI_ERROR (Status)) {\r
242 goto Done;\r
243 }\r
244\r
245 //\r
246 // Initialize the PCAT ISA ACPI Device structure\r
247 //\r
cb68247d
RN
248 PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;\r
249 PcatIsaAcpiDev->Handle = Controller;\r
250 PcatIsaAcpiDev->PciIo = PciIo;\r
251 PcatIsaAcpiDev->OriginalAttributes = OriginalAttributes;\r
e8bce4b4
RN
252\r
253 //\r
254 // Initialize PcatIsaAcpiDeviceList\r
255 //\r
256 InitializePcatIsaAcpiDeviceList ();\r
5a702acd 257\r
c69dd9df 258 //\r
259 // IsaAcpi interface\r
260 //\r
261 (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate = IsaDeviceEnumerate;\r
262 (PcatIsaAcpiDev->IsaAcpi).SetPower = IsaDeviceSetPower;\r
263 (PcatIsaAcpiDev->IsaAcpi).GetCurResource = IsaGetCurrentResource;\r
264 (PcatIsaAcpiDev->IsaAcpi).GetPosResource = IsaGetPossibleResource;\r
265 (PcatIsaAcpiDev->IsaAcpi).SetResource = IsaSetResource;\r
266 (PcatIsaAcpiDev->IsaAcpi).EnableDevice = IsaEnableDevice;\r
267 (PcatIsaAcpiDev->IsaAcpi).InitDevice = IsaInitDevice;\r
268 (PcatIsaAcpiDev->IsaAcpi).InterfaceInit = IsaInterfaceInit;\r
5a702acd 269\r
c69dd9df 270 //\r
271 // Install the ISA ACPI Protocol interface\r
272 //\r
273 Status = gBS->InstallMultipleProtocolInterfaces (\r
274 &Controller,\r
275 &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,\r
276 NULL\r
277 );\r
278\r
279Done:\r
280 if (EFI_ERROR (Status)) {\r
e0ee9d93 281 if (PciIo != NULL && Enabled) {\r
c69dd9df 282 PciIo->Attributes (\r
5a702acd 283 PciIo,\r
cb68247d
RN
284 EfiPciIoAttributeOperationSet,\r
285 OriginalAttributes,\r
5a702acd 286 NULL\r
c69dd9df 287 );\r
288 }\r
289 gBS->CloseProtocol (\r
5a702acd
LG
290 Controller,\r
291 &gEfiPciIoProtocolGuid,\r
292 This->DriverBindingHandle,\r
c69dd9df 293 Controller\r
294 );\r
295 if (PcatIsaAcpiDev != NULL) {\r
296 gBS->FreePool (PcatIsaAcpiDev);\r
297 }\r
298 return Status;\r
299 }\r
5a702acd 300\r
c69dd9df 301 return EFI_SUCCESS;\r
302}\r
303\r
18c97f53 304\r
305/**\r
306 Stop this driver on ControllerHandle. Support stopping any child handles\r
307 created by this driver.\r
308\r
309 @param This Protocol instance pointer.\r
310 @param ControllerHandle Handle of device to stop driver on\r
311 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
312 children is zero stop the entire bus driver.\r
313 @param ChildHandleBuffer List of Child Handles to Stop.\r
314\r
315 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
316 @retval other This driver was not removed from this device\r
317\r
318**/\r
c69dd9df 319EFI_STATUS\r
320EFIAPI\r
321PcatIsaAcpiDriverBindingStop (\r
322 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
323 IN EFI_HANDLE Controller,\r
324 IN UINTN NumberOfChildren,\r
325 IN EFI_HANDLE *ChildHandleBuffer\r
326 )\r
c69dd9df 327{\r
328 EFI_STATUS Status;\r
329 EFI_ISA_ACPI_PROTOCOL *IsaAcpi;\r
330 PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;\r
5a702acd 331\r
c69dd9df 332 //\r
333 // Get the ISA ACPI Protocol Interface\r
5a702acd 334 //\r
c69dd9df 335 Status = gBS->OpenProtocol (\r
5a702acd
LG
336 Controller,\r
337 &gEfiIsaAcpiProtocolGuid,\r
9c83c97a 338 (VOID**)&IsaAcpi,\r
5a702acd
LG
339 This->DriverBindingHandle,\r
340 Controller,\r
c69dd9df 341 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
342 );\r
343 if (EFI_ERROR (Status)) {\r
344 return Status;\r
345 }\r
346\r
347 //\r
348 // Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol\r
349 //\r
350 PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);\r
351\r
e0ee9d93 352 //\r
cb68247d 353 // Restore PCI attributes\r
e0ee9d93 354 //\r
355 Status = PcatIsaAcpiDev->PciIo->Attributes (\r
356 PcatIsaAcpiDev->PciIo,\r
cb68247d
RN
357 EfiPciIoAttributeOperationSet,\r
358 PcatIsaAcpiDev->OriginalAttributes,\r
359 NULL\r
e0ee9d93 360 );\r
361 if (EFI_ERROR (Status)) {\r
362 return Status;\r
363 }\r
364\r
c69dd9df 365 //\r
366 // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL\r
367 //\r
368 Status = gBS->UninstallProtocolInterface (\r
369 Controller,\r
370 &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi\r
371 );\r
372 if (EFI_ERROR (Status)) {\r
373 return Status;\r
374 }\r
375\r
376 gBS->CloseProtocol (\r
5a702acd
LG
377 Controller,\r
378 &gEfiPciIoProtocolGuid,\r
379 This->DriverBindingHandle,\r
c69dd9df 380 Controller\r
381 );\r
5a702acd 382\r
c69dd9df 383 gBS->FreePool (PcatIsaAcpiDev);\r
5a702acd 384\r
c69dd9df 385 return EFI_SUCCESS;\r
386}\r