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