]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/SioBusDxe/SioService.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / SioBusDxe / SioService.c
CommitLineData
a5cc178a
HW
1/** @file\r
2 The SioBusDxe driver is used to create child devices on the ISA bus and\r
3 installs the Super I/O protocols on them.\r
4\r
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
6\r
b26f0cf9 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a5cc178a
HW
8\r
9**/\r
10\r
11#include "SioBusDxe.h"\r
12\r
13//\r
14// Super I/O Protocol interfaces\r
15//\r
ac0a286f 16EFI_SIO_PROTOCOL mSioInterface = {\r
a5cc178a
HW
17 SioRegisterAccess,\r
18 SioGetResources,\r
19 SioSetResources,\r
20 SioPossibleResources,\r
21 SioModify\r
22};\r
23\r
24//\r
25// COM 1 UART Controller\r
26//\r
27GLOBAL_REMOVE_IF_UNREFERENCED\r
ac0a286f
MK
28SIO_RESOURCES_IO mCom1Resources = {\r
29 {\r
30 { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, 0x3F8, 8\r
31 },\r
32 { ACPI_END_TAG_DESCRIPTOR, 0 }\r
a5cc178a
HW
33};\r
34\r
35//\r
36// COM 2 UART Controller\r
37//\r
38GLOBAL_REMOVE_IF_UNREFERENCED\r
ac0a286f
MK
39SIO_RESOURCES_IO mCom2Resources = {\r
40 {\r
41 { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, 0x2F8, 8\r
42 },\r
43 { ACPI_END_TAG_DESCRIPTOR, 0 }\r
a5cc178a
HW
44};\r
45\r
46//\r
47// PS/2 Keyboard Controller\r
48//\r
49GLOBAL_REMOVE_IF_UNREFERENCED\r
ac0a286f
MK
50SIO_RESOURCES_IO mPs2KeyboardDeviceResources = {\r
51 {\r
52 { ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR }, 0x60, 5\r
53 },\r
54 { ACPI_END_TAG_DESCRIPTOR, 0 }\r
a5cc178a
HW
55};\r
56\r
57//\r
58// Table of SIO Controllers\r
59//\r
60GLOBAL_REMOVE_IF_UNREFERENCED\r
ac0a286f 61SIO_DEVICE_INFO mDevicesInfo[] = {\r
a5cc178a
HW
62 {\r
63 EISA_PNP_ID (0x501),\r
64 0,\r
ac0a286f 65 { (ACPI_SMALL_RESOURCE_HEADER *)&mCom1Resources }\r
a5cc178a
HW
66 }, // COM 1 UART Controller\r
67 {\r
68 EISA_PNP_ID (0x501),\r
69 1,\r
ac0a286f 70 { (ACPI_SMALL_RESOURCE_HEADER *)&mCom2Resources }\r
a5cc178a
HW
71 }, // COM 2 UART Controller\r
72 {\r
ac0a286f 73 EISA_PNP_ID (0x303),\r
a5cc178a 74 0,\r
ac0a286f 75 { (ACPI_SMALL_RESOURCE_HEADER *)&mPs2KeyboardDeviceResources }\r
a5cc178a
HW
76 } // PS/2 Keyboard Controller\r
77};\r
78\r
79//\r
80// ACPI Device Path Node template\r
81//\r
82GLOBAL_REMOVE_IF_UNREFERENCED\r
ac0a286f 83ACPI_HID_DEVICE_PATH mAcpiDeviceNodeTemplate = {\r
a5cc178a
HW
84 { // Header\r
85 ACPI_DEVICE_PATH,\r
86 ACPI_DP,\r
87 {\r
ac0a286f
MK
88 (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),\r
89 (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)\r
a5cc178a
HW
90 }\r
91 },\r
92 0x0, // HID\r
93 0x0 // UID\r
94};\r
95\r
a5cc178a
HW
96/**\r
97 Provides a low level access to the registers for the Super I/O.\r
98\r
99 @param[in] This Indicates a pointer to the calling context.\r
100 @param[in] Write Specifies the type of the register operation.\r
101 If this parameter is TRUE, Value is interpreted\r
102 as an input parameter and the operation is a\r
103 register write. If this parameter is FALSE,\r
104 Value is interpreted as an output parameter and\r
105 the operation is a register read.\r
106 @param[in] ExitCfgMode Exit Configuration Mode Indicator. If this\r
107 parameter is set to TRUE, the Super I/O driver\r
108 will turn off configuration mode of the Super\r
109 I/O prior to returning from this function. If\r
110 this parameter is set to FALSE, the Super I/O\r
111 driver will leave Super I/O in the\r
112 configuration mode. The Super I/O driver must\r
113 track the current state of the Super I/O and\r
114 enable the configuration mode of Super I/O if\r
115 necessary prior to register access.\r
116 @param[in] Register Register number.\r
117 @param[in,out] Value If Write is TRUE, Value is a pointer to the\r
118 buffer containing the byte of data to be\r
119 written to the Super I/O register. If Write is\r
120 FALSE, Value is a pointer to the destination\r
121 buffer for the byte of data to be read from the\r
122 Super I/O register.\r
123\r
124 @retval EFI_SUCCESS The operation completed successfully.\r
125 @retval EFI_INVALID_PARAMETER The Value is NULL.\r
126 @retval EFI_INVALID_PARAMETER Invalid Register number.\r
127\r
128**/\r
129EFI_STATUS\r
130EFIAPI\r
131SioRegisterAccess (\r
ac0a286f
MK
132 IN CONST EFI_SIO_PROTOCOL *This,\r
133 IN BOOLEAN Write,\r
134 IN BOOLEAN ExitCfgMode,\r
135 IN UINT8 Register,\r
136 IN OUT UINT8 *Value\r
a5cc178a
HW
137 )\r
138{\r
139 return EFI_SUCCESS;\r
140}\r
141\r
142/**\r
143 Provides an interface to get a list of the current resources consumed by the\r
144 device in the ACPI Resource Descriptor format.\r
145\r
146 GetResources() returns a list of resources currently consumed by the device.\r
147 The ResourceList is a pointer to the buffer containing resource descriptors\r
148 for the device. The descriptors are in the format of Small or Large ACPI\r
149 resource descriptor as defined by ACPI specification (2.0 & 3.0). The buffer\r
150 of resource descriptors is terminated with the 'End tag' resource descriptor.\r
151\r
152 @param[in] This Indicates a pointer to the calling context.\r
153 @param[out] ResourceList A pointer to an ACPI resource descriptor list\r
154 that defines the current resources used by the\r
155 device.\r
156\r
157 @retval EFI_SUCCESS The operation completed successfully.\r
158 @retval EFI_INVALID_PARAMETER ResourceList is NULL.\r
159\r
160**/\r
161EFI_STATUS\r
162EFIAPI\r
163SioGetResources (\r
ac0a286f
MK
164 IN CONST EFI_SIO_PROTOCOL *This,\r
165 OUT ACPI_RESOURCE_HEADER_PTR *ResourceList\r
a5cc178a
HW
166 )\r
167{\r
ac0a286f 168 SIO_DEV *SioDevice;\r
a5cc178a
HW
169\r
170 if (ResourceList == NULL) {\r
171 return EFI_INVALID_PARAMETER;\r
172 }\r
173\r
174 SioDevice = SIO_DEV_FROM_SIO (This);\r
175 if (SioDevice->DeviceIndex < ARRAY_SIZE (mDevicesInfo)) {\r
176 *ResourceList = mDevicesInfo[SioDevice->DeviceIndex].Resources;\r
177 }\r
178\r
179 return EFI_SUCCESS;\r
180}\r
181\r
182/**\r
183 Sets the resources for the device.\r
184\r
185 @param[in] This Indicates a pointer to the calling context.\r
186 @param[in] ResourceList Pointer to the ACPI resource descriptor list.\r
187\r
188 @retval EFI_SUCCESS The operation completed successfully.\r
189 @retval EFI_INVALID_PARAMETER ResourceList is invalid.\r
190 @retval EFI_ACCESS_DENIED Some of the resources in ResourceList are in\r
191 use.\r
192\r
193**/\r
194EFI_STATUS\r
195EFIAPI\r
196SioSetResources (\r
ac0a286f
MK
197 IN CONST EFI_SIO_PROTOCOL *This,\r
198 IN ACPI_RESOURCE_HEADER_PTR ResourceList\r
a5cc178a
HW
199 )\r
200{\r
201 return EFI_SUCCESS;\r
202}\r
203\r
204/**\r
205 Provides a collection of resource descriptor lists. Each resource descriptor\r
206 list in the collection defines a combination of resources that can\r
207 potentially be used by the device.\r
208\r
209 @param[in] This Indicates a pointer to the calling context.\r
210 @param[out] ResourceCollection Collection of the resource descriptor\r
211 lists.\r
212\r
213 @retval EFI_SUCCESS The operation completed successfully.\r
214 @retval EFI_INVALID_PARAMETER ResourceCollection is NULL.\r
215\r
216**/\r
217EFI_STATUS\r
218EFIAPI\r
219SioPossibleResources (\r
ac0a286f
MK
220 IN CONST EFI_SIO_PROTOCOL *This,\r
221 OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection\r
a5cc178a
HW
222 )\r
223{\r
224 return EFI_SUCCESS;\r
225}\r
226\r
227/**\r
228 Provides an interface for a table based programming of the Super I/O\r
229 registers.\r
230\r
231 The Modify() function provides an interface for table based programming of\r
232 the Super I/O registers. This function can be used to perform programming of\r
233 multiple Super I/O registers with a single function call. For each table\r
234 entry, the Register is read, its content is bitwise ANDed with AndMask, and\r
235 then ORed with OrMask before being written back to the Register. The Super\r
236 I/O driver must track the current state of the Super I/O and enable the\r
237 configuration mode of Super I/O if necessary prior to table processing. Once\r
238 the table is processed, the Super I/O device has to be returned to the\r
239 original state.\r
240\r
241 @param[in] This Indicates a pointer to the calling context.\r
242 @param[in] Command A pointer to an array of NumberOfCommands\r
243 EFI_SIO_REGISTER_MODIFY structures. Each\r
244 structure specifies a single Super I/O register\r
245 modify operation.\r
246 @param[in] NumberOfCommands Number of elements in the Command array.\r
247\r
248 @retval EFI_SUCCESS The operation completed successfully.\r
249 @retval EFI_INVALID_PARAMETER Command is NULL.\r
250\r
251**/\r
252EFI_STATUS\r
253EFIAPI\r
254SioModify (\r
ac0a286f
MK
255 IN CONST EFI_SIO_PROTOCOL *This,\r
256 IN CONST EFI_SIO_REGISTER_MODIFY *Command,\r
257 IN UINTN NumberOfCommands\r
a5cc178a
HW
258 )\r
259{\r
260 return EFI_SUCCESS;\r
261}\r
262\r
263/**\r
264 Create the child device with a given device index.\r
265\r
266 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL instance.\r
267 @param[in] Controller The handle of ISA bus controller.\r
268 @param[in] PciIo The pointer to the PCI protocol.\r
269 @param[in] ParentDevicePath Device path of the ISA bus controller.\r
270 @param[in] DeviceIndex Index of the device supported by this driver.\r
271\r
272 @retval EFI_SUCCESS The child device has been created successfully.\r
60835c96 273 @retval Others Error occurred during the child device creation.\r
a5cc178a
HW
274\r
275**/\r
276EFI_STATUS\r
277SioCreateChildDevice (\r
278 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
279 IN EFI_HANDLE Controller,\r
280 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
281 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
282 IN UINT32 DeviceIndex\r
283 )\r
284{\r
ac0a286f
MK
285 EFI_STATUS Status;\r
286 SIO_DEV *SioDevice;\r
a5cc178a
HW
287\r
288 //\r
289 // Initialize the SIO_DEV structure\r
290 //\r
291 SioDevice = AllocateZeroPool (sizeof (SIO_DEV));\r
292 if (SioDevice == NULL) {\r
293 return EFI_OUT_OF_RESOURCES;\r
294 }\r
295\r
ac0a286f
MK
296 SioDevice->Signature = SIO_DEV_SIGNATURE;\r
297 SioDevice->Handle = NULL;\r
298 SioDevice->PciIo = PciIo;\r
a5cc178a
HW
299\r
300 //\r
301 // Construct the child device path\r
302 //\r
303 mAcpiDeviceNodeTemplate.HID = mDevicesInfo[DeviceIndex].Hid;\r
304 mAcpiDeviceNodeTemplate.UID = mDevicesInfo[DeviceIndex].Uid;\r
ac0a286f
MK
305 SioDevice->DevicePath = AppendDevicePathNode (\r
306 ParentDevicePath,\r
307 (EFI_DEVICE_PATH_PROTOCOL *)&mAcpiDeviceNodeTemplate\r
308 );\r
a5cc178a
HW
309 if (SioDevice->DevicePath == NULL) {\r
310 Status = EFI_OUT_OF_RESOURCES;\r
311 goto Done;\r
312 }\r
313\r
314 CopyMem (&SioDevice->Sio, &mSioInterface, sizeof (EFI_SIO_PROTOCOL));\r
315 SioDevice->DeviceIndex = DeviceIndex;\r
316\r
317 //\r
318 // Create a child handle and install Device Path and Super I/O protocols\r
319 //\r
320 Status = gBS->InstallMultipleProtocolInterfaces (\r
321 &SioDevice->Handle,\r
322 &gEfiDevicePathProtocolGuid,\r
323 SioDevice->DevicePath,\r
324 &gEfiSioProtocolGuid,\r
325 &SioDevice->Sio,\r
326 NULL\r
327 );\r
328 if (EFI_ERROR (Status)) {\r
329 goto Done;\r
330 }\r
331\r
332 Status = gBS->OpenProtocol (\r
333 Controller,\r
334 &gEfiPciIoProtocolGuid,\r
ac0a286f 335 (VOID **)&PciIo,\r
a5cc178a
HW
336 This->DriverBindingHandle,\r
337 SioDevice->Handle,\r
338 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
339 );\r
340 if (EFI_ERROR (Status)) {\r
341 gBS->UninstallMultipleProtocolInterfaces (\r
342 SioDevice->Handle,\r
343 &gEfiDevicePathProtocolGuid,\r
344 SioDevice->DevicePath,\r
345 &gEfiSioProtocolGuid,\r
346 &SioDevice->Sio,\r
347 NULL\r
348 );\r
349 }\r
350\r
351Done:\r
352 if (EFI_ERROR (Status)) {\r
353 if (SioDevice->DevicePath != NULL) {\r
354 FreePool (SioDevice->DevicePath);\r
355 }\r
356\r
357 FreePool (SioDevice);\r
358 }\r
359\r
360 return Status;\r
361}\r
362\r
363/**\r
364 Create all the ISA child devices on the ISA bus controller (PCI to ISA\r
365 bridge).\r
366\r
367 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL instance.\r
368 @param[in] Controller The handle of ISA bus controller.\r
369 @param[in] PciIo The pointer to the PCI protocol.\r
370 @param[in] ParentDevicePath Device path of the ISA bus controller.\r
371\r
372 @retval The number of child device that is successfully created.\r
373\r
374**/\r
375UINT32\r
376SioCreateAllChildDevices (\r
377 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
378 IN EFI_HANDLE Controller,\r
379 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
380 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
381 )\r
382{\r
ac0a286f
MK
383 UINT32 Index;\r
384 UINT32 ChildDeviceNumber;\r
385 EFI_STATUS Status;\r
a5cc178a
HW
386\r
387 ChildDeviceNumber = 0;\r
388\r
389 for (Index = 0; Index < ARRAY_SIZE (mDevicesInfo); Index++) {\r
390 Status = SioCreateChildDevice (\r
391 This,\r
392 Controller,\r
393 PciIo,\r
394 ParentDevicePath,\r
395 Index\r
396 );\r
397 if (!EFI_ERROR (Status)) {\r
398 ChildDeviceNumber++;\r
399 }\r
400 }\r
401\r
402 return ChildDeviceNumber;\r
403}\r