VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdePkg/Library/UefiLib/Acpi.c

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette