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