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
240 //
241 // Get Pci IO
242 //
243 Status = gBS->OpenProtocol (
244 Controller,
245 &gEfiPciIoProtocolGuid,
246 (VOID **)&PciIo,
247 This->DriverBindingHandle,
248 Controller,
249 EFI_OPEN_PROTOCOL_BY_DRIVER
250 );
251
252 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
253 return Status;
254 }
255
256 mLpc.PciIo = PciIo;
257
258 //
259 // Install IsaAcpi interface, the Sio interface is not installed!
260 //
261 Status = gBS->InstallMultipleProtocolInterfaces (
262 &Controller,
263 &gEfiIsaAcpiProtocolGuid,
LpcDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)264 &mLpc.IsaAcpi,
265 NULL
266 );
267 return Status;
268 }
269
270
271 EFI_STATUS
272 EFIAPI
273 LpcDriverStop (
274 IN EFI_DRIVER_BINDING_PROTOCOL *This,
275 IN EFI_HANDLE Controller,
276 IN UINTN NumberOfChildren,
277 IN EFI_HANDLE *ChildHandleBuffer
278 )
279 {
280 EFI_STATUS Status;
281 EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
282 LPC_DEV *LpcDev;
283
284 //
285 // Get EFI_ISA_ACPI_PROTOCOL interface
286 //
287 Status = gBS->OpenProtocol (
288 Controller,
289 &gEfiIsaAcpiProtocolGuid,
290 (VOID **)&IsaAcpi,
291 This->DriverBindingHandle,
292 Controller,
293 EFI_OPEN_PROTOCOL_GET_PROTOCOL
294 );
295 if (EFI_ERROR (Status)) {
296 return Status;
297 }
298
299 LpcDev = LPC_ISA_ACPI_FROM_THIS (IsaAcpi);
300
301 //
302 // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
303 //
304 Status = gBS->UninstallProtocolInterface (
305 Controller,
306 &gEfiIsaAcpiProtocolGuid,
307 &LpcDev->IsaAcpi
308 );
309 if (EFI_ERROR (Status)) {
310 return Status;
311 }
312
313 gBS->CloseProtocol (
314 Controller,
LpcIoRead8(IN UINT16 Port,OUT UINT8 * Data)315 &gEfiPciIoProtocolGuid,
316 This->DriverBindingHandle,
317 Controller
318 );
319
320 return EFI_SUCCESS;
321 }
322
323 VOID
324 LpcIoRead8 (
325 IN UINT16 Port,
326 OUT UINT8 *Data
327 )
328 {
329 mLpc.PciIo->Io.Read(
330 mLpc.PciIo,
LpcIoWrite8(IN UINT16 Port,IN UINT8 Data)331 EfiPciWidthUint8,
332 EFI_PCI_IO_PASS_THROUGH_BAR,
333 Port,
334 1,
335 Data
336 );
337 }
338
339 VOID
340 LpcIoWrite8 (
341 IN UINT16 Port,
342 IN UINT8 Data
343 )
344 {
345 mLpc.PciIo->Io.Write(
346 mLpc.PciIo,
347 EfiPciWidthUint8,
348 EFI_PCI_IO_PASS_THROUGH_BAR,
349 Port,
350 1,
351 &Data
352 );
353 }
354
355