]> git.proxmox.com Git - mirror_edk2.git/blame - DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c
DynamicTablesPkg: Apply uncrustify changes
[mirror_edk2.git] / DynamicTablesPkg / Library / Acpi / Arm / AcpiSsdtSerialPortLibArm / SsdtSerialPortGenerator.c
CommitLineData
5b035def
PG
1/** @file\r
2 SSDT Serial Port Table Generator.\r
3\r
1f515342 4 Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>\r
5b035def
PG
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7**/\r
8\r
5b035def
PG
9#include <Library/AcpiLib.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/BaseMemoryLib.h>\r
12#include <Library/DebugLib.h>\r
13#include <Library/MemoryAllocationLib.h>\r
5b035def
PG
14#include <Protocol/AcpiTable.h>\r
15\r
16// Module specific include files.\r
17#include <AcpiTableGenerator.h>\r
18#include <ConfigurationManagerObject.h>\r
19#include <ConfigurationManagerHelper.h>\r
0875443f 20#include <Library/AcpiHelperLib.h>\r
5b035def 21#include <Library/SsdtSerialPortFixupLib.h>\r
5b035def
PG
22#include <Protocol/ConfigurationManagerProtocol.h>\r
23\r
24/** ARM standard SSDT Serial Port Table Generator\r
25\r
26 Constructs SSDT tables describing serial ports (other than the serial ports\r
27 used by the SPCR or DBG2 tables).\r
28\r
29Requirements:\r
30 The following Configuration Manager Object(s) are required by\r
31 this Generator:\r
32 - EArmObjSerialPortInfo\r
33*/\r
34\r
35/** This macro expands to a function that retrieves the Serial-port\r
36 information from the Configuration Manager.\r
37*/\r
38GET_OBJECT_LIST (\r
39 EObjNameSpaceArm,\r
40 EArmObjSerialPortInfo,\r
41 CM_ARM_SERIAL_PORT_INFO\r
42 );\r
43\r
44/** Starting value for the UID to represent the serial ports.\r
45 Note: The UID 0 and 1 are reserved for use by DBG2 port and SPCR\r
46 respectively. So, the UIDs for serial ports for general use\r
47 start at 2.\r
48*/\r
731c67e1 49#define SERIAL_PORT_START_UID 2\r
5b035def
PG
50\r
51/** Maximum serial ports supported by this generator.\r
52 This generator supports a maximum of 14 (16 - 2) serial ports.\r
53 The -2 here reflects the reservation for serial ports for the DBG2\r
54 and SPCR ports regardless of whether the DBG2 or SPCR port is enabled.\r
55 Note: This is not a hard limitation and can be extended if needed.\r
56 Corresponding changes would be needed to support the Name and\r
57 UID fields describing the serial port.\r
58\r
59*/\r
731c67e1 60#define MAX_SERIAL_PORTS_SUPPORTED 14\r
5b035def
PG
61\r
62/** Free any resources allocated for constructing the tables.\r
63\r
64 @param [in] This Pointer to the ACPI table generator.\r
65 @param [in] AcpiTableInfo Pointer to the ACPI Table Info.\r
66 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
67 Protocol Interface.\r
68 @param [in, out] Table Pointer to an array of pointers\r
69 to ACPI Table(s).\r
70 @param [in] TableCount Number of ACPI table(s).\r
71\r
72 @retval EFI_SUCCESS The resources were freed successfully.\r
73 @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.\r
74**/\r
75STATIC\r
76EFI_STATUS\r
77EFIAPI\r
78FreeSsdtSerialPortTableEx (\r
731c67e1
MK
79 IN CONST ACPI_TABLE_GENERATOR *CONST This,\r
80 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
81 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
82 IN OUT EFI_ACPI_DESCRIPTION_HEADER ***CONST Table,\r
5b035def
PG
83 IN CONST UINTN TableCount\r
84 )\r
85{\r
731c67e1
MK
86 EFI_STATUS Status;\r
87 EFI_ACPI_DESCRIPTION_HEADER **TableList;\r
88 UINTN Index;\r
5b035def
PG
89\r
90 ASSERT (This != NULL);\r
653fb710
SM
91 ASSERT (AcpiTableInfo != NULL);\r
92 ASSERT (CfgMgrProtocol != NULL);\r
5b035def
PG
93 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
94 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
5b035def
PG
95\r
96 if ((Table == NULL) ||\r
97 (*Table == NULL) ||\r
731c67e1
MK
98 (TableCount == 0))\r
99 {\r
5b035def
PG
100 DEBUG ((DEBUG_ERROR, "ERROR: SSDT-SERIAL-PORT: Invalid Table Pointer\n"));\r
101 return EFI_INVALID_PARAMETER;\r
102 }\r
103\r
104 TableList = *Table;\r
105\r
106 for (Index = 0; Index < TableCount; Index++) {\r
107 if ((TableList[Index] != NULL) &&\r
108 (TableList[Index]->Signature ==\r
731c67e1
MK
109 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE))\r
110 {\r
5b035def
PG
111 Status = FreeSsdtSerialPortTable (TableList[Index]);\r
112 } else {\r
113 Status = EFI_INVALID_PARAMETER;\r
114 }\r
115\r
116 if (EFI_ERROR (Status)) {\r
117 DEBUG ((\r
118 DEBUG_ERROR,\r
119 "ERROR: SSDT-SERIAL-PORT: Could not free SSDT table at index %d."\r
120 " Status = %r\n",\r
121 Index,\r
122 Status\r
123 ));\r
124 return Status;\r
125 }\r
731c67e1 126 } // for\r
5b035def
PG
127\r
128 // Free the table list.\r
129 FreePool (*Table);\r
130\r
131 return EFI_SUCCESS;\r
132}\r
133\r
134/** Construct SSDT tables describing serial-ports.\r
135\r
136 This function invokes the Configuration Manager protocol interface\r
137 to get the required hardware information for generating the ACPI\r
138 table.\r
139\r
140 If this function allocates any resources then they must be freed\r
141 in the FreeXXXXTableResourcesEx function.\r
142\r
143 @param [in] This Pointer to the ACPI table generator.\r
144 @param [in] AcpiTableInfo Pointer to the ACPI table information.\r
145 @param [in] CfgMgrProtocol Pointer to the Configuration Manager\r
146 Protocol interface.\r
147 @param [out] Table Pointer to a list of generated ACPI table(s).\r
148 @param [out] TableCount Number of generated ACPI table(s).\r
149\r
150 @retval EFI_SUCCESS Table generated successfully.\r
151 @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration\r
152 Manager is less than the Object size for\r
153 the requested object.\r
154 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
155 @retval EFI_NOT_FOUND Could not find information.\r
156 @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
157 @retval EFI_UNSUPPORTED Unsupported configuration.\r
158**/\r
159STATIC\r
160EFI_STATUS\r
161EFIAPI\r
162BuildSsdtSerialPortTableEx (\r
731c67e1
MK
163 IN CONST ACPI_TABLE_GENERATOR *This,\r
164 IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,\r
165 IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,\r
166 OUT EFI_ACPI_DESCRIPTION_HEADER ***Table,\r
167 OUT UINTN *CONST TableCount\r
5b035def
PG
168 )\r
169{\r
731c67e1
MK
170 EFI_STATUS Status;\r
171 CM_ARM_SERIAL_PORT_INFO *SerialPortInfo;\r
172 UINT32 SerialPortCount;\r
173 UINTN Index;\r
174 CHAR8 NewName[AML_NAME_SEG_SIZE + 1];\r
175 UINT64 Uid;\r
176 EFI_ACPI_DESCRIPTION_HEADER **TableList;\r
5b035def
PG
177\r
178 ASSERT (This != NULL);\r
179 ASSERT (AcpiTableInfo != NULL);\r
180 ASSERT (CfgMgrProtocol != NULL);\r
181 ASSERT (Table != NULL);\r
182 ASSERT (TableCount != NULL);\r
183 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
184 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
185\r
186 *Table = NULL;\r
187\r
188 Status = GetEArmObjSerialPortInfo (\r
189 CfgMgrProtocol,\r
190 CM_NULL_TOKEN,\r
191 &SerialPortInfo,\r
192 &SerialPortCount\r
193 );\r
194 if (EFI_ERROR (Status)) {\r
195 DEBUG ((\r
196 DEBUG_ERROR,\r
197 "ERROR: SSDT-SERIAL-PORT: Failed to get serial port information."\r
198 " Status = %r\n",\r
199 Status\r
200 ));\r
201 return Status;\r
202 }\r
203\r
204 if (SerialPortCount > MAX_SERIAL_PORTS_SUPPORTED) {\r
205 DEBUG ((\r
206 DEBUG_ERROR,\r
207 "ERROR: SSDT-SERIAL-PORT: Too many serial ports: %d."\r
208 " Maximum serial ports supported = %d.\n",\r
209 SerialPortCount,\r
210 MAX_SERIAL_PORTS_SUPPORTED\r
211 ));\r
212 return EFI_INVALID_PARAMETER;\r
213 }\r
214\r
215 // Validate the SerialPort info.\r
216 Status = ValidateSerialPortInfo (SerialPortInfo, SerialPortCount);\r
217 if (EFI_ERROR (Status)) {\r
218 DEBUG ((\r
219 DEBUG_ERROR,\r
220 "ERROR: SSDT-SERIAL-PORT: Invalid serial port information. Status = %r\n",\r
221 Status\r
222 ));\r
223 return Status;\r
224 }\r
225\r
226 // Allocate a table to store pointers to the SSDT tables.\r
731c67e1 227 TableList = (EFI_ACPI_DESCRIPTION_HEADER **)\r
5b035def 228 AllocateZeroPool (\r
731c67e1 229 (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * SerialPortCount)\r
5b035def
PG
230 );\r
231 if (TableList == NULL) {\r
232 Status = EFI_OUT_OF_RESOURCES;\r
233 DEBUG ((\r
234 DEBUG_ERROR,\r
235 "ERROR: SSDT-SERIAL-PORT: Failed to allocate memory for Table List."\r
236 " Status = %r\n",\r
237 Status\r
238 ));\r
239 return Status;\r
240 }\r
241\r
242 // Setup the table list early so that that appropriate cleanup\r
243 // can be done in case of failure.\r
244 *Table = TableList;\r
245\r
32493100
SM
246 NewName[0] = 'C';\r
247 NewName[1] = 'O';\r
248 NewName[2] = 'M';\r
249 NewName[4] = '\0';\r
5b035def 250 for (Index = 0; Index < SerialPortCount; Index++) {\r
731c67e1 251 Uid = SERIAL_PORT_START_UID + Index;\r
5b035def
PG
252 NewName[3] = AsciiFromHex ((UINT8)(Uid));\r
253\r
254 // Build a SSDT table describing the serial port.\r
255 Status = BuildSsdtSerialPortTable (\r
256 AcpiTableInfo,\r
257 &SerialPortInfo[Index],\r
258 NewName,\r
259 Uid,\r
260 &TableList[Index]\r
261 );\r
262 if (EFI_ERROR (Status)) {\r
263 DEBUG ((\r
264 DEBUG_ERROR,\r
265 "ERROR: SSDT-SERIAL-PORT: Failed to build associated SSDT table."\r
266 " Status = %r\n",\r
267 Status\r
268 ));\r
269 goto error_handler;\r
270 }\r
271\r
272 // Increment the table count here so that appropriate cleanup\r
273 // can be done in case of failure.\r
274 *TableCount += 1;\r
275 } // for\r
276\r
277error_handler:\r
278 // Note: Table list and Serial port count has been setup. The\r
279 // error handler does nothing here as the framework will invoke\r
280 // FreeSsdtSerialPortTableEx() even on failure.\r
281 return Status;\r
282}\r
283\r
284/** This macro defines the SSDT Serial Port Table Generator revision.\r
285*/\r
731c67e1 286#define SSDT_SERIAL_GENERATOR_REVISION CREATE_REVISION (1, 0)\r
5b035def
PG
287\r
288/** The interface for the SSDT Serial Port Table Generator.\r
289*/\r
290STATIC\r
291CONST\r
731c67e1 292ACPI_TABLE_GENERATOR SsdtSerialPortGenerator = {\r
5b035def
PG
293 // Generator ID\r
294 CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtSerialPort),\r
295 // Generator Description\r
296 L"ACPI.STD.SSDT.SERIAL.PORT.GENERATOR",\r
297 // ACPI Table Signature\r
298 EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,\r
299 // ACPI Table Revision - Unused\r
300 0,\r
301 // Minimum ACPI Table Revision - Unused\r
302 0,\r
303 // Creator ID\r
304 TABLE_GENERATOR_CREATOR_ID_ARM,\r
305 // Creator Revision\r
306 SSDT_SERIAL_GENERATOR_REVISION,\r
307 // Build table function. Use the extended version instead.\r
308 NULL,\r
309 // Free table function. Use the extended version instead.\r
310 NULL,\r
311 // Extended Build table function.\r
312 BuildSsdtSerialPortTableEx,\r
313 // Extended free function.\r
314 FreeSsdtSerialPortTableEx\r
315};\r
316\r
317/** Register the Generator with the ACPI Table Factory.\r
318\r
319 @param [in] ImageHandle The handle to the image.\r
320 @param [in] SystemTable Pointer to the System Table.\r
321\r
322 @retval EFI_SUCCESS The Generator is registered.\r
323 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
324 @retval EFI_ALREADY_STARTED The Generator for the Table ID\r
325 is already registered.\r
326**/\r
327EFI_STATUS\r
328EFIAPI\r
329AcpiSsdtSerialPortLibConstructor (\r
731c67e1
MK
330 IN EFI_HANDLE ImageHandle,\r
331 IN EFI_SYSTEM_TABLE *SystemTable\r
5b035def
PG
332 )\r
333{\r
334 EFI_STATUS Status;\r
731c67e1 335\r
5b035def
PG
336 Status = RegisterAcpiTableGenerator (&SsdtSerialPortGenerator);\r
337 DEBUG ((\r
338 DEBUG_INFO,\r
339 "SSDT-SERIAL-PORT: Register Generator. Status = %r\n",\r
340 Status\r
341 ));\r
342 ASSERT_EFI_ERROR (Status);\r
343\r
344 return Status;\r
345}\r
346\r
347/** Deregister the Generator from the ACPI Table Factory.\r
348\r
349 @param [in] ImageHandle The handle to the image.\r
350 @param [in] SystemTable Pointer to the System Table.\r
351\r
352 @retval EFI_SUCCESS The Generator is deregistered.\r
353 @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
354 @retval EFI_NOT_FOUND The Generator is not registered.\r
355**/\r
356EFI_STATUS\r
357EFIAPI\r
358AcpiSsdtSerialPortLibDestructor (\r
731c67e1
MK
359 IN EFI_HANDLE ImageHandle,\r
360 IN EFI_SYSTEM_TABLE *SystemTable\r
5b035def
PG
361 )\r
362{\r
363 EFI_STATUS Status;\r
731c67e1 364\r
5b035def
PG
365 Status = DeregisterAcpiTableGenerator (&SsdtSerialPortGenerator);\r
366 DEBUG ((\r
367 DEBUG_INFO,\r
368 "SSDT-SERIAL-PORT: Deregister Generator. Status = %r\n",\r
369 Status\r
370 ));\r
371 ASSERT_EFI_ERROR (Status);\r
372 return Status;\r
373}\r