1 /** @file
2   Super I/O specific implementation.
3 
4   Copyright (c) 2010 - 2020 Intel Corporation. All rights reserved. <BR>
5 
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 **/
8 
9 #include "SioDriver.h"
10 
11 //
12 // System configuration (setup) information
13 //
14 // SYSTEM_CONFIGURATION                mSystemConfiguration;
15 
16 //
17 // COM 1 UART Controller
18 //
19 ACPI_SIO_RESOURCES_IO_IRQ      mCom1Resources = {
20   {
21     { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
22       FixedPcdGet16 (PcdUart1IoPort),
23       FixedPcdGet8 (PcdUart1Length)
24     },
25     {
26       { ACPI_IRQ_NOFLAG_DESCRIPTOR },
27       FixedPcdGet16 (PcdUart1IrqMask)
28     },
29     {
30       ACPI_END_TAG_DESCRIPTOR,
31       0
32     }
33 };
gistfillbuffer(Page page,IndexTuple * itup,int len,OffsetNumber off)34 
35 //
36 // COM 2 UART Controller
37 //
38 ACPI_SIO_RESOURCES_IO_IRQ      mCom2Resources = {
39   {
40     { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
41     FixedPcdGet16 (PcdUart2IoPort),
42     FixedPcdGet8 (PcdUart2Length)
43   },
44   {
45     { ACPI_IRQ_NOFLAG_DESCRIPTOR },
46     FixedPcdGet16 (PcdUart2IrqMask),
47   },
48   {
49     ACPI_END_TAG_DESCRIPTOR,
50     0
51   }
52 };
53 
54 //
55 // PS/2 Keyboard Controller
56 //
57 ACPI_SIO_RESOURCES_IO_IRQ      mKeyboardResources = {
58   {
gistnospace(Page page,IndexTuple * itvec,int len,OffsetNumber todelete,Size freespace)59     { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
60     0x60,
61     5
62   },
63   {
64     { ACPI_IRQ_NOFLAG_DESCRIPTOR },
65     BIT1
66   },
67   {
68     ACPI_END_TAG_DESCRIPTOR,
69     0
70   }
71 };
72 
73 //
74 // PS/2 Mouse Controller
75 //
76 ACPI_SIO_RESOURCES_IO_IRQ      mMouseResources = {
77   {
78     { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR },
gistfitpage(IndexTuple * itvec,int len)79     0x60,
80     5
81   },
82   {
83     { ACPI_IRQ_NOFLAG_DESCRIPTOR },
84     BIT12
85   },
86   {
87     ACPI_END_TAG_DESCRIPTOR,
88     0
89   }
90 };
91 
92 //
93 // Table of SIO Controllers
94 //
gistextractpage(Page page,int * len)95 DEVICE_INFO    mDeviceInfo[] = {
96 #if FixedPcdGet8 (PcdUart1Enable) == DEVICE_ENABLED
97   {
98     {
99       EISA_PNP_ID(0x501),
100       0
101     },
102     0,
103     RESOURCE_IO | RESOURCE_IRQ,
104     { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources },
105     { (ACPI_SMALL_RESOURCE_HEADER *) &mCom1Resources }
106   },  // COM 1 UART Controller
107 #endif
108 #if FixedPcdGet8 (PcdUart2Enable) == DEVICE_ENABLED
109   {
110     {
111       EISA_PNP_ID(0x501),
112       0
113     },
114     0,
115     RESOURCE_IO | RESOURCE_IRQ,
116     { (ACPI_SMALL_RESOURCE_HEADER *) &mCom2Resources },
117     { (ACPI_SMALL_RESOURCE_HEADER *) &mCom2Resources }
118   },  // COM 2 UART Controller
119 #endif
120 #if FixedPcdGet8 (PcdPs2KbMsEnable) == DEVICE_ENABLED
121   {
122     {
123       EISA_PNP_ID(0x303),
124       0
125     },
126     0,
127     0,  // Cannot change resource
128     { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources },
129     { (ACPI_SMALL_RESOURCE_HEADER *) &mKeyboardResources }
130   },  // PS/2 Keyboard Controller
131   {
132     {
133       EISA_PNP_ID(0xF03),
134       0
135     },
136     0,
137     0,  // Cannot change resource
138     { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources },
139     { (ACPI_SMALL_RESOURCE_HEADER *) &mMouseResources }
140   },  // PS/2 Mouse Controller
141 #endif
142   DEVICE_INFO_END
143 };
144 
145 
146 
147 /**
148   Gets the number of devices in Table of SIO Controllers mDeviceInfo.
149 
150   @retval     Number of enabled devices in Table of SIO Controllers.
151 **/
152 UINTN
153 EFIAPI
154 GetDeviceCount (
gistMakeUnionItVec(GISTSTATE * giststate,IndexTuple * itvec,int len,Datum * attr,bool * isnull)155   VOID
156   )
157 {
158    UINTN        Count;
159    // Get mDeviceInfo item count
160    // -1 to account for for the end device info
161    Count = ARRAY_SIZE (mDeviceInfo) - 1;
162    return Count;
163 }
164 
165 /**
166   Return the supported devices.
167 
168   @param[out] Devices         Pointer to pointer of EFI_SIO_ACPI_DEVICE_ID.
169                               Caller is responsible to free the buffer.
170   @param[out] Count           Pointer to UINTN holding the device count.
171 **/
172 VOID
173 DeviceGetList (
174   OUT EFI_SIO_ACPI_DEVICE_ID **Devices,
175   OUT UINTN                  *Count
176   )
177 {
178   EFI_SIO_ACPI_DEVICE_ID   *LocalDevices;
179   UINTN                    LocalCount;
180   UINTN                    DeviceCount;
181   UINTN                    Index;
182 
183   //
184   // Allocate enough memory for simplicity
185   //
186   DeviceCount = GetDeviceCount ();
187   LocalDevices = AllocatePool (sizeof (EFI_SIO_ACPI_DEVICE_ID) * DeviceCount);
188   ASSERT (LocalDevices != NULL);
189   if (LocalDevices == NULL) {
190     return;
191   }
192   LocalCount = 0;
193 
194   for (Index = 0; Index < DeviceCount; Index++) {
195     CopyMem (&LocalDevices[LocalCount], &mDeviceInfo[Index].Device, sizeof (EFI_SIO_ACPI_DEVICE_ID));
196     LocalCount++;
197   }
198 
199   *Devices = LocalDevices;
200   *Count   = LocalCount;
201 }
202 
203 
204 /**
205   Super I/O controller initialization.
206 
207   @retval     EFI_SUCCESS       The super I/O controller is found and initialized.
208   @retval     EFI_UNSUPPORTED   The super I/O controller is not found.
209 **/
210 EFI_STATUS
211 SioInit (
212   VOID
213   )
214 {
215   return EFI_SUCCESS;
216 }
217 
218 
gistunion(Relation r,IndexTuple * itvec,int len,GISTSTATE * giststate)219 /**
220   Find the DEVICE_INFO for specified Device.
221 
222   @param[in]  Device        Pointer to the EFI_SIO_ACPI_DEVICE_ID.
223 
224   @retval     DEVICE_INFO*  Pointer to the DEVICE_INFO.
225 **/
226 DEVICE_INFO *
227 DeviceSearch (
228   IN EFI_SIO_ACPI_DEVICE_ID *Device
229   )
230 {
231   UINTN       Index;
232   UINTN       DeviceCount;
233 
234   DeviceCount = GetDeviceCount ();
235   for (Index = 0; Index < DeviceCount; Index++) {
236     if (CompareMem (Device, &mDeviceInfo[Index].Device, sizeof (*Device)) == 0) {
237       return &mDeviceInfo[Index];
238     }
239   }
240 
241   ASSERT (FALSE);
242   return NULL;
243 }
244 
245 
246 /**
247   Program the SIO chip to enable the specified device using the default resource.
248 
249   @param[in] Device          Pointer to EFI_SIO_ACPI_DEVICE_ID.
250 **/
251 VOID
252 DeviceEnable (
253   IN EFI_SIO_ACPI_DEVICE_ID   *Device
254   )
255 {
256 }
257 
258 
259 /**
260   Get the ACPI resources for specified device.
261 
262   @param[in]  Device          Pointer to EFI_SIO_ACPI_DEVICE_ID.
263   @param[out] Resources       Pointer to ACPI_RESOURCE_HEADER_PTR.
264 
265   @retval     EFI_SUCCESS     The resources are returned successfully.
266 **/
267 EFI_STATUS
268 DeviceGetResources (
269   IN  EFI_SIO_ACPI_DEVICE_ID   *Device,
270   OUT ACPI_RESOURCE_HEADER_PTR *Resources
271   )
272 {
273   DEVICE_INFO               *DeviceInfo;
274 
275   DeviceInfo = DeviceSearch (Device);
276 
277   *Resources = DeviceInfo->Resources;
278 
279   return EFI_SUCCESS;
280 }
gistKeyIsEQ(GISTSTATE * giststate,int attno,Datum a,Datum b)281 
282 
283 /**
284   Set the ACPI resources for specified device.
285 
286   The SIO chip is programmed to use the new resources and the
287   resources setting are saved. The function assumes the resources
288   are valid.
289 
290   @param[in] Device          Pointer to EFI_SIO_ACPI_DEVICE_ID.
291   @param[in] Resources       ACPI_RESOURCE_HEADER_PTR.
292 
293   @retval    EFI_UNSUPPORTED
294 **/
295 EFI_STATUS
296 DeviceSetResources (
297   IN EFI_SIO_ACPI_DEVICE_ID   *Device,
298   IN ACPI_RESOURCE_HEADER_PTR Resources
299   )
300 {
301   return EFI_UNSUPPORTED;
302 }
303 
304 
305 /**
306   Get the possible ACPI resources for specified device.
307 
308   @param[in]  Device          Pointer to EFI_SIO_ACPI_DEVICE_ID.
309   @param[out] Resources       Pointer to ACPI_RESOURCE_HEADER_PTR.
310 
311   @retval     EFI_SUCCESS     The resources are returned successfully.
312 **/
313 EFI_STATUS
314 DevicePossibleResources (
315   IN  EFI_SIO_ACPI_DEVICE_ID   *Device,
gistgetadjusted(Relation r,IndexTuple oldtup,IndexTuple addtup,GISTSTATE * giststate)316   OUT ACPI_RESOURCE_HEADER_PTR *Resources
317   )
318 {
319   DEVICE_INFO               *DeviceInfo;
320 
321   DeviceInfo = DeviceSearch (Device);
322 
323   *Resources = DeviceInfo->PossibleResources;
324 
325   return EFI_SUCCESS;
326 }
327