• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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