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