]> git.proxmox.com Git - mirror_edk2.git/blob - PcAtChipsetPkg/IsaAcpiDxe/PcatIsaAcpi.c
Update logic in Suuported() for PCI-ISA Bridges with Positive Decode to avoid false...
[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 - 2010, 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 Sucess 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
175 PcatIsaAcpiDev = NULL;
176 //
177 // Open the PCI I/O Protocol Interface
178 //
179 PciIo = NULL;
180 Status = gBS->OpenProtocol (
181 Controller,
182 &gEfiPciIoProtocolGuid,
183 (VOID**)&PciIo,
184 This->DriverBindingHandle,
185 Controller,
186 EFI_OPEN_PROTOCOL_BY_DRIVER
187 );
188 if (EFI_ERROR (Status)) {
189 goto Done;
190 }
191
192 Status = PciIo->Attributes (
193 PciIo,
194 EfiPciIoAttributeOperationEnable,
195 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
196 NULL
197 );
198 if (EFI_ERROR (Status)) {
199 goto Done;
200 }
201
202 //
203 // Allocate memory for the PCAT ISA ACPI Device structure
204 //
205 PcatIsaAcpiDev = NULL;
206 Status = gBS->AllocatePool (
207 EfiBootServicesData,
208 sizeof(PCAT_ISA_ACPI_DEV),
209 (VOID**)&PcatIsaAcpiDev
210 );
211 if (EFI_ERROR (Status)) {
212 goto Done;
213 }
214
215 //
216 // Initialize the PCAT ISA ACPI Device structure
217 //
218 PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
219 PcatIsaAcpiDev->Handle = Controller;
220 PcatIsaAcpiDev->PciIo = PciIo;
221
222 //
223 // IsaAcpi interface
224 //
225 (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate = IsaDeviceEnumerate;
226 (PcatIsaAcpiDev->IsaAcpi).SetPower = IsaDeviceSetPower;
227 (PcatIsaAcpiDev->IsaAcpi).GetCurResource = IsaGetCurrentResource;
228 (PcatIsaAcpiDev->IsaAcpi).GetPosResource = IsaGetPossibleResource;
229 (PcatIsaAcpiDev->IsaAcpi).SetResource = IsaSetResource;
230 (PcatIsaAcpiDev->IsaAcpi).EnableDevice = IsaEnableDevice;
231 (PcatIsaAcpiDev->IsaAcpi).InitDevice = IsaInitDevice;
232 (PcatIsaAcpiDev->IsaAcpi).InterfaceInit = IsaInterfaceInit;
233
234 //
235 // Install the ISA ACPI Protocol interface
236 //
237 Status = gBS->InstallMultipleProtocolInterfaces (
238 &Controller,
239 &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
240 NULL
241 );
242
243 Done:
244 if (EFI_ERROR (Status)) {
245 if (PciIo) {
246 PciIo->Attributes (
247 PciIo,
248 EfiPciIoAttributeOperationDisable,
249 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
250 NULL
251 );
252 }
253 gBS->CloseProtocol (
254 Controller,
255 &gEfiPciIoProtocolGuid,
256 This->DriverBindingHandle,
257 Controller
258 );
259 if (PcatIsaAcpiDev != NULL) {
260 gBS->FreePool (PcatIsaAcpiDev);
261 }
262 return Status;
263 }
264
265 return EFI_SUCCESS;
266 }
267
268
269 /**
270 Stop this driver on ControllerHandle. Support stopping any child handles
271 created by this driver.
272
273 @param This Protocol instance pointer.
274 @param ControllerHandle Handle of device to stop driver on
275 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
276 children is zero stop the entire bus driver.
277 @param ChildHandleBuffer List of Child Handles to Stop.
278
279 @retval EFI_SUCCESS This driver is removed ControllerHandle
280 @retval other This driver was not removed from this device
281
282 **/
283 EFI_STATUS
284 EFIAPI
285 PcatIsaAcpiDriverBindingStop (
286 IN EFI_DRIVER_BINDING_PROTOCOL *This,
287 IN EFI_HANDLE Controller,
288 IN UINTN NumberOfChildren,
289 IN EFI_HANDLE *ChildHandleBuffer
290 )
291 {
292 EFI_STATUS Status;
293 EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
294 PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;
295
296 //
297 // Get the ISA ACPI Protocol Interface
298 //
299 Status = gBS->OpenProtocol (
300 Controller,
301 &gEfiIsaAcpiProtocolGuid,
302 (VOID**)&IsaAcpi,
303 This->DriverBindingHandle,
304 Controller,
305 EFI_OPEN_PROTOCOL_GET_PROTOCOL
306 );
307 if (EFI_ERROR (Status)) {
308 return Status;
309 }
310
311 //
312 // Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol
313 //
314 PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);
315
316 PcatIsaAcpiDev->PciIo->Attributes (
317 PcatIsaAcpiDev->PciIo,
318 EfiPciIoAttributeOperationDisable,
319 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
320 NULL
321 );
322
323 //
324 // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
325 //
326 Status = gBS->UninstallProtocolInterface (
327 Controller,
328 &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi
329 );
330 if (EFI_ERROR (Status)) {
331 return Status;
332 }
333
334 gBS->CloseProtocol (
335 Controller,
336 &gEfiPciIoProtocolGuid,
337 This->DriverBindingHandle,
338 Controller
339 );
340
341 gBS->FreePool (PcatIsaAcpiDev);
342
343 return EFI_SUCCESS;
344 }