PcatIsaAcpi.c revision 81727f38ed0d37bf6f5110def397220a8c207182
1/*++
2
3Copyright (c) 2006, Intel Corporation
4All rights reserved. This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution.  The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12
13Module Name:
14
15    PcatIsaAcpi.c
16
17Abstract:
18
19    EFI PCAT ISA ACPI Driver for a Generic PC Platform
20
21Revision History
22
23--*/
24
25#include "PcatIsaAcpi.h"
26
27//
28//  PcatIsaAcpi Driver Binding Protocol
29//
30EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding = {
31  PcatIsaAcpiDriverBindingSupported,
32  PcatIsaAcpiDriverBindingStart,
33  PcatIsaAcpiDriverBindingStop,
34  0xa,
35  NULL,
36  NULL
37};
38
39EFI_STATUS
40EFIAPI
41PcatIsaAcpiDriverEntryPoint (
42  IN EFI_HANDLE        ImageHandle,
43  IN EFI_SYSTEM_TABLE  *SystemTable
44  )
45/*++
46
47  Routine Description:
48    the entry point of the PcatIsaAcpi driver
49
50  Arguments:
51
52  Returns:
53
54--*/
55{
56  return EfiLibInstallDriverBindingComponentName2 (
57           ImageHandle,
58           SystemTable,
59           &gPcatIsaAcpiDriverBinding,
60           ImageHandle,
61           &gPcatIsaAcpiComponentName,
62           &gPcatIsaAcpiComponentName2
63           );
64}
65
66EFI_STATUS
67EFIAPI
68PcatIsaAcpiDriverBindingSupported (
69  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
70  IN EFI_HANDLE                   Controller,
71  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
72  )
73/*++
74
75Routine Description:
76
77  ControllerDriver Protocol Method
78
79Arguments:
80
81Returns:
82
83--*/
84{
85  EFI_STATUS           Status;
86  EFI_PCI_IO_PROTOCOL  *PciIo;
87  PCI_TYPE00           Pci;
88
89  //
90  // Get PciIo protocol instance
91  //
92  Status = gBS->OpenProtocol (
93                  Controller,
94                  &gEfiPciIoProtocolGuid,
95                  (VOID**)&PciIo,
96                  This->DriverBindingHandle,
97                  Controller,
98                  EFI_OPEN_PROTOCOL_BY_DRIVER
99                  );
100  if (EFI_ERROR(Status)) {
101    return Status;
102  }
103
104  Status = PciIo->Pci.Read (
105                    PciIo,
106                    EfiPciIoWidthUint32,
107                    0,
108                    sizeof(Pci) / sizeof(UINT32),
109                    &Pci);
110
111  if (!EFI_ERROR (Status)) {
112    Status = EFI_UNSUPPORTED;
113    if ((Pci.Hdr.Command & 0x03) == 0x03) {
114      if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
115        //
116        // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code
117        //
118        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
119          Status = EFI_SUCCESS;
120        }
121
122        //
123        // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
124        //
125        if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
126            Pci.Hdr.VendorId == 0x8086 &&
127            Pci.Hdr.DeviceId == 0x7110) {
128          Status = EFI_SUCCESS;
129        }
130      }
131    }
132  }
133
134  gBS->CloseProtocol (
135         Controller,
136         &gEfiPciIoProtocolGuid,
137         This->DriverBindingHandle,
138         Controller
139         );
140
141  return Status;
142}
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
153Routine Description:
154  Install EFI_ISA_ACPI_PROTOCOL
155
156Arguments:
157
158Returns:
159
160--*/
161{
162  EFI_STATUS           Status;
163  EFI_PCI_IO_PROTOCOL  *PciIo;
164  PCAT_ISA_ACPI_DEV    *PcatIsaAcpiDev;
165
166  PcatIsaAcpiDev = NULL;
167  //
168  // Open the PCI I/O Protocol Interface
169  //
170  PciIo = NULL;
171  Status = gBS->OpenProtocol (
172                  Controller,
173                  &gEfiPciIoProtocolGuid,
174                  (VOID**)&PciIo,
175                  This->DriverBindingHandle,
176                  Controller,
177                  EFI_OPEN_PROTOCOL_BY_DRIVER
178                  );
179  if (EFI_ERROR (Status)) {
180    goto Done;
181  }
182
183  Status = PciIo->Attributes (
184                    PciIo,
185                    EfiPciIoAttributeOperationEnable,
186                    EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
187                    NULL
188                    );
189  if (EFI_ERROR (Status)) {
190    goto Done;
191  }
192
193  //
194  // Allocate memory for the PCAT ISA ACPI Device structure
195  //
196  PcatIsaAcpiDev = NULL;
197  Status = gBS->AllocatePool (
198                  EfiBootServicesData,
199                  sizeof(PCAT_ISA_ACPI_DEV),
200                  (VOID**)&PcatIsaAcpiDev
201                  );
202  if (EFI_ERROR (Status)) {
203    goto Done;
204  }
205
206  //
207  // Initialize the PCAT ISA ACPI Device structure
208  //
209  PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
210  PcatIsaAcpiDev->Handle    = Controller;
211  PcatIsaAcpiDev->PciIo     = PciIo;
212
213  //
214  // IsaAcpi interface
215  //
216  (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate  = IsaDeviceEnumerate;
217  (PcatIsaAcpiDev->IsaAcpi).SetPower         = IsaDeviceSetPower;
218  (PcatIsaAcpiDev->IsaAcpi).GetCurResource   = IsaGetCurrentResource;
219  (PcatIsaAcpiDev->IsaAcpi).GetPosResource   = IsaGetPossibleResource;
220  (PcatIsaAcpiDev->IsaAcpi).SetResource      = IsaSetResource;
221  (PcatIsaAcpiDev->IsaAcpi).EnableDevice     = IsaEnableDevice;
222  (PcatIsaAcpiDev->IsaAcpi).InitDevice       = IsaInitDevice;
223  (PcatIsaAcpiDev->IsaAcpi).InterfaceInit    = IsaInterfaceInit;
224
225  //
226  // Install the ISA ACPI Protocol interface
227  //
228  Status = gBS->InstallMultipleProtocolInterfaces (
229                  &Controller,
230                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
231                  NULL
232                  );
233
234Done:
235  if (EFI_ERROR (Status)) {
236    if (PciIo) {
237      PciIo->Attributes (
238               PciIo,
239               EfiPciIoAttributeOperationDisable,
240               EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
241               NULL
242               );
243    }
244    gBS->CloseProtocol (
245           Controller,
246           &gEfiPciIoProtocolGuid,
247           This->DriverBindingHandle,
248           Controller
249           );
250    if (PcatIsaAcpiDev != NULL) {
251      gBS->FreePool (PcatIsaAcpiDev);
252    }
253    return Status;
254  }
255
256  return EFI_SUCCESS;
257}
258
259EFI_STATUS
260EFIAPI
261PcatIsaAcpiDriverBindingStop (
262  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
263  IN EFI_HANDLE                   Controller,
264  IN UINTN                        NumberOfChildren,
265  IN EFI_HANDLE                   *ChildHandleBuffer
266  )
267/*++
268
269  Routine Description:
270
271  Arguments:
272
273  Returns:
274
275--*/
276{
277  EFI_STATUS             Status;
278  EFI_ISA_ACPI_PROTOCOL  *IsaAcpi;
279  PCAT_ISA_ACPI_DEV      *PcatIsaAcpiDev;
280
281  //
282  // Get the ISA ACPI Protocol Interface
283  //
284  Status = gBS->OpenProtocol (
285                  Controller,
286                  &gEfiIsaAcpiProtocolGuid,
287                  (VOID**)&IsaAcpi,
288                  This->DriverBindingHandle,
289                  Controller,
290                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
291                  );
292  if (EFI_ERROR (Status)) {
293    return Status;
294  }
295
296  //
297  // Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol
298  //
299  PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);
300
301  PcatIsaAcpiDev->PciIo->Attributes (
302                           PcatIsaAcpiDev->PciIo,
303                           EfiPciIoAttributeOperationDisable,
304                           EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
305                           NULL
306                           );
307
308  //
309  // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
310  //
311  Status = gBS->UninstallProtocolInterface (
312                  Controller,
313                  &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi
314                  );
315  if (EFI_ERROR (Status)) {
316    return Status;
317  }
318
319  gBS->CloseProtocol (
320         Controller,
321         &gEfiPciIoProtocolGuid,
322         This->DriverBindingHandle,
323         Controller
324         );
325
326  gBS->FreePool (PcatIsaAcpiDev);
327
328  return EFI_SUCCESS;
329}
330