PcatIsaAcpi.c revision 95d48e8299e000aefae3c7682039ce2473648940
1/** @file
2  EFI PCAT ISA ACPI Driver for a Generic PC Platform
3
4Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT 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//
20EFI_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**/
37EFI_STATUS
38EFIAPI
39PcatIsaAcpiDriverEntryPoint (
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**/
65EFI_STATUS
66EFIAPI
67PcatIsaAcpiDriverBindingSupported (
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
77  //
78  // Get PciIo protocol instance
79  //
80  Status = gBS->OpenProtocol (
81                  Controller,
82                  &gEfiPciIoProtocolGuid,
83                  (VOID**)&PciIo,
84                  This->DriverBindingHandle,
85                  Controller,
86                  EFI_OPEN_PROTOCOL_BY_DRIVER
87                  );
88  if (EFI_ERROR(Status)) {
89    return Status;
90  }
91
92  Status = PciIo->Pci.Read (
93                    PciIo,
94                    EfiPciIoWidthUint32,
95                    0,
96                    sizeof(Pci) / sizeof(UINT32),
97                    &Pci);
98
99  if (!EFI_ERROR (Status)) {
100    Status = EFI_UNSUPPORTED;
101    if ((Pci.Hdr.Command & 0x03) == 0x03) {
102      if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
103        //
104        // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code
105        //
106        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
107          Status = EFI_SUCCESS;
108        }
109
110        //
111        // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
112        //
113        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
114            Pci.Hdr.VendorId == 0x8086 &&
115            (Pci.Hdr.DeviceId & 0xF000) == 0x7000) {
116          Status = EFI_SUCCESS;
117        }
118      }
119    }
120  }
121
122  gBS->CloseProtocol (
123         Controller,
124         &gEfiPciIoProtocolGuid,
125         This->DriverBindingHandle,
126         Controller
127         );
128
129  return Status;
130}
131
132/**
133  Install EFI_ISA_ACPI_PROTOCOL.
134
135  @param  This                 Driver Binding protocol instance pointer.
136  @param  ControllerHandle     Handle of device to bind driver to.
137  @param  RemainingDevicePath  Optional parameter use to pick a specific child
138                               device to start.
139
140  @retval EFI_SUCCESS          This driver is added to ControllerHandle
141  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
142  @retval other                This driver does not support this device
143**/
144EFI_STATUS
145EFIAPI
146PcatIsaAcpiDriverBindingStart (
147  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
148  IN EFI_HANDLE                   Controller,
149  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
150  )
151{
152  EFI_STATUS           Status;
153  EFI_PCI_IO_PROTOCOL  *PciIo;
154  PCAT_ISA_ACPI_DEV    *PcatIsaAcpiDev;
155
156  PcatIsaAcpiDev = NULL;
157  //
158  // Open the PCI I/O Protocol Interface
159  //
160  PciIo = NULL;
161  Status = gBS->OpenProtocol (
162                  Controller,
163                  &gEfiPciIoProtocolGuid,
164                  (VOID**)&PciIo,
165                  This->DriverBindingHandle,
166                  Controller,
167                  EFI_OPEN_PROTOCOL_BY_DRIVER
168                  );
169  if (EFI_ERROR (Status)) {
170    goto Done;
171  }
172
173  Status = PciIo->Attributes (
174                    PciIo,
175                    EfiPciIoAttributeOperationEnable,
176                    EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
177                    NULL
178                    );
179  if (EFI_ERROR (Status)) {
180    goto Done;
181  }
182
183  //
184  // Allocate memory for the PCAT ISA ACPI Device structure
185  //
186  PcatIsaAcpiDev = NULL;
187  Status = gBS->AllocatePool (
188                  EfiBootServicesData,
189                  sizeof(PCAT_ISA_ACPI_DEV),
190                  (VOID**)&PcatIsaAcpiDev
191                  );
192  if (EFI_ERROR (Status)) {
193    goto Done;
194  }
195
196  //
197  // Initialize the PCAT ISA ACPI Device structure
198  //
199  PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
200  PcatIsaAcpiDev->Handle    = Controller;
201  PcatIsaAcpiDev->PciIo     = PciIo;
202
203  //
204  // IsaAcpi interface
205  //
206  (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate  = IsaDeviceEnumerate;
207  (PcatIsaAcpiDev->IsaAcpi).SetPower         = IsaDeviceSetPower;
208  (PcatIsaAcpiDev->IsaAcpi).GetCurResource   = IsaGetCurrentResource;
209  (PcatIsaAcpiDev->IsaAcpi).GetPosResource   = IsaGetPossibleResource;
210  (PcatIsaAcpiDev->IsaAcpi).SetResource      = IsaSetResource;
211  (PcatIsaAcpiDev->IsaAcpi).EnableDevice     = IsaEnableDevice;
212  (PcatIsaAcpiDev->IsaAcpi).InitDevice       = IsaInitDevice;
213  (PcatIsaAcpiDev->IsaAcpi).InterfaceInit    = IsaInterfaceInit;
214
215  //
216  // Install the ISA ACPI Protocol interface
217  //
218  Status = gBS->InstallMultipleProtocolInterfaces (
219                  &Controller,
220                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
221                  NULL
222                  );
223
224Done:
225  if (EFI_ERROR (Status)) {
226    if (PciIo) {
227      PciIo->Attributes (
228               PciIo,
229               EfiPciIoAttributeOperationDisable,
230               EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
231               NULL
232               );
233    }
234    gBS->CloseProtocol (
235           Controller,
236           &gEfiPciIoProtocolGuid,
237           This->DriverBindingHandle,
238           Controller
239           );
240    if (PcatIsaAcpiDev != NULL) {
241      gBS->FreePool (PcatIsaAcpiDev);
242    }
243    return Status;
244  }
245
246  return EFI_SUCCESS;
247}
248
249
250/**
251  Stop this driver on ControllerHandle. Support stopping any child handles
252  created by this driver.
253
254  @param  This              Protocol instance pointer.
255  @param  ControllerHandle  Handle of device to stop driver on
256  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
257                            children is zero stop the entire bus driver.
258  @param  ChildHandleBuffer List of Child Handles to Stop.
259
260  @retval EFI_SUCCESS       This driver is removed ControllerHandle
261  @retval other             This driver was not removed from this device
262
263**/
264EFI_STATUS
265EFIAPI
266PcatIsaAcpiDriverBindingStop (
267  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
268  IN EFI_HANDLE                   Controller,
269  IN UINTN                        NumberOfChildren,
270  IN EFI_HANDLE                   *ChildHandleBuffer
271  )
272{
273  EFI_STATUS             Status;
274  EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;
275  PCAT_ISA_ACPI_DEV      *PcatIsaAcpiDev;
276
277  //
278  // Get the ISA ACPI Protocol Interface
279  //
280  Status = gBS->OpenProtocol (
281                  Controller,
282                  &gEfiIsaAcpiProtocolGuid,
283                  (VOID**)&IsaAcpi,
284                  This->DriverBindingHandle,
285                  Controller,
286                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
287                  );
288  if (EFI_ERROR (Status)) {
289    return Status;
290  }
291
292  //
293  // Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol
294  //
295  PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);
296
297  PcatIsaAcpiDev->PciIo->Attributes (
298                           PcatIsaAcpiDev->PciIo,
299                           EfiPciIoAttributeOperationDisable,
300                           EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
301                           NULL
302                           );
303
304  //
305  // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
306  //
307  Status = gBS->UninstallProtocolInterface (
308                  Controller,
309                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi
310                  );
311  if (EFI_ERROR (Status)) {
312    return Status;
313  }
314
315  gBS->CloseProtocol (
316         Controller,
317         &gEfiPciIoProtocolGuid,
318         This->DriverBindingHandle,
319         Controller
320         );
321
322  gBS->FreePool (PcatIsaAcpiDev);
323
324  return EFI_SUCCESS;
325}
326