Program SD Cards into 4-bit mode (support for this is required in the spec). This...
[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
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 **/
144 EFI_STATUS
145 EFIAPI
146 PcatIsaAcpiDriverBindingStart (
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
224 Done:
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 **/
264 EFI_STATUS
265 EFIAPI
266 PcatIsaAcpiDriverBindingStop (
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 }