2 This module provides help function for finding ACPI table.
4 Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "UefiLibInternal.h"
10 #include <IndustryStandard/Acpi.h>
11 #include <Guid/Acpi.h>
14 This function scans ACPI table in XSDT/RSDT.
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.
25 If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().
26 If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().
28 @return ACPI table or NULL if not found.
31 EFI_ACPI_COMMON_HEADER
*
33 IN EFI_ACPI_DESCRIPTION_HEADER
*Sdt
,
34 IN UINTN TablePointerSize
,
36 IN EFI_ACPI_COMMON_HEADER
*PreviousTable OPTIONAL
,
37 OUT BOOLEAN
*PreviousTableLocated OPTIONAL
44 EFI_ACPI_COMMON_HEADER
*Table
;
46 if (PreviousTableLocated
!= NULL
) {
47 ASSERT (PreviousTable
!= NULL
);
48 *PreviousTableLocated
= FALSE
;
50 ASSERT (PreviousTable
== NULL
);
57 EntryCount
= (Sdt
->Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / TablePointerSize
;
59 BasePtr
= (UINTN
)(Sdt
+ 1);
60 for (Index
= 0; Index
< EntryCount
; Index
++) {
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
) {
76 // Return first table.
87 To locate FACS in FADT.
89 @param Fadt FADT table pointer.
91 @return FACS table pointer or NULL if not found.
94 EFI_ACPI_COMMON_HEADER
*
95 LocateAcpiFacsFromFadt (
96 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt
99 EFI_ACPI_COMMON_HEADER
*Facs
;
106 if (Fadt
->Header
.Revision
< EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
107 Facs
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->FirmwareCtrl
;
109 CopyMem (&Data64
, &Fadt
->XFirmwareCtrl
, sizeof (UINT64
));
111 Facs
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Data64
;
113 Facs
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->FirmwareCtrl
;
121 To locate DSDT in FADT.
123 @param Fadt FADT table pointer.
125 @return DSDT table pointer or NULL if not found.
128 EFI_ACPI_COMMON_HEADER
*
129 LocateAcpiDsdtFromFadt (
130 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt
133 EFI_ACPI_COMMON_HEADER
*Dsdt
;
140 if (Fadt
->Header
.Revision
< EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
141 Dsdt
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->Dsdt
;
143 CopyMem (&Data64
, &Fadt
->XDsdt
, sizeof (UINT64
));
145 Dsdt
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Data64
;
147 Dsdt
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->Dsdt
;
155 To locate ACPI table in ACPI ConfigurationTable.
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.
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().
169 @return ACPI table or NULL if not found.
172 EFI_ACPI_COMMON_HEADER
*
173 LocateAcpiTableInAcpiConfigurationTable (
174 IN EFI_GUID
*AcpiGuid
,
176 IN EFI_ACPI_COMMON_HEADER
*PreviousTable OPTIONAL
,
177 OUT BOOLEAN
*PreviousTableLocated OPTIONAL
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
;
187 if (PreviousTableLocated
!= NULL
) {
188 ASSERT (PreviousTable
!= NULL
);
189 *PreviousTableLocated
= FALSE
;
191 ASSERT (PreviousTable
== NULL
);
196 // Get ACPI ConfigurationTable (RSD_PTR)
198 Status
= EfiGetSystemConfigurationTable (AcpiGuid
, (VOID
**)&Rsdp
);
199 if (EFI_ERROR (Status
) || (Rsdp
== NULL
)) {
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
);
213 // It is to locate DSDT,
214 // need to locate FADT first.
216 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ScanTableInSDT (
219 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
223 Table
= LocateAcpiDsdtFromFadt (Fadt
);
224 } else if (Signature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
225 ASSERT (PreviousTable
== NULL
);
227 // It is to locate FACS,
228 // need to locate FADT first.
230 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ScanTableInSDT (
233 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
237 Table
= LocateAcpiFacsFromFadt (Fadt
);
239 Table
= ScanTableInSDT (
251 } else if ((PreviousTableLocated
!= NULL
) &&
252 *PreviousTableLocated
)
255 // PreviousTable could be located in XSDT,
256 // but next table could not be located in XSDT.
264 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)Rsdp
->RsdtAddress
;
265 if (Signature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) {
266 ASSERT (PreviousTable
== NULL
);
268 // It is to locate DSDT,
269 // need to locate FADT first.
271 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ScanTableInSDT (
274 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
278 Table
= LocateAcpiDsdtFromFadt (Fadt
);
279 } else if (Signature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
280 ASSERT (PreviousTable
== NULL
);
282 // It is to locate FACS,
283 // need to locate FADT first.
285 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ScanTableInSDT (
288 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
292 Table
= LocateAcpiFacsFromFadt (Fadt
);
294 Table
= ScanTableInSDT (
307 This function locates next ACPI table in XSDT/RSDT based on Signature and
308 previous returned Table.
310 If PreviousTable is NULL:
311 This function will locate the first ACPI table in XSDT/RSDT based on
312 Signature in gEfiAcpi20TableGuid system configuration table first, and then
313 gEfiAcpi10TableGuid system configuration table.
314 This function will locate in XSDT first, and then RSDT.
315 For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in
317 For FACS, this function will locate XFirmwareCtrl in FADT first, and then
318 FirmwareCtrl in FADT.
320 If PreviousTable is not NULL:
321 1. If it could be located in XSDT in gEfiAcpi20TableGuid system configuration
322 table, then this function will just locate next table in XSDT in
323 gEfiAcpi20TableGuid system configuration table.
324 2. If it could be located in RSDT in gEfiAcpi20TableGuid system configuration
325 table, then this function will just locate next table in RSDT in
326 gEfiAcpi20TableGuid system configuration table.
327 3. If it could be located in RSDT in gEfiAcpi10TableGuid system configuration
328 table, then this function will just locate next table in RSDT in
329 gEfiAcpi10TableGuid system configuration table.
331 It's not supported that PreviousTable is not NULL but PreviousTable->Signature
332 is not same with Signature, NULL will be returned.
334 @param Signature ACPI table signature.
335 @param PreviousTable Pointer to previous returned table to locate next
336 table, or NULL to locate first table.
338 @return Next ACPI table or NULL if not found.
341 EFI_ACPI_COMMON_HEADER
*
343 EfiLocateNextAcpiTable (
345 IN EFI_ACPI_COMMON_HEADER
*PreviousTable OPTIONAL
348 EFI_ACPI_COMMON_HEADER
*Table
;
349 BOOLEAN TempPreviousTableLocated
;
350 BOOLEAN
*PreviousTableLocated
;
352 if (PreviousTable
!= NULL
) {
353 if (PreviousTable
->Signature
!= Signature
) {
355 // PreviousTable->Signature is not same with Signature.
358 } else if ((Signature
== EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
) ||
359 (Signature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) ||
360 (Signature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
))
363 // There is only one FADT/DSDT/FACS table,
364 // so don't try to locate next one.
369 PreviousTableLocated
= &TempPreviousTableLocated
;
370 *PreviousTableLocated
= FALSE
;
372 PreviousTableLocated
= NULL
;
375 Table
= LocateAcpiTableInAcpiConfigurationTable (
376 &gEfiAcpi20TableGuid
,
383 } else if ((PreviousTableLocated
!= NULL
) &&
384 *PreviousTableLocated
)
387 // PreviousTable could be located in gEfiAcpi20TableGuid system
388 // configuration table, but next table could not be located in
389 // gEfiAcpi20TableGuid system configuration table.
394 return LocateAcpiTableInAcpiConfigurationTable (
395 &gEfiAcpi10TableGuid
,
403 This function locates first ACPI table in XSDT/RSDT based on Signature.
405 This function will locate the first ACPI table in XSDT/RSDT based on
406 Signature in gEfiAcpi20TableGuid system configuration table first, and then
407 gEfiAcpi10TableGuid system configuration table.
408 This function will locate in XSDT first, and then RSDT.
409 For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in
411 For FACS, this function will locate XFirmwareCtrl in FADT first, and then
412 FirmwareCtrl in FADT.
414 @param Signature ACPI table signature.
416 @return First ACPI table or NULL if not found.
419 EFI_ACPI_COMMON_HEADER
*
421 EfiLocateFirstAcpiTable (
425 return EfiLocateNextAcpiTable (Signature
, NULL
);