]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Wpce791/LpcDriver.c
MdeModulePkg: Fix use-after-free error in InstallConfigurationTable()
[mirror_edk2.git] / Vlv2TbltDevicePkg / Wpce791 / LpcDriver.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 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 Module Name:
16
17 LpcDriver.c
18
19 Abstract:
20
21 EFI Lpc Driver for a Generic PC Platform
22
23
24
25 --*/
26
27 #include "LpcDriver.h"
28 #include "IndustryStandard/Pci22.h"
29
30 //
31 // This driver is for ACPI(PNP0A03,0)/PCI(0x1f,0)
32 //
33
34 //
35 // Lpc Driver Global Variables
36 //
37
38 EFI_DRIVER_BINDING_PROTOCOL gLpcDriver = {
39 LpcDriverSupported,
40 LpcDriverStart,
41 LpcDriverStop,
42 0x10,
43 NULL,
44 NULL
45 };
46
47 LPC_DEV mLpc = {
48 LPC_DEV_SIGNATURE,
49 NULL,
50 {
51 IsaDeviceEnumerate,
52 IsaDeviceSetPower,
53 IsaGetCurrentResource,
54 IsaGetPossibleResource,
55 IsaSetResource,
56 IsaEnableDevice,
57 IsaInitDevice,
58 LpcInterfaceInit
59 },
60 NULL
61 };
62
63 BOOLEAN InitExecuted = FALSE;
64
65 /**
66 the entry point of the Lpc driver
67
68 **/
69 EFI_STATUS
70 EFIAPI
71 LpcDriverEntryPoint(
72 IN EFI_HANDLE ImageHandle,
73 IN EFI_SYSTEM_TABLE *SystemTable
74 )
75 {
76
77
78 return EfiLibInstallDriverBinding (ImageHandle, SystemTable, &gLpcDriver, ImageHandle);
79 }
80
81 /**
82
83 ControllerDriver Protocol Method
84
85 **/
86 EFI_STATUS
87 EFIAPI
88 LpcDriverSupported (
89 IN EFI_DRIVER_BINDING_PROTOCOL *This,
90 IN EFI_HANDLE Controller,
91 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
92 )
93 {
94 EFI_STATUS Status;
95 EFI_PCI_IO_PROTOCOL *PciIo;
96 EFI_DEVICE_PATH_PROTOCOL *IsaBridgeDevicePath;
97
98 ACPI_HID_DEVICE_PATH *AcpiNode;
99 PCI_DEVICE_PATH *PciNode;
100 PCI_TYPE00 Pci;
101
102 //
103 // Get the ISA bridge's Device Path and test it
104 // the following code is specific
105 //
106 Status = gBS->OpenProtocol (
107 Controller,
108 &gEfiDevicePathProtocolGuid,
109 (VOID **)&IsaBridgeDevicePath,
110 This->DriverBindingHandle,
111 Controller,
112 EFI_OPEN_PROTOCOL_BY_DRIVER
113 );
114
115 if (EFI_ERROR (Status)) {
116 return Status;
117 }
118
119 Status = EFI_SUCCESS;
120 AcpiNode = (ACPI_HID_DEVICE_PATH *)IsaBridgeDevicePath;
121 if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
122 AcpiNode->Header.SubType != ACPI_DP ||
123 DevicePathNodeLength (&AcpiNode->Header) != sizeof(ACPI_HID_DEVICE_PATH) ||
124 AcpiNode -> HID != EISA_PNP_ID(0x0A03) ||
125 AcpiNode -> UID != 0 ) {
126 Status = EFI_UNSUPPORTED;
127 } else {
128 //
129 // Get the next node
130 //
131 IsaBridgeDevicePath = NextDevicePathNode (IsaBridgeDevicePath);
132 PciNode = (PCI_DEVICE_PATH *)IsaBridgeDevicePath;
133 if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
134 PciNode->Header.SubType != HW_PCI_DP ||
135 DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH) ||
136 PciNode -> Function != 0x00 ||
137 PciNode -> Device != 0x1f ) {
138 Status = EFI_UNSUPPORTED;
139 }
140 }
141
142 gBS->CloseProtocol (
143 Controller,
144 &gEfiDevicePathProtocolGuid,
145 This->DriverBindingHandle,
146 Controller
147 );
148
149 if (EFI_ERROR (Status)) {
150 return EFI_UNSUPPORTED;
151 }
152
153 //
154 // Get PciIo protocol instance
155 //
156 Status = gBS->OpenProtocol (
157 Controller,
158 &gEfiPciIoProtocolGuid,
159 (VOID **)&PciIo,
160 This->DriverBindingHandle,
161 Controller,
162 EFI_OPEN_PROTOCOL_BY_DRIVER
163 );
164
165 if (EFI_ERROR(Status)) {
166 return Status;
167 }
168
169 Status = PciIo->Pci.Read (
170 PciIo,
171 EfiPciIoWidthUint32,
172 0,
173 sizeof(Pci) / sizeof(UINT32),
174 &Pci
175 );
176
177 if (!EFI_ERROR (Status)) {
178 Status = EFI_SUCCESS; //TODO: force return success as temp solution EFI_UNSUPPORTED;
179 if ((Pci.Hdr.Command & 0x03) == 0x03) {
180 if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
181 //
182 // See if this is a standard PCI to ISA Bridge from the Base Code
183 // and Class Code
184 //
185 if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
186 Status = EFI_SUCCESS;
187 } else {
188 }
189
190 //
191 // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
192 //
193 if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
194 Pci.Hdr.VendorId == 0x8086 &&
195 Pci.Hdr.DeviceId == 0x7110) {
196 Status = EFI_SUCCESS;
197 } else {
198 }
199 } else {
200 }
201 }
202 else {
203 }
204 }
205
206 gBS->CloseProtocol (
207 Controller,
208 &gEfiPciIoProtocolGuid,
209 This->DriverBindingHandle,
210 Controller
211 );
212 return Status;
213 }
214
215
216 /**
217 Install EFI_ISA_ACPI_PROTOCOL
218
219 **/
220 EFI_STATUS
221 EFIAPI
222 LpcDriverStart (
223 IN EFI_DRIVER_BINDING_PROTOCOL *This,
224 IN EFI_HANDLE Controller,
225 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
226 )
227 {
228 EFI_STATUS Status;
229 EFI_PCI_IO_PROTOCOL *PciIo;
230
231 //
232 // Get Pci IO
233 //
234 Status = gBS->OpenProtocol (
235 Controller,
236 &gEfiPciIoProtocolGuid,
237 (VOID **)&PciIo,
238 This->DriverBindingHandle,
239 Controller,
240 EFI_OPEN_PROTOCOL_BY_DRIVER
241 );
242
243 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
244 return Status;
245 }
246
247 mLpc.PciIo = PciIo;
248
249 //
250 // Install IsaAcpi interface, the Sio interface is not installed!
251 //
252 Status = gBS->InstallMultipleProtocolInterfaces (
253 &Controller,
254 &gEfiIsaAcpiProtocolGuid,
255 &mLpc.IsaAcpi,
256 NULL
257 );
258 return Status;
259 }
260
261
262 EFI_STATUS
263 EFIAPI
264 LpcDriverStop (
265 IN EFI_DRIVER_BINDING_PROTOCOL *This,
266 IN EFI_HANDLE Controller,
267 IN UINTN NumberOfChildren,
268 IN EFI_HANDLE *ChildHandleBuffer
269 )
270 {
271 EFI_STATUS Status;
272 EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
273 LPC_DEV *LpcDev;
274
275 //
276 // Get EFI_ISA_ACPI_PROTOCOL interface
277 //
278 Status = gBS->OpenProtocol (
279 Controller,
280 &gEfiIsaAcpiProtocolGuid,
281 (VOID **)&IsaAcpi,
282 This->DriverBindingHandle,
283 Controller,
284 EFI_OPEN_PROTOCOL_GET_PROTOCOL
285 );
286 if (EFI_ERROR (Status)) {
287 return Status;
288 }
289
290 LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
291
292 //
293 // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
294 //
295 Status = gBS->UninstallProtocolInterface (
296 Controller,
297 &gEfiIsaAcpiProtocolGuid,
298 &LpcDev->IsaAcpi
299 );
300 if (EFI_ERROR (Status)) {
301 return Status;
302 }
303
304 gBS->CloseProtocol (
305 Controller,
306 &gEfiPciIoProtocolGuid,
307 This->DriverBindingHandle,
308 Controller
309 );
310
311 return EFI_SUCCESS;
312 }
313
314 VOID
315 LpcIoRead8 (
316 IN UINT16 Port,
317 OUT UINT8 *Data
318 )
319 {
320 mLpc.PciIo->Io.Read(
321 mLpc.PciIo,
322 EfiPciWidthUint8,
323 EFI_PCI_IO_PASS_THROUGH_BAR,
324 Port,
325 1,
326 Data
327 );
328 }
329
330 VOID
331 LpcIoWrite8 (
332 IN UINT16 Port,
333 IN UINT8 Data
334 )
335 {
336 mLpc.PciIo->Io.Write(
337 mLpc.PciIo,
338 EfiPciWidthUint8,
339 EFI_PCI_IO_PASS_THROUGH_BAR,
340 Port,
341 1,
342 &Data
343 );
344 }
345