]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiLib/Acpi.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / UefiLib / Acpi.c
CommitLineData
af5e9521
SZ
1/** @file\r
2 This module provides help function for finding ACPI table.\r
3\r
4 Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
9344f092 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
af5e9521
SZ
6\r
7**/\r
8\r
9#include "UefiLibInternal.h"\r
10#include <IndustryStandard/Acpi.h>\r
11#include <Guid/Acpi.h>\r
12\r
13/**\r
14 This function scans ACPI table in XSDT/RSDT.\r
15\r
16 @param Sdt ACPI XSDT/RSDT.\r
17 @param TablePointerSize Size of table pointer: 8(XSDT) or 4(RSDT).\r
18 @param Signature ACPI table signature.\r
19 @param PreviousTable Pointer to previous returned table to locate\r
20 next table, or NULL to locate first table.\r
21 @param PreviousTableLocated Pointer to the indicator about whether the\r
22 previous returned table could be located, or\r
23 NULL if PreviousTable is NULL.\r
24\r
25 If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().\r
26 If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().\r
27\r
28 @return ACPI table or NULL if not found.\r
29\r
30**/\r
31EFI_ACPI_COMMON_HEADER *\r
32ScanTableInSDT (\r
2f88bd3a
MK
33 IN EFI_ACPI_DESCRIPTION_HEADER *Sdt,\r
34 IN UINTN TablePointerSize,\r
35 IN UINT32 Signature,\r
36 IN EFI_ACPI_COMMON_HEADER *PreviousTable OPTIONAL,\r
37 OUT BOOLEAN *PreviousTableLocated OPTIONAL\r
af5e9521
SZ
38 )\r
39{\r
2f88bd3a
MK
40 UINTN Index;\r
41 UINTN EntryCount;\r
42 UINT64 EntryPtr;\r
43 UINTN BasePtr;\r
44 EFI_ACPI_COMMON_HEADER *Table;\r
af5e9521
SZ
45\r
46 if (PreviousTableLocated != NULL) {\r
47 ASSERT (PreviousTable != NULL);\r
48 *PreviousTableLocated = FALSE;\r
49 } else {\r
50 ASSERT (PreviousTable == NULL);\r
51 }\r
52\r
53 if (Sdt == NULL) {\r
54 return NULL;\r
55 }\r
56\r
57 EntryCount = (Sdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / TablePointerSize;\r
58\r
59 BasePtr = (UINTN)(Sdt + 1);\r
2f88bd3a 60 for (Index = 0; Index < EntryCount; Index++) {\r
af5e9521
SZ
61 EntryPtr = 0;\r
62 CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * TablePointerSize), TablePointerSize);\r
63 Table = (EFI_ACPI_COMMON_HEADER *)((UINTN)(EntryPtr));\r
e7ac09b9 64 if ((Table != NULL) && (Table->Signature == Signature)) {\r
af5e9521
SZ
65 if (PreviousTable != NULL) {\r
66 if (Table == PreviousTable) {\r
67 *PreviousTableLocated = TRUE;\r
68 } else if (*PreviousTableLocated) {\r
69 //\r
70 // Return next table.\r
71 //\r
72 return Table;\r
73 }\r
74 } else {\r
75 //\r
76 // Return first table.\r
77 //\r
78 return Table;\r
79 }\r
af5e9521
SZ
80 }\r
81 }\r
82\r
83 return NULL;\r
84}\r
85\r
86/**\r
87 To locate FACS in FADT.\r
88\r
89 @param Fadt FADT table pointer.\r
90\r
91 @return FACS table pointer or NULL if not found.\r
92\r
93**/\r
94EFI_ACPI_COMMON_HEADER *\r
95LocateAcpiFacsFromFadt (\r
96 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
97 )\r
98{\r
2f88bd3a
MK
99 EFI_ACPI_COMMON_HEADER *Facs;\r
100 UINT64 Data64;\r
af5e9521
SZ
101\r
102 if (Fadt == NULL) {\r
103 return NULL;\r
104 }\r
105\r
106 if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
107 Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->FirmwareCtrl;\r
108 } else {\r
2f88bd3a 109 CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof (UINT64));\r
af5e9521
SZ
110 if (Data64 != 0) {\r
111 Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Data64;\r
112 } else {\r
113 Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->FirmwareCtrl;\r
114 }\r
115 }\r
2f88bd3a 116\r
af5e9521
SZ
117 return Facs;\r
118}\r
119\r
120/**\r
121 To locate DSDT in FADT.\r
122\r
123 @param Fadt FADT table pointer.\r
124\r
125 @return DSDT table pointer or NULL if not found.\r
126\r
127**/\r
128EFI_ACPI_COMMON_HEADER *\r
129LocateAcpiDsdtFromFadt (\r
130 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
131 )\r
132{\r
2f88bd3a
MK
133 EFI_ACPI_COMMON_HEADER *Dsdt;\r
134 UINT64 Data64;\r
af5e9521
SZ
135\r
136 if (Fadt == NULL) {\r
137 return NULL;\r
138 }\r
139\r
140 if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
141 Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->Dsdt;\r
142 } else {\r
2f88bd3a 143 CopyMem (&Data64, &Fadt->XDsdt, sizeof (UINT64));\r
af5e9521
SZ
144 if (Data64 != 0) {\r
145 Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Data64;\r
146 } else {\r
147 Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->Dsdt;\r
148 }\r
149 }\r
2f88bd3a 150\r
af5e9521
SZ
151 return Dsdt;\r
152}\r
153\r
154/**\r
155 To locate ACPI table in ACPI ConfigurationTable.\r
156\r
157 @param AcpiGuid The GUID used to get ACPI ConfigurationTable.\r
158 @param Signature ACPI table signature.\r
159 @param PreviousTable Pointer to previous returned table to locate\r
160 next table, or NULL to locate first table.\r
161 @param PreviousTableLocated Pointer to the indicator to return whether the\r
162 previous returned table could be located or not,\r
163 or NULL if PreviousTable is NULL.\r
164\r
165 If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().\r
166 If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().\r
167 If AcpiGuid is NULL, then ASSERT().\r
168\r
169 @return ACPI table or NULL if not found.\r
170\r
171**/\r
172EFI_ACPI_COMMON_HEADER *\r
173LocateAcpiTableInAcpiConfigurationTable (\r
2f88bd3a
MK
174 IN EFI_GUID *AcpiGuid,\r
175 IN UINT32 Signature,\r
176 IN EFI_ACPI_COMMON_HEADER *PreviousTable OPTIONAL,\r
177 OUT BOOLEAN *PreviousTableLocated OPTIONAL\r
af5e9521
SZ
178 )\r
179{\r
180 EFI_STATUS Status;\r
181 EFI_ACPI_COMMON_HEADER *Table;\r
182 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
183 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
184 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
185 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
186\r
187 if (PreviousTableLocated != NULL) {\r
188 ASSERT (PreviousTable != NULL);\r
189 *PreviousTableLocated = FALSE;\r
190 } else {\r
191 ASSERT (PreviousTable == NULL);\r
192 }\r
193\r
194 Rsdp = NULL;\r
195 //\r
196 // Get ACPI ConfigurationTable (RSD_PTR)\r
197 //\r
2f88bd3a 198 Status = EfiGetSystemConfigurationTable (AcpiGuid, (VOID **)&Rsdp);\r
af5e9521
SZ
199 if (EFI_ERROR (Status) || (Rsdp == NULL)) {\r
200 return NULL;\r
201 }\r
202\r
203 Table = NULL;\r
204\r
205 //\r
206 // Search XSDT\r
207 //\r
208 if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {\r
2f88bd3a 209 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;\r
af5e9521
SZ
210 if (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {\r
211 ASSERT (PreviousTable == NULL);\r
212 //\r
213 // It is to locate DSDT,\r
214 // need to locate FADT first.\r
215 //\r
2f88bd3a
MK
216 Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (\r
217 Xsdt,\r
218 sizeof (UINT64),\r
219 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
220 NULL,\r
221 NULL\r
222 );\r
af5e9521
SZ
223 Table = LocateAcpiDsdtFromFadt (Fadt);\r
224 } else if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {\r
225 ASSERT (PreviousTable == NULL);\r
226 //\r
227 // It is to locate FACS,\r
228 // need to locate FADT first.\r
229 //\r
2f88bd3a
MK
230 Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (\r
231 Xsdt,\r
232 sizeof (UINT64),\r
233 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
234 NULL,\r
235 NULL\r
236 );\r
af5e9521
SZ
237 Table = LocateAcpiFacsFromFadt (Fadt);\r
238 } else {\r
239 Table = ScanTableInSDT (\r
240 Xsdt,\r
241 sizeof (UINT64),\r
242 Signature,\r
243 PreviousTable,\r
244 PreviousTableLocated\r
245 );\r
246 }\r
247 }\r
248\r
249 if (Table != NULL) {\r
250 return Table;\r
251 } else if ((PreviousTableLocated != NULL) &&\r
2f88bd3a
MK
252 *PreviousTableLocated)\r
253 {\r
af5e9521
SZ
254 //\r
255 // PreviousTable could be located in XSDT,\r
256 // but next table could not be located in XSDT.\r
257 //\r
258 return NULL;\r
259 }\r
260\r
261 //\r
262 // Search RSDT\r
263 //\r
2f88bd3a 264 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;\r
af5e9521
SZ
265 if (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {\r
266 ASSERT (PreviousTable == NULL);\r
267 //\r
268 // It is to locate DSDT,\r
269 // need to locate FADT first.\r
270 //\r
2f88bd3a
MK
271 Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (\r
272 Rsdt,\r
273 sizeof (UINT32),\r
274 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
275 NULL,\r
276 NULL\r
277 );\r
af5e9521
SZ
278 Table = LocateAcpiDsdtFromFadt (Fadt);\r
279 } else if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {\r
280 ASSERT (PreviousTable == NULL);\r
281 //\r
282 // It is to locate FACS,\r
283 // need to locate FADT first.\r
284 //\r
2f88bd3a
MK
285 Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)ScanTableInSDT (\r
286 Rsdt,\r
287 sizeof (UINT32),\r
288 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
289 NULL,\r
290 NULL\r
291 );\r
af5e9521
SZ
292 Table = LocateAcpiFacsFromFadt (Fadt);\r
293 } else {\r
294 Table = ScanTableInSDT (\r
295 Rsdt,\r
296 sizeof (UINT32),\r
297 Signature,\r
298 PreviousTable,\r
299 PreviousTableLocated\r
300 );\r
301 }\r
302\r
303 return Table;\r
304}\r
305\r
306/**\r
307 This function locates next ACPI table in XSDT/RSDT based on Signature and\r
308 previous returned Table.\r
309\r
310 If PreviousTable is NULL:\r
311 This function will locate the first ACPI table in XSDT/RSDT based on\r
312 Signature in gEfiAcpi20TableGuid system configuration table first, and then\r
313 gEfiAcpi10TableGuid system configuration table.\r
314 This function will locate in XSDT first, and then RSDT.\r
315 For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in\r
316 FADT.\r
317 For FACS, this function will locate XFirmwareCtrl in FADT first, and then\r
318 FirmwareCtrl in FADT.\r
319\r
320 If PreviousTable is not NULL:\r
321 1. If it could be located in XSDT in gEfiAcpi20TableGuid system configuration\r
322 table, then this function will just locate next table in XSDT in\r
323 gEfiAcpi20TableGuid system configuration table.\r
324 2. If it could be located in RSDT in gEfiAcpi20TableGuid system configuration\r
325 table, then this function will just locate next table in RSDT in\r
326 gEfiAcpi20TableGuid system configuration table.\r
327 3. If it could be located in RSDT in gEfiAcpi10TableGuid system configuration\r
328 table, then this function will just locate next table in RSDT in\r
329 gEfiAcpi10TableGuid system configuration table.\r
330\r
331 It's not supported that PreviousTable is not NULL but PreviousTable->Signature\r
332 is not same with Signature, NULL will be returned.\r
333\r
334 @param Signature ACPI table signature.\r
335 @param PreviousTable Pointer to previous returned table to locate next\r
336 table, or NULL to locate first table.\r
337\r
338 @return Next ACPI table or NULL if not found.\r
339\r
340**/\r
341EFI_ACPI_COMMON_HEADER *\r
342EFIAPI\r
343EfiLocateNextAcpiTable (\r
2f88bd3a
MK
344 IN UINT32 Signature,\r
345 IN EFI_ACPI_COMMON_HEADER *PreviousTable OPTIONAL\r
af5e9521
SZ
346 )\r
347{\r
2f88bd3a
MK
348 EFI_ACPI_COMMON_HEADER *Table;\r
349 BOOLEAN TempPreviousTableLocated;\r
350 BOOLEAN *PreviousTableLocated;\r
af5e9521
SZ
351\r
352 if (PreviousTable != NULL) {\r
353 if (PreviousTable->Signature != Signature) {\r
354 //\r
355 // PreviousTable->Signature is not same with Signature.\r
356 //\r
357 return NULL;\r
358 } else if ((Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) ||\r
359 (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||\r
2f88bd3a
MK
360 (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE))\r
361 {\r
af5e9521
SZ
362 //\r
363 // There is only one FADT/DSDT/FACS table,\r
364 // so don't try to locate next one.\r
365 //\r
366 return NULL;\r
367 }\r
368\r
2f88bd3a 369 PreviousTableLocated = &TempPreviousTableLocated;\r
af5e9521
SZ
370 *PreviousTableLocated = FALSE;\r
371 } else {\r
372 PreviousTableLocated = NULL;\r
373 }\r
374\r
375 Table = LocateAcpiTableInAcpiConfigurationTable (\r
376 &gEfiAcpi20TableGuid,\r
377 Signature,\r
378 PreviousTable,\r
379 PreviousTableLocated\r
380 );\r
381 if (Table != NULL) {\r
382 return Table;\r
383 } else if ((PreviousTableLocated != NULL) &&\r
2f88bd3a
MK
384 *PreviousTableLocated)\r
385 {\r
af5e9521
SZ
386 //\r
387 // PreviousTable could be located in gEfiAcpi20TableGuid system\r
388 // configuration table, but next table could not be located in\r
389 // gEfiAcpi20TableGuid system configuration table.\r
390 //\r
391 return NULL;\r
392 }\r
393\r
394 return LocateAcpiTableInAcpiConfigurationTable (\r
395 &gEfiAcpi10TableGuid,\r
396 Signature,\r
397 PreviousTable,\r
398 PreviousTableLocated\r
399 );\r
400}\r
401\r
402/**\r
403 This function locates first ACPI table in XSDT/RSDT based on Signature.\r
404\r
405 This function will locate the first ACPI table in XSDT/RSDT based on\r
406 Signature in gEfiAcpi20TableGuid system configuration table first, and then\r
407 gEfiAcpi10TableGuid system configuration table.\r
408 This function will locate in XSDT first, and then RSDT.\r
409 For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in\r
410 FADT.\r
411 For FACS, this function will locate XFirmwareCtrl in FADT first, and then\r
412 FirmwareCtrl in FADT.\r
413\r
414 @param Signature ACPI table signature.\r
415\r
416 @return First ACPI table or NULL if not found.\r
417\r
418**/\r
419EFI_ACPI_COMMON_HEADER *\r
420EFIAPI\r
421EfiLocateFirstAcpiTable (\r
2f88bd3a 422 IN UINT32 Signature\r
af5e9521
SZ
423 )\r
424{\r
425 return EfiLocateNextAcpiTable (Signature, NULL);\r
426}\r