2 This module provides help function for finding ACPI table.
4 Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "UefiLibInternal.h"
16 #include <IndustryStandard/Acpi.h>
17 #include <Guid/Acpi.h>
20 This function scans ACPI table in XSDT/RSDT.
22 @param Sdt ACPI XSDT/RSDT.
23 @param TablePointerSize Size of table pointer: 8(XSDT) or 4(RSDT).
24 @param Signature ACPI table signature.
25 @param PreviousTable Pointer to previous returned table to locate
26 next table, or NULL to locate first table.
27 @param PreviousTableLocated Pointer to the indicator about whether the
28 previous returned table could be located, or
29 NULL if PreviousTable is NULL.
31 If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().
32 If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().
34 @return ACPI table or NULL if not found.
37 EFI_ACPI_COMMON_HEADER
*
39 IN EFI_ACPI_DESCRIPTION_HEADER
*Sdt
,
40 IN UINTN TablePointerSize
,
42 IN EFI_ACPI_COMMON_HEADER
*PreviousTable
, OPTIONAL
43 OUT BOOLEAN
*PreviousTableLocated OPTIONAL
50 EFI_ACPI_COMMON_HEADER
*Table
;
52 if (PreviousTableLocated
!= NULL
) {
53 ASSERT (PreviousTable
!= NULL
);
54 *PreviousTableLocated
= FALSE
;
56 ASSERT (PreviousTable
== NULL
);
63 EntryCount
= (Sdt
->Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / TablePointerSize
;
65 BasePtr
= (UINTN
)(Sdt
+ 1);
66 for (Index
= 0; Index
< EntryCount
; Index
++) {
68 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* TablePointerSize
), TablePointerSize
);
69 Table
= (EFI_ACPI_COMMON_HEADER
*)((UINTN
)(EntryPtr
));
70 if ((Table
!= NULL
) && (Table
->Signature
== Signature
)) {
71 if (PreviousTable
!= NULL
) {
72 if (Table
== PreviousTable
) {
73 *PreviousTableLocated
= TRUE
;
74 } else if (*PreviousTableLocated
) {
82 // Return first table.
94 To locate FACS in FADT.
96 @param Fadt FADT table pointer.
98 @return FACS table pointer or NULL if not found.
101 EFI_ACPI_COMMON_HEADER
*
102 LocateAcpiFacsFromFadt (
103 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt
106 EFI_ACPI_COMMON_HEADER
*Facs
;
113 if (Fadt
->Header
.Revision
< EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
114 Facs
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->FirmwareCtrl
;
116 CopyMem (&Data64
, &Fadt
->XFirmwareCtrl
, sizeof(UINT64
));
118 Facs
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Data64
;
120 Facs
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->FirmwareCtrl
;
127 To locate DSDT in FADT.
129 @param Fadt FADT table pointer.
131 @return DSDT table pointer or NULL if not found.
134 EFI_ACPI_COMMON_HEADER
*
135 LocateAcpiDsdtFromFadt (
136 IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt
139 EFI_ACPI_COMMON_HEADER
*Dsdt
;
146 if (Fadt
->Header
.Revision
< EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
147 Dsdt
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->Dsdt
;
149 CopyMem (&Data64
, &Fadt
->XDsdt
, sizeof(UINT64
));
151 Dsdt
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Data64
;
153 Dsdt
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)Fadt
->Dsdt
;
160 To locate ACPI table in ACPI ConfigurationTable.
162 @param AcpiGuid The GUID used to get ACPI ConfigurationTable.
163 @param Signature ACPI table signature.
164 @param PreviousTable Pointer to previous returned table to locate
165 next table, or NULL to locate first table.
166 @param PreviousTableLocated Pointer to the indicator to return whether the
167 previous returned table could be located or not,
168 or NULL if PreviousTable is NULL.
170 If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().
171 If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().
172 If AcpiGuid is NULL, then ASSERT().
174 @return ACPI table or NULL if not found.
177 EFI_ACPI_COMMON_HEADER
*
178 LocateAcpiTableInAcpiConfigurationTable (
179 IN EFI_GUID
*AcpiGuid
,
181 IN EFI_ACPI_COMMON_HEADER
*PreviousTable
, OPTIONAL
182 OUT BOOLEAN
*PreviousTableLocated OPTIONAL
186 EFI_ACPI_COMMON_HEADER
*Table
;
187 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
;
188 EFI_ACPI_DESCRIPTION_HEADER
*Rsdt
;
189 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
190 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*Fadt
;
192 if (PreviousTableLocated
!= NULL
) {
193 ASSERT (PreviousTable
!= NULL
);
194 *PreviousTableLocated
= FALSE
;
196 ASSERT (PreviousTable
== NULL
);
201 // Get ACPI ConfigurationTable (RSD_PTR)
203 Status
= EfiGetSystemConfigurationTable(AcpiGuid
, (VOID
**)&Rsdp
);
204 if (EFI_ERROR (Status
) || (Rsdp
== NULL
)) {
213 if (Rsdp
->Revision
>= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION
) {
214 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
) Rsdp
->XsdtAddress
;
215 if (Signature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) {
216 ASSERT (PreviousTable
== NULL
);
218 // It is to locate DSDT,
219 // need to locate FADT first.
221 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*) ScanTableInSDT (
224 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
228 Table
= LocateAcpiDsdtFromFadt (Fadt
);
229 } else if (Signature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
230 ASSERT (PreviousTable
== NULL
);
232 // It is to locate FACS,
233 // need to locate FADT first.
235 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*) ScanTableInSDT (
238 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
242 Table
= LocateAcpiFacsFromFadt (Fadt
);
244 Table
= ScanTableInSDT (
256 } else if ((PreviousTableLocated
!= NULL
) &&
257 *PreviousTableLocated
) {
259 // PreviousTable could be located in XSDT,
260 // but next table could not be located in XSDT.
268 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
) Rsdp
->RsdtAddress
;
269 if (Signature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) {
270 ASSERT (PreviousTable
== NULL
);
272 // It is to locate DSDT,
273 // need to locate FADT first.
275 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*) ScanTableInSDT (
278 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
282 Table
= LocateAcpiDsdtFromFadt (Fadt
);
283 } else if (Signature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
284 ASSERT (PreviousTable
== NULL
);
286 // It is to locate FACS,
287 // need to locate FADT first.
289 Fadt
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*) ScanTableInSDT (
292 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
,
296 Table
= LocateAcpiFacsFromFadt (Fadt
);
298 Table
= ScanTableInSDT (
311 This function locates next ACPI table in XSDT/RSDT based on Signature and
312 previous returned Table.
314 If PreviousTable is NULL:
315 This function will locate the first ACPI table in XSDT/RSDT based on
316 Signature in gEfiAcpi20TableGuid system configuration table first, and then
317 gEfiAcpi10TableGuid system configuration table.
318 This function will locate in XSDT first, and then RSDT.
319 For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in
321 For FACS, this function will locate XFirmwareCtrl in FADT first, and then
322 FirmwareCtrl in FADT.
324 If PreviousTable is not NULL:
325 1. If it could be located in XSDT in gEfiAcpi20TableGuid system configuration
326 table, then this function will just locate next table in XSDT in
327 gEfiAcpi20TableGuid system configuration table.
328 2. If it could be located in RSDT in gEfiAcpi20TableGuid system configuration
329 table, then this function will just locate next table in RSDT in
330 gEfiAcpi20TableGuid system configuration table.
331 3. If it could be located in RSDT in gEfiAcpi10TableGuid system configuration
332 table, then this function will just locate next table in RSDT in
333 gEfiAcpi10TableGuid system configuration table.
335 It's not supported that PreviousTable is not NULL but PreviousTable->Signature
336 is not same with Signature, NULL will be returned.
338 @param Signature ACPI table signature.
339 @param PreviousTable Pointer to previous returned table to locate next
340 table, or NULL to locate first table.
342 @return Next ACPI table or NULL if not found.
345 EFI_ACPI_COMMON_HEADER
*
347 EfiLocateNextAcpiTable (
349 IN EFI_ACPI_COMMON_HEADER
*PreviousTable OPTIONAL
352 EFI_ACPI_COMMON_HEADER
*Table
;
353 BOOLEAN TempPreviousTableLocated
;
354 BOOLEAN
*PreviousTableLocated
;
356 if (PreviousTable
!= NULL
) {
357 if (PreviousTable
->Signature
!= Signature
) {
359 // PreviousTable->Signature is not same with Signature.
362 } else if ((Signature
== EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
) ||
363 (Signature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) ||
364 (Signature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
)) {
366 // There is only one FADT/DSDT/FACS table,
367 // so don't try to locate next one.
372 PreviousTableLocated
= &TempPreviousTableLocated
;
373 *PreviousTableLocated
= FALSE
;
375 PreviousTableLocated
= NULL
;
378 Table
= LocateAcpiTableInAcpiConfigurationTable (
379 &gEfiAcpi20TableGuid
,
386 } else if ((PreviousTableLocated
!= NULL
) &&
387 *PreviousTableLocated
) {
389 // PreviousTable could be located in gEfiAcpi20TableGuid system
390 // configuration table, but next table could not be located in
391 // gEfiAcpi20TableGuid system configuration table.
396 return LocateAcpiTableInAcpiConfigurationTable (
397 &gEfiAcpi10TableGuid
,
405 This function locates first ACPI table in XSDT/RSDT based on Signature.
407 This function will locate the first ACPI table in XSDT/RSDT based on
408 Signature in gEfiAcpi20TableGuid system configuration table first, and then
409 gEfiAcpi10TableGuid system configuration table.
410 This function will locate in XSDT first, and then RSDT.
411 For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in
413 For FACS, this function will locate XFirmwareCtrl in FADT first, and then
414 FirmwareCtrl in FADT.
416 @param Signature ACPI table signature.
418 @return First ACPI table or NULL if not found.
421 EFI_ACPI_COMMON_HEADER
*
423 EfiLocateFirstAcpiTable (
427 return EfiLocateNextAcpiTable (Signature
, NULL
);