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 Module Name:
24 
25     LpcIsaAcpi.c
26 
27 Abstract: IsaAcpi implementation
28 
29 
30 
31 --*/
32 
33 #include "LpcDriver.h"
34 
35 //
36 // PS/2 Keyboard Controller
37 //
38 static EFI_ISA_ACPI_RESOURCE  mLpcWpce791Ps2KeyboardDeviceResources[] = {
39   {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},
40   {EfiIsaAcpiResourceInterrupt, 0, 1,     0},
41   {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
42 };
43 
44 //
45 // PS/2 Mouse Controller
46 //
47 static EFI_ISA_ACPI_RESOURCE  mLpcWpce791Ps2MouseDeviceResources[] = {
48   {EfiIsaAcpiResourceIo,        0, 0x60, 0x64},
49   {EfiIsaAcpiResourceInterrupt, 0, 12,     0},
50   {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
51 };
52 
53 //
54 // COM
55 //
56 static EFI_ISA_ACPI_RESOURCE  mLpcWpce791ComDeviceResources[] = {
57   {EfiIsaAcpiResourceIo,        0, 0x3f8, 0x3ff},
58   {EfiIsaAcpiResourceInterrupt, 0, 4,     0},
59   {EfiIsaAcpiResourceEndOfList, 0, 0,     0}
60 };
61 
62 //
63 // Table of ISA Controllers
64 //
65 EFI_ISA_ACPI_RESOURCE_LIST mLpcWpce791DeviceList[] = {
66   {{EISA_PNP_ID(0x303), 0}, mLpcWpce791Ps2KeyboardDeviceResources }, // PS/2 Keyboard Controller
67   {{EISA_PNP_ID(0xF03), 0}, mLpcWpce791Ps2MouseDeviceResources	  }, // PS/2 Mouse Controller
68   {{EISA_PNP_ID(0x501), 0}, mLpcWpce791ComDeviceResources	      }, // COM
69   {{0,                  0}, NULL                                  }  // End
70 };
71 
72 static ICH_DMA_INIT  mIchDmaInitTable [] = {
73 //
74 //Register OFFSET,           Value
75 //
76 
77             0x0D8,           0x000,   // Reset DMA Controller 2
78             0x0D0,           0x000,   // Enable DMA controller 2
79             0x00C,           0x000,   // Reset DMA Controller 1
80             0x008,           0x000,   // Enable DMA controller 1
81 
82             //
83             // Channel 4
84             //
85             0x0D6,           0x0c0,   // DMA contr. 2 Cascade mode, addr. increment, disable auto init.
86             0x0D2,           0x000,   // Clear write request register
87             0x0d4,           0x000,   // Enable DREQs for channel
88 
89             //
90             // Channel 0
91             //
92             0x00B,           0x040,   // DMA contr. 1 single mode, addr. increment, disable auto init.
93             0x009,           0x000,   // Clear write request register
94             0x00A,           0x000,   // Enable DREQs for channel
95 
96             //
97             // Channel 1
98             //
99             0x00B,           0x041,   // DMA contr. 1 single mode, addr. increment, disable auto init.
100             0x009,           0x001,   // Clear write request register
101             0x00A,           0x001,   // Enable DREQs for channel
102 
103             //
104             // Channel 2
105             //
106             0x00B,           0x042,   // DMA contr. 1 single mode, addr. increment, disable auto init.
107             0x009,           0x002,   // Clear write request register
108             0x00A,           0x002,   // Enable DREQs for channel
109 
110             //
111             // Channel 3
112             //
113             0x00B,           0x043,   // DMA contr. 1 single mode, addr. increment, disable auto init.
114             0x009,           0x003,   // Clear write request register
115             0x00A,           0x003,   // Enable DREQs for channel
116 
117             //
118             // Channel 5
119             //
120             0x0D6,           0x041,   // DMA contr. 2 single mode, addr. increment, disable auto init.
121             0x0D2,           0x001,   // Clear write request register
122             0x0D4,           0x001,   // Enable DREQs for channel
123 
124             //
125             // Channel 6
126             //
127             0x0D6,           0x042,   // DMA contr. 2 single mode, addr. increment, disable auto init.
128             0x0D2,           0x002,   // Clear write request register
129             0x0D4,           0x002,   // Enable DREQs for channel
130 
131             //
132             // Channel 7
133             //
134             0x0D6,           0x043,   // DMA contr. 2 single mode, addr. increment, disable auto init.
135             0x0D2,           0x003,   // Clear write request register
136             0x0D4,           0x003    // Enable DREQs for channel
137 
138 };
139 
IsaDeviceLookup(IN EFI_ISA_ACPI_DEVICE_ID * Device,OUT EFI_ISA_ACPI_RESOURCE_LIST ** IsaAcpiDevice,OUT EFI_ISA_ACPI_RESOURCE_LIST ** NextIsaAcpiDevice)140 //
141 // ISA ACPI Protocol Functions
142 //
143 /**
144 
145   Enumerate the ISA devices on the ISA bus
146 
147 **/
148 VOID
149 IsaDeviceLookup (
150   IN  EFI_ISA_ACPI_DEVICE_ID      *Device,
151   OUT EFI_ISA_ACPI_RESOURCE_LIST  **IsaAcpiDevice,
152   OUT EFI_ISA_ACPI_RESOURCE_LIST  **NextIsaAcpiDevice
153   )
154 {
155   UINTN  Index;
156 
157   *IsaAcpiDevice = NULL;
158   if (NextIsaAcpiDevice != NULL) {
159     *NextIsaAcpiDevice = NULL;
160   }
161   if (Device == NULL) {
162     Index = 0;
163   } else {
164     for(Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
165       if (Device->HID == mLpcWpce791DeviceList[Index].Device.HID &&
166           Device->UID == mLpcWpce791DeviceList[Index].Device.UID    ) {
167         break;
168       }
169     }
170     if (mLpcWpce791DeviceList[Index].Device.HID == 0) {
171       return;
172     }
173     *IsaAcpiDevice = &(mLpcWpce791DeviceList[Index]);
174     Index++;
175   }
176   if (NextIsaAcpiDevice != NULL && mLpcWpce791DeviceList[Index].Device.HID != 0){
177     *NextIsaAcpiDevice = &(mLpcWpce791DeviceList[Index]);
178   }
179 }
IsaDeviceEnumerate(IN EFI_ISA_ACPI_PROTOCOL * This,OUT EFI_ISA_ACPI_DEVICE_ID ** Device)180 
181 
182 /**
183   Enumerate the ISA devices on the ISA bus
184   It is hard code now and future it will get from ACPI table
185 
186 **/
187 EFI_STATUS
188 EFIAPI
189 IsaDeviceEnumerate (
190   IN     EFI_ISA_ACPI_PROTOCOL       *This,
191   OUT    EFI_ISA_ACPI_DEVICE_ID      **Device
192   )
193 {
194   EFI_ISA_ACPI_RESOURCE_LIST  *IsaAcpiDevice;
195   EFI_ISA_ACPI_RESOURCE_LIST  *NextIsaAcpiDevice;
196 
197   IsaDeviceLookup (*Device, &IsaAcpiDevice, &NextIsaAcpiDevice);
198   if (NextIsaAcpiDevice == NULL) {
199     return EFI_NOT_FOUND;
200   }
201   *Device = &(NextIsaAcpiDevice->Device);
202   return EFI_SUCCESS;
203 }
204 
205 /**
206   Set ISA device power use sio
207 
208 **/
209 EFI_STATUS
210 EFIAPI
211 IsaDeviceSetPower (
212   IN     EFI_ISA_ACPI_PROTOCOL       *This,
213   IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
214   IN     BOOLEAN                     OnOff
215   )
216 {
217   return EFI_UNSUPPORTED;
218 }
IsaGetCurrentResource(IN EFI_ISA_ACPI_PROTOCOL * This,IN EFI_ISA_ACPI_DEVICE_ID * Device,OUT EFI_ISA_ACPI_RESOURCE_LIST ** ResourceList)219 
220 
221 /**
222   Get current Resource of the specific ISA device
223   It is hardcode now and future will get from ACPI table
224 
225 **/
226 EFI_STATUS
227 EFIAPI
228 IsaGetCurrentResource (
229   IN     EFI_ISA_ACPI_PROTOCOL        *This,
230   IN     EFI_ISA_ACPI_DEVICE_ID       *Device,
231   OUT    EFI_ISA_ACPI_RESOURCE_LIST   **ResourceList
232   )
233 {
234   IsaDeviceLookup (Device, ResourceList, NULL);
235   if (*ResourceList == NULL || (*ResourceList)->ResourceItem == NULL) {
236     return EFI_NOT_FOUND;
237   }
238   return EFI_SUCCESS;
239 }
240 
241 EFI_STATUS
242 EFIAPI
243 IsaGetPossibleResource (
244   IN     EFI_ISA_ACPI_PROTOCOL       *This,
245   IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
246   OUT    EFI_ISA_ACPI_RESOURCE_LIST  **ResourceList
247   )
248 {
IsaSetResource(IN EFI_ISA_ACPI_PROTOCOL * This,IN EFI_ISA_ACPI_DEVICE_ID * Device,IN EFI_ISA_ACPI_RESOURCE_LIST * ResourceList)249   //
250   // Not supported yet
251   //
252   return EFI_UNSUPPORTED;
253 }
254 
255 
256 EFI_STATUS
257 EFIAPI
258 IsaSetResource (
259   IN     EFI_ISA_ACPI_PROTOCOL       *This,
IsaEnableDevice(IN EFI_ISA_ACPI_PROTOCOL * This,IN EFI_ISA_ACPI_DEVICE_ID * Device,IN BOOLEAN Enable)260   IN     EFI_ISA_ACPI_DEVICE_ID      *Device,
261   IN     EFI_ISA_ACPI_RESOURCE_LIST  *ResourceList
262   )
263 {
264   return EFI_UNSUPPORTED;
265 }
266 
267 EFI_STATUS
268 EFIAPI
269 IsaEnableDevice (
270   IN    EFI_ISA_ACPI_PROTOCOL        *This,
271   IN    EFI_ISA_ACPI_DEVICE_ID       *Device,
272   IN    BOOLEAN                      Enable
273   )
274 {
275 
EmptyResourceList(IN UINT32 DeviceHid)276   return EFI_UNSUPPORTED;
277 }
278 
279 /**
280 
281   Clear out Resource List if device is set to disable by platform policy
282 
283 **/
284 VOID
285 EmptyResourceList (
286   IN  UINT32      DeviceHid
287   )
288 {
289   UINT8     Index;
290   for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
291     if (DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) {
292       mLpcWpce791DeviceList[Index].ResourceItem = NULL;
293     }
294   }
EmptyResourceListHidUid(IN UINT32 DeviceHid,IN UINT32 DeviceUid)295   return;
296 }
297 
298 /**
299 
300   Clear out Resource List if device is set to disable by platform policy
301 
302 **/
303 VOID
304 EmptyResourceListHidUid (
305   IN  UINT32      DeviceHid,
306   IN  UINT32      DeviceUid
307   )
308 {
309   UINT8     Index;
310   for (Index = 0; mLpcWpce791DeviceList[Index].Device.HID != 0; Index++) {
311     if ((DeviceHid == mLpcWpce791DeviceList[Index].Device.HID) &&
IsaInitDevice(IN EFI_ISA_ACPI_PROTOCOL * This,IN EFI_ISA_ACPI_DEVICE_ID * Device)312         (DeviceUid == mLpcWpce791DeviceList[Index].Device.UID)) {
313       mLpcWpce791DeviceList[Index].ResourceItem = NULL;
314     }
315   }
316   return;
317 }
318 
319 EFI_STATUS
320 EFIAPI
321 IsaInitDevice (
322   IN    EFI_ISA_ACPI_PROTOCOL        *This,
323   IN    EFI_ISA_ACPI_DEVICE_ID       *Device
324   )
325 {
326   EFI_WPCE791_POLICY_PROTOCOL      *LpcWpce791Policy;
327   EFI_STATUS                      Status;
328 
329   //
330   // Disable configuration according to platform protocol
331   //
332   Status = gBS->LocateProtocol (
333                   &gEfiLpcWpce791PolicyProtocolGuid,
334                   NULL,
335                   (VOID **) &LpcWpce791Policy
336                   );
337   if (!EFI_ERROR(Status)) {
338     if (LpcWpce791Policy->DeviceEnables.Ps2Keyboard == EFI_WPCE791_PS2_KEYBOARD_DISABLE) {
339       EmptyResourceList(EISA_PNP_ID(0x303));
340       DisableLogicalDevice (SIO_KEYBOARD);
341       EmptyResourceList(EISA_PNP_ID(0xF03));
342       DisableLogicalDevice (SIO_KEYBOARD);
343     }
344     if (LpcWpce791Policy->DeviceEnables.Ps2Mouse == EFI_WPCE791_PS2_MOUSE_DISABLE) {
345       EmptyResourceList(EISA_PNP_ID(0xF03));
LpcInterfaceInit(IN EFI_ISA_ACPI_PROTOCOL * This)346       DisableLogicalDevice (SIO_MOUSE);
347     }
348   }
349 
350   return EFI_SUCCESS;
351 }
352 
353 EFI_STATUS
354 EFIAPI
355 LpcInterfaceInit (
356   IN    EFI_ISA_ACPI_PROTOCOL        *This
357   )
358 {
359   EFI_PCI_IO_PROTOCOL             *PciIo;
360   UINTN                           Index;
361 
362   PciIo = (LPC_ISA_ACPI_FROM_THIS (This))->PciIo;
363 
364   //
365   // DMA controller initialize
366   //
367   for (Index=0; Index < (sizeof(mIchDmaInitTable)/sizeof(ICH_DMA_INIT)); Index++) {
368     PciIo->Io.Write (
369                 PciIo,
370                 EfiPciIoWidthUint8,
371                 EFI_PCI_IO_PASS_THROUGH_BAR,
372                 mIchDmaInitTable[Index].Register,
373                 1,
374                 &mIchDmaInitTable[Index].Value
375                 );
376   }
377 
378   return EFI_SUCCESS;
379 }
380 
381