]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/AcpiLib/AcpiLib.c
EmbeddedPkg/AcpiLib: Fix code formatting errors
[mirror_edk2.git] / EmbeddedPkg / Library / AcpiLib / AcpiLib.c
CommitLineData
3356211b
OM
1/** @file\r
2*\r
da7dd714 3* Copyright (c) 2014-2015, ARM Limited. All rights reserved.\r
c63a10ec 4* Copyright (c) 2021, Ampere Computing LLC. All rights reserved.\r
3356211b 5*\r
878b807a 6* SPDX-License-Identifier: BSD-2-Clause-Patent\r
3356211b
OM
7*\r
8**/\r
9\r
10#include <Uefi.h>\r
11\r
12#include <Library/AcpiLib.h>\r
c63a10ec
NP
13#include <Library/BaseLib.h>\r
14#include <Library/BaseMemoryLib.h>\r
3356211b
OM
15#include <Library/DebugLib.h>\r
16#include <Library/UefiBootServicesTableLib.h>\r
17\r
c63a10ec 18#include <Protocol/AcpiSystemDescriptionTable.h>\r
3356211b
OM
19#include <Protocol/AcpiTable.h>\r
20#include <Protocol/FirmwareVolume2.h>\r
21\r
22#include <IndustryStandard/Acpi.h>\r
23\r
24/**\r
da7dd714
OM
25 Locate and Install the ACPI tables from the Firmware Volume if it verifies\r
26 the function condition.\r
3356211b 27\r
da7dd714
OM
28 @param AcpiFile Guid of the ACPI file into the Firmware Volume\r
29 @param CheckAcpiTableFunction Function that checks if the ACPI table should be installed\r
3356211b 30\r
da7dd714
OM
31 @return EFI_SUCCESS The function completed successfully.\r
32 @return EFI_NOT_FOUND The protocol could not be located.\r
33 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.\r
3356211b
OM
34\r
35**/\r
36EFI_STATUS\r
da7dd714 37LocateAndInstallAcpiFromFvConditional (\r
e7108d0e 38 IN CONST EFI_GUID *AcpiFile,\r
da7dd714 39 IN EFI_LOCATE_ACPI_CHECK CheckAcpiTableFunction\r
3356211b
OM
40 )\r
41{\r
e7108d0e
MK
42 EFI_STATUS Status;\r
43 EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol;\r
44 EFI_HANDLE *HandleBuffer;\r
45 UINTN NumberOfHandles;\r
46 UINT32 FvStatus;\r
47 UINTN Index;\r
48 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
49 INTN SectionInstance;\r
50 UINTN SectionSize;\r
51 EFI_ACPI_COMMON_HEADER *AcpiTable;\r
52 UINTN AcpiTableSize;\r
53 UINTN AcpiTableKey;\r
54 BOOLEAN Valid;\r
3356211b
OM
55\r
56 // Ensure the ACPI Table is present\r
57 Status = gBS->LocateProtocol (\r
58 &gEfiAcpiTableProtocolGuid,\r
59 NULL,\r
e7108d0e 60 (VOID **)&AcpiProtocol\r
3356211b
OM
61 );\r
62 if (EFI_ERROR (Status)) {\r
63 return Status;\r
64 }\r
65\r
66 FvStatus = 0;\r
67 SectionInstance = 0;\r
68\r
69 // Locate all the Firmware Volume protocols.\r
70 Status = gBS->LocateHandleBuffer (\r
e7108d0e
MK
71 ByProtocol,\r
72 &gEfiFirmwareVolume2ProtocolGuid,\r
73 NULL,\r
74 &NumberOfHandles,\r
75 &HandleBuffer\r
76 );\r
3356211b
OM
77 if (EFI_ERROR (Status)) {\r
78 return Status;\r
79 }\r
80\r
81 // Looking for FV with ACPI storage file\r
82 for (Index = 0; Index < NumberOfHandles; Index++) {\r
83 //\r
84 // Get the protocol on this handle\r
85 // This should not fail because of LocateHandleBuffer\r
86 //\r
87 Status = gBS->HandleProtocol (\r
e7108d0e
MK
88 HandleBuffer[Index],\r
89 &gEfiFirmwareVolume2ProtocolGuid,\r
90 (VOID **)&FvInstance\r
91 );\r
3356211b
OM
92 if (EFI_ERROR (Status)) {\r
93 goto FREE_HANDLE_BUFFER;\r
94 }\r
95\r
96 while (Status == EFI_SUCCESS) {\r
97 // AcpiTable must be allocated by ReadSection (ie: AcpiTable == NULL)\r
98 AcpiTable = NULL;\r
99\r
100 // See if it has the ACPI storage file\r
101 Status = FvInstance->ReadSection (\r
e7108d0e
MK
102 FvInstance,\r
103 AcpiFile,\r
104 EFI_SECTION_RAW,\r
105 SectionInstance,\r
106 (VOID **)&AcpiTable,\r
107 &SectionSize,\r
108 &FvStatus\r
109 );\r
3356211b 110 if (!EFI_ERROR (Status)) {\r
e7108d0e
MK
111 AcpiTableKey = 0;\r
112 AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Length;\r
3356211b
OM
113 ASSERT (SectionSize >= AcpiTableSize);\r
114\r
e7108d0e
MK
115 DEBUG ((\r
116 DEBUG_ERROR,\r
117 "- Found '%c%c%c%c' ACPI Table\n",\r
118 (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature & 0xFF),\r
119 ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 8) & 0xFF),\r
120 ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 16) & 0xFF),\r
121 ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 24) & 0xFF)\r
122 ));\r
3356211b 123\r
da7dd714
OM
124 // Is the ACPI table valid?\r
125 if (CheckAcpiTableFunction) {\r
126 Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable);\r
127 } else {\r
128 Valid = TRUE;\r
129 }\r
130\r
3356211b 131 // Install the ACPI Table\r
da7dd714
OM
132 if (Valid) {\r
133 Status = AcpiProtocol->InstallAcpiTable (\r
e7108d0e
MK
134 AcpiProtocol,\r
135 AcpiTable,\r
136 AcpiTableSize,\r
137 &AcpiTableKey\r
138 );\r
da7dd714
OM
139 }\r
140\r
3356211b
OM
141 // Free memory allocated by ReadSection\r
142 gBS->FreePool (AcpiTable);\r
143\r
144 if (EFI_ERROR (Status)) {\r
145 break;\r
146 }\r
147\r
148 // Increment the section instance\r
149 SectionInstance++;\r
150 }\r
151 }\r
152 }\r
153\r
154FREE_HANDLE_BUFFER:\r
155 //\r
156 // Free any allocated buffers\r
157 //\r
158 gBS->FreePool (HandleBuffer);\r
159\r
160 return EFI_SUCCESS;\r
161}\r
da7dd714
OM
162\r
163/**\r
164 Locate and Install the ACPI tables from the Firmware Volume\r
165\r
166 @param AcpiFile Guid of the ACPI file into the Firmware Volume\r
167\r
168 @return EFI_SUCCESS The function completed successfully.\r
169 @return EFI_NOT_FOUND The protocol could not be located.\r
170 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.\r
171\r
172**/\r
173EFI_STATUS\r
174LocateAndInstallAcpiFromFv (\r
e7108d0e 175 IN CONST EFI_GUID *AcpiFile\r
da7dd714
OM
176 )\r
177{\r
178 return LocateAndInstallAcpiFromFvConditional (AcpiFile, NULL);\r
179}\r
c63a10ec
NP
180\r
181/**\r
182 This function calculates and updates a UINT8 checksum\r
183 in an ACPI description table header.\r
184\r
185 @param Buffer Pointer to buffer to checksum\r
186 @param Size Number of bytes to checksum\r
187\r
188 @retval EFI_SUCCESS The function completed successfully.\r
189 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
190\r
191**/\r
192EFI_STATUS\r
193EFIAPI\r
194AcpiUpdateChecksum (\r
51e05995
MK
195 IN OUT UINT8 *Buffer,\r
196 IN UINTN Size\r
c63a10ec
NP
197 )\r
198{\r
51e05995 199 UINTN ChecksumOffset;\r
c63a10ec 200\r
51e05995 201 if ((Buffer == NULL) || (Size == 0)) {\r
c63a10ec
NP
202 return EFI_INVALID_PARAMETER;\r
203 }\r
204\r
205 ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
206\r
207 //\r
208 // Set checksum to 0 first\r
209 //\r
210 Buffer[ChecksumOffset] = 0;\r
211\r
212 //\r
213 // Update checksum value\r
214 //\r
215 Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);\r
216\r
217 return EFI_SUCCESS;\r
218}\r
219\r
220/**\r
221 This function uses the ACPI SDT protocol to search an ACPI table\r
222 with a given signature.\r
223\r
224 @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol.\r
225 @param TableSignature ACPI table signature.\r
226 @param Index The zero-based index of the table where to search the table.\r
227 The index will be updated to the next instance if the table\r
228 is found with the matched TableSignature.\r
229 @param Table Pointer to the table.\r
230 @param TableKey Pointer to the table key.\r
231\r
232 @return EFI_SUCCESS The function completed successfully.\r
233 @return EFI_INVALID_PARAMETER At least one of parameters is invalid.\r
234 @retval EFI_NOT_FOUND The requested index is too large and a table was not found.\r
235\r
236**/\r
237EFI_STATUS\r
238EFIAPI\r
239AcpiLocateTableBySignature (\r
51e05995
MK
240 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol,\r
241 IN UINT32 TableSignature,\r
242 IN OUT UINTN *Index,\r
243 OUT EFI_ACPI_DESCRIPTION_HEADER **Table,\r
244 OUT UINTN *TableKey\r
c63a10ec
NP
245 )\r
246{\r
247 EFI_STATUS Status;\r
248 EFI_ACPI_SDT_HEADER *TempTable;\r
249 EFI_ACPI_TABLE_VERSION TableVersion;\r
250 UINTN TableIndex;\r
251\r
51e05995
MK
252 if ( (AcpiSdtProtocol == NULL)\r
253 || (Table == NULL)\r
254 || (TableKey == NULL))\r
255 {\r
c63a10ec
NP
256 return EFI_INVALID_PARAMETER;\r
257 }\r
258\r
259 Status = EFI_SUCCESS;\r
260\r
261 //\r
262 // Search for ACPI Table with matching signature\r
263 //\r
264 TableVersion = 0;\r
51e05995 265 TableIndex = *Index;\r
c63a10ec
NP
266 while (!EFI_ERROR (Status)) {\r
267 Status = AcpiSdtProtocol->GetAcpiTable (\r
268 TableIndex,\r
269 &TempTable,\r
270 &TableVersion,\r
271 TableKey\r
272 );\r
273 if (!EFI_ERROR (Status)) {\r
274 TableIndex++;\r
275\r
276 if (((EFI_ACPI_DESCRIPTION_HEADER *)TempTable)->Signature == TableSignature) {\r
277 *Table = (EFI_ACPI_DESCRIPTION_HEADER *)TempTable;\r
278 *Index = TableIndex;\r
279 break;\r
280 }\r
281 }\r
282 }\r
283\r
284 return Status;\r
285}\r
286\r
287/**\r
288 This function updates the integer value of an AML Object.\r
289\r
290 @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol.\r
291 @param TableHandle Points to the table representing the starting point\r
292 for the object path search.\r
293 @param AsciiObjectPath Pointer to the ACPI path of the object being updated.\r
294 @param Value New value to write to the object.\r
295\r
296 @return EFI_SUCCESS The function completed successfully.\r
297 @return EFI_INVALID_PARAMETER At least one of parameters is invalid or the data type\r
298 of the ACPI object is not an integer value.\r
299 @retval EFI_NOT_FOUND The object is not found with the given path.\r
300\r
301**/\r
302EFI_STATUS\r
303EFIAPI\r
304AcpiAmlObjectUpdateInteger (\r
51e05995
MK
305 IN EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol,\r
306 IN EFI_ACPI_HANDLE TableHandle,\r
307 IN CHAR8 *AsciiObjectPath,\r
308 IN UINTN Value\r
c63a10ec
NP
309 )\r
310{\r
51e05995
MK
311 EFI_STATUS Status;\r
312 EFI_ACPI_HANDLE ObjectHandle;\r
313 EFI_ACPI_HANDLE DataHandle;\r
314 EFI_ACPI_DATA_TYPE DataType;\r
315 UINT8 *Buffer;\r
316 UINTN BufferSize;\r
317 UINTN DataSize;\r
318\r
319 if ((AcpiSdtProtocol == NULL) || (AsciiObjectPath == NULL)) {\r
c63a10ec
NP
320 return EFI_INVALID_PARAMETER;\r
321 }\r
322\r
323 ObjectHandle = NULL;\r
51e05995 324 DataHandle = NULL;\r
c63a10ec
NP
325\r
326 Status = AcpiSdtProtocol->FindPath (TableHandle, AsciiObjectPath, &ObjectHandle);\r
327 if (EFI_ERROR (Status)) {\r
328 return Status;\r
329 }\r
330\r
331 Status = AcpiSdtProtocol->GetOption (ObjectHandle, 0, &DataType, (VOID *)&Buffer, &BufferSize);\r
332 if (EFI_ERROR (Status)) {\r
333 Status = EFI_NOT_FOUND;\r
334 goto Exit;\r
335 }\r
51e05995 336\r
c63a10ec
NP
337 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);\r
338 ASSERT (Buffer != NULL);\r
339\r
340 if (Buffer[0] != AML_NAME_OP) {\r
341 Status = EFI_NOT_FOUND;\r
342 goto Exit;\r
343 }\r
344\r
345 //\r
346 // Get handle of data object\r
347 //\r
348 Status = AcpiSdtProtocol->GetChild (ObjectHandle, &DataHandle);\r
349 ASSERT_EFI_ERROR (Status);\r
350\r
351 Status = AcpiSdtProtocol->GetOption (DataHandle, 0, &DataType, (VOID *)&Buffer, &BufferSize);\r
352 ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);\r
353 ASSERT (Buffer != NULL);\r
354\r
51e05995 355 if ((Buffer[0] == AML_ZERO_OP) || (Buffer[0] == AML_ONE_OP)) {\r
c63a10ec
NP
356 Status = AcpiSdtProtocol->SetOption (DataHandle, 0, (VOID *)&Value, sizeof (UINT8));\r
357 ASSERT_EFI_ERROR (Status);\r
358 } else {\r
359 //\r
360 // Check the size of data object\r
361 //\r
362 switch (Buffer[0]) {\r
51e05995
MK
363 case AML_BYTE_PREFIX:\r
364 DataSize = sizeof (UINT8);\r
365 break;\r
366\r
367 case AML_WORD_PREFIX:\r
368 DataSize = sizeof (UINT16);\r
369 break;\r
370\r
371 case AML_DWORD_PREFIX:\r
372 DataSize = sizeof (UINT32);\r
373 break;\r
374\r
375 case AML_QWORD_PREFIX:\r
376 DataSize = sizeof (UINT64);\r
377 break;\r
378\r
379 default:\r
380 // The data type of the ACPI object is not an integer\r
381 Status = EFI_INVALID_PARAMETER;\r
382 goto Exit;\r
c63a10ec
NP
383 }\r
384\r
385 Status = AcpiSdtProtocol->SetOption (DataHandle, 1, (VOID *)&Value, DataSize);\r
386 ASSERT_EFI_ERROR (Status);\r
387 }\r
388\r
389Exit:\r
390 AcpiSdtProtocol->Close (DataHandle);\r
391 AcpiSdtProtocol->Close (ObjectHandle);\r
392\r
393 return Status;\r
394}\r