2 ACPI Table Protocol Implementation
4 Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include "AcpiTable.h"
15 // The maximum number of tables that pre-allocated.
17 UINTN mEfiAcpiMaxNumTables
= EFI_ACPI_MAX_NUM_TABLES
;
20 // Allocation strategy to use for AllocatePages ().
21 // Runtime value depends on PcdExposedAcpiTableVersions.
23 STATIC EFI_ALLOCATE_TYPE mAcpiTableAllocType
;
26 This function adds an ACPI table to the table list. It will detect FACS and
27 allocate the correct type of memory and properly align the table.
29 @param AcpiTableInstance Instance of the protocol.
30 @param Table Table to add.
31 @param Checksum Does the table require checksumming.
32 @param Version The version of the list to add the table to.
33 @param IsFromHob True, if add Apci Table from Hob List.
34 @param Handle Pointer for returning the handle.
36 @return EFI_SUCCESS The function completed successfully.
37 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
38 @return EFI_ABORTED The table is a duplicate of a table that is required
44 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
47 IN EFI_ACPI_TABLE_VERSION Version
,
53 This function finds and removes the table specified by the handle.
55 @param AcpiTableInstance Instance of the protocol.
56 @param Version Bitmask of which versions to remove.
57 @param Handle Table to remove.
59 @return EFI_SUCCESS The function completed successfully.
60 @return EFI_ABORTED An error occurred.
61 @return EFI_NOT_FOUND Handle not found in table list.
66 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
67 IN EFI_ACPI_TABLE_VERSION Version
,
72 This function calculates and updates an UINT8 checksum.
74 @param Buffer Pointer to buffer to checksum
75 @param Size Number of bytes to checksum
76 @param ChecksumOffset Offset to place the checksum result in
78 @return EFI_SUCCESS The function completed successfully.
81 AcpiPlatformChecksum (
84 IN UINTN ChecksumOffset
88 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
90 @param AcpiTableInstance Protocol instance private data.
92 @return EFI_SUCCESS The function completed successfully.
96 ChecksumCommonTables (
97 IN OUT EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
101 // Protocol function implementations.
105 This function publishes the specified versions of the ACPI tables by
106 installing EFI configuration table entries for them. Any combination of
107 table versions can be published.
109 @param AcpiTableInstance Instance of the protocol.
110 @param Version Version(s) to publish.
112 @return EFI_SUCCESS The function completed successfully.
113 @return EFI_ABORTED The function could not complete successfully.
119 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
120 IN EFI_ACPI_TABLE_VERSION Version
124 UINT32
*CurrentRsdtEntry
;
125 VOID
*CurrentXsdtEntry
;
129 // Reorder tables as some operating systems don't seem to find the
130 // FADT correctly if it is not in the first few entries
134 // Add FADT as the first entry
136 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
137 CurrentRsdtEntry
= (UINT32
*)((UINT8
*)AcpiTableInstance
->Rsdt1
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
138 *CurrentRsdtEntry
= (UINT32
)(UINTN
)AcpiTableInstance
->Fadt1
;
140 CurrentRsdtEntry
= (UINT32
*)((UINT8
*)AcpiTableInstance
->Rsdt3
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
141 *CurrentRsdtEntry
= (UINT32
)(UINTN
)AcpiTableInstance
->Fadt3
;
144 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
145 CurrentXsdtEntry
= (VOID
*)((UINT8
*)AcpiTableInstance
->Xsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
147 // Add entry to XSDT, XSDT expects 64 bit pointers, but
148 // the table pointers in XSDT are not aligned on 8 byte boundary.
150 Buffer64
= (UINT64
)(UINTN
)AcpiTableInstance
->Fadt3
;
159 // Do checksum again because Dsdt/Xsdt is updated.
161 ChecksumCommonTables (AcpiTableInstance
);
164 // Add the RSD_PTR to the system table and store that we have installed the
167 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
168 Status
= gBS
->InstallConfigurationTable (&gEfiAcpi10TableGuid
, AcpiTableInstance
->Rsdp1
);
169 if (EFI_ERROR (Status
)) {
174 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
175 Status
= gBS
->InstallConfigurationTable (&gEfiAcpiTableGuid
, AcpiTableInstance
->Rsdp3
);
176 if (EFI_ERROR (Status
)) {
185 Installs an ACPI table into the RSDT/XSDT.
186 Note that the ACPI table should be checksumed before installing it.
187 Otherwise it will assert.
189 @param This Protocol instance pointer.
190 @param AcpiTableBuffer A pointer to a buffer containing the ACPI table to be installed.
191 @param AcpiTableBufferSize Specifies the size, in bytes, of the AcpiTableBuffer buffer.
192 @param TableKey Reurns a key to refer to the ACPI table.
194 @return EFI_SUCCESS The table was successfully inserted.
195 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize
196 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer
198 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
199 @retval EFI_ACCESS_DENIED The table signature matches a table already
200 present in the system and platform policy
201 does not allow duplicate tables of this type.
207 IN EFI_ACPI_TABLE_PROTOCOL
*This
,
208 IN VOID
*AcpiTableBuffer
,
209 IN UINTN AcpiTableBufferSize
,
213 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
215 VOID
*AcpiTableBufferConst
;
216 EFI_ACPI_TABLE_VERSION Version
;
219 // Check for invalid input parameters
221 if ( (AcpiTableBuffer
== NULL
) || (TableKey
== NULL
)
222 || (((EFI_ACPI_DESCRIPTION_HEADER
*)AcpiTableBuffer
)->Length
!= AcpiTableBufferSize
))
224 return EFI_INVALID_PARAMETER
;
227 Version
= PcdGet32 (PcdAcpiExposedTableVersions
);
230 // Get the instance of the ACPI table protocol
232 AcpiTableInstance
= EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This
);
235 // Install the ACPI table
237 AcpiTableBufferConst
= AllocateCopyPool (AcpiTableBufferSize
, AcpiTableBuffer
);
239 Status
= AddTableToList (
241 AcpiTableBufferConst
,
247 if (!EFI_ERROR (Status
)) {
248 Status
= PublishTables (
254 FreePool (AcpiTableBufferConst
);
257 // Add a new table successfully, notify registed callback
259 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol
)) {
260 if (!EFI_ERROR (Status
)) {
273 Removes an ACPI table from the RSDT/XSDT.
275 @param This Protocol instance pointer.
276 @param TableKey Specifies the table to uninstall. The key was returned from InstallAcpiTable().
278 @return EFI_SUCCESS The table was successfully uninstalled.
279 @return EFI_NOT_FOUND TableKey does not refer to a valid key for a table entry.
285 IN EFI_ACPI_TABLE_PROTOCOL
*This
,
289 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
291 EFI_ACPI_TABLE_VERSION Version
;
294 // Get the instance of the ACPI table protocol
296 AcpiTableInstance
= EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This
);
298 Version
= PcdGet32 (PcdAcpiExposedTableVersions
);
301 // Uninstall the ACPI table
303 Status
= RemoveTableFromList (
308 if (!EFI_ERROR (Status
)) {
309 Status
= PublishTables (
315 if (EFI_ERROR (Status
)) {
316 return EFI_NOT_FOUND
;
323 If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.
325 @param AcpiTableInstance ACPI table protocol instance data structure.
327 @return EFI_SUCCESS reallocate the table beffer successfully.
328 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
332 ReallocateAcpiTableBuffer (
333 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
336 UINTN NewMaxTableNumber
;
339 EFI_PHYSICAL_ADDRESS PageAddress
;
340 EFI_ACPI_TABLE_INSTANCE TempPrivateData
;
344 CopyMem (&TempPrivateData
, AcpiTableInstance
, sizeof (EFI_ACPI_TABLE_INSTANCE
));
346 // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES
348 NewMaxTableNumber
= mEfiAcpiMaxNumTables
+ EFI_ACPI_MAX_NUM_TABLES
;
350 // Create RSDT, XSDT structures and allocate buffers.
352 TotalSize
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
353 NewMaxTableNumber
* sizeof (UINT64
);
355 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
356 TotalSize
+= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
357 NewMaxTableNumber
* sizeof (UINT32
) +
358 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
359 NewMaxTableNumber
* sizeof (UINT32
);
362 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
364 // Allocate memory in the lower 32 bit of address range for
365 // compatibility with ACPI 1.0 OS.
367 // This is done because ACPI 1.0 pointers are 32 bit values.
368 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
369 // There is no architectural reason these should be below 4GB, it is purely
370 // for convenience of implementation that we force memory below 4GB.
372 PageAddress
= 0xFFFFFFFF;
373 Status
= gBS
->AllocatePages (
375 EfiACPIReclaimMemory
,
376 EFI_SIZE_TO_PAGES (TotalSize
),
380 Status
= gBS
->AllocatePool (
381 EfiACPIReclaimMemory
,
387 if (EFI_ERROR (Status
)) {
388 return EFI_OUT_OF_RESOURCES
;
391 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
392 Pointer
= (UINT8
*)(UINTN
)PageAddress
;
395 ZeroMem (Pointer
, TotalSize
);
397 AcpiTableInstance
->Rsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*)Pointer
;
398 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
399 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + NewMaxTableNumber
* sizeof (UINT32
));
400 AcpiTableInstance
->Rsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*)Pointer
;
401 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + NewMaxTableNumber
* sizeof (UINT32
));
404 AcpiTableInstance
->Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)Pointer
;
407 // Update RSDP to point to the new Rsdt and Xsdt address.
409 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
410 AcpiTableInstance
->Rsdp1
->RsdtAddress
= (UINT32
)(UINTN
)AcpiTableInstance
->Rsdt1
;
411 AcpiTableInstance
->Rsdp3
->RsdtAddress
= (UINT32
)(UINTN
)AcpiTableInstance
->Rsdt3
;
414 CurrentData
= (UINT64
)(UINTN
)AcpiTableInstance
->Xsdt
;
415 CopyMem (&AcpiTableInstance
->Rsdp3
->XsdtAddress
, &CurrentData
, sizeof (UINT64
));
418 // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer
420 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
421 CopyMem (AcpiTableInstance
->Rsdt1
, TempPrivateData
.Rsdt1
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT32
)));
422 CopyMem (AcpiTableInstance
->Rsdt3
, TempPrivateData
.Rsdt3
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT32
)));
425 CopyMem (AcpiTableInstance
->Xsdt
, TempPrivateData
.Xsdt
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT64
)));
427 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
429 // Calculate orignal ACPI table buffer size
431 TotalSize
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
432 mEfiAcpiMaxNumTables
* sizeof (UINT64
);
434 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
435 TotalSize
+= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
436 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
437 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
438 mEfiAcpiMaxNumTables
* sizeof (UINT32
);
442 (EFI_PHYSICAL_ADDRESS
)(UINTN
)TempPrivateData
.Rsdt1
,
443 EFI_SIZE_TO_PAGES (TotalSize
)
446 gBS
->FreePool (TempPrivateData
.Rsdt1
);
450 // Update the Max ACPI table number
452 mEfiAcpiMaxNumTables
= NewMaxTableNumber
;
457 Free the memory associated with the provided EFI_ACPI_TABLE_LIST instance.
459 @param TableEntry EFI_ACPI_TABLE_LIST instance pointer
465 EFI_ACPI_TABLE_LIST
*TableEntry
468 if (TableEntry
->PoolAllocation
) {
469 gBS
->FreePool (TableEntry
->Table
);
472 (EFI_PHYSICAL_ADDRESS
)(UINTN
)TableEntry
->Table
,
473 EFI_SIZE_TO_PAGES (TableEntry
->TableSize
)
479 This function adds an ACPI table to the table list. It will detect FACS and
480 allocate the correct type of memory and properly align the table.
482 @param AcpiTableInstance Instance of the protocol.
483 @param Table Table to add.
484 @param Checksum Does the table require checksumming.
485 @param Version The version of the list to add the table to.
486 @param IsFromHob True, if add Apci Table from Hob List.
487 @param Handle Pointer for returning the handle.
489 @return EFI_SUCCESS The function completed successfully.
490 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
491 @retval EFI_ACCESS_DENIED The table signature matches a table already
492 present in the system and platform policy
493 does not allow duplicate tables of this type.
498 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
501 IN EFI_ACPI_TABLE_VERSION Version
,
502 IN BOOLEAN IsFromHob
,
507 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
508 UINT32 CurrentTableSignature
;
509 UINT32 CurrentTableSize
;
510 UINT32
*CurrentRsdtEntry
;
511 VOID
*CurrentXsdtEntry
;
512 EFI_PHYSICAL_ADDRESS AllocPhysAddress
;
517 // Check for invalid input parameters
519 ASSERT (AcpiTableInstance
);
529 // Create a new list entry
531 CurrentTableList
= AllocatePool (sizeof (EFI_ACPI_TABLE_LIST
));
532 ASSERT (CurrentTableList
);
535 // Determine table type and size
537 CurrentTableSignature
= ((EFI_ACPI_COMMON_HEADER
*)Table
)->Signature
;
538 CurrentTableSize
= ((EFI_ACPI_COMMON_HEADER
*)Table
)->Length
;
541 // Allocate a buffer for the table. All tables are allocated in the lower 32 bits of address space
542 // for backwards compatibility with ACPI 1.0 OS.
544 // This is done because ACPI 1.0 pointers are 32 bit values.
545 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
546 // There is no architectural reason these should be below 4GB, it is purely
547 // for convenience of implementation that we force memory below 4GB.
549 AllocPhysAddress
= 0xFFFFFFFF;
550 CurrentTableList
->TableSize
= CurrentTableSize
;
551 CurrentTableList
->PoolAllocation
= FALSE
;
554 // Allocation memory type depends on the type of the table
556 if ((CurrentTableSignature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) ||
557 (CurrentTableSignature
== EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE
))
560 // Allocate memory for the FACS. This structure must be aligned
561 // on a 64 byte boundary and must be ACPI NVS memory.
562 // Using AllocatePages should ensure that it is always aligned.
563 // Do not change signature for new ACPI version because they are same.
565 // UEFI table also need to be in ACPI NVS memory, because some data field
566 // could be updated by OS present agent. For example, BufferPtrAddress in
567 // SMM communication ACPI table.
569 ASSERT ((EFI_PAGE_SIZE
% 64) == 0);
571 AllocPhysAddress
= (UINTN
)Table
;
572 Status
= EFI_SUCCESS
;
574 Status
= gBS
->AllocatePages (
577 EFI_SIZE_TO_PAGES (CurrentTableList
->TableSize
),
581 } else if (mAcpiTableAllocType
== AllocateAnyPages
) {
583 // If there is no allocation limit, there is also no need to use page
584 // based allocations for ACPI tables, which may be wasteful on platforms
585 // such as AArch64 that allocate multiples of 64 KB
587 Status
= gBS
->AllocatePool (
588 EfiACPIReclaimMemory
,
589 CurrentTableList
->TableSize
,
590 (VOID
**)&CurrentTableList
->Table
592 CurrentTableList
->PoolAllocation
= TRUE
;
595 // All other tables are ACPI reclaim memory, no alignment requirements.
597 Status
= gBS
->AllocatePages (
599 EfiACPIReclaimMemory
,
600 EFI_SIZE_TO_PAGES (CurrentTableList
->TableSize
),
603 CurrentTableList
->Table
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)AllocPhysAddress
;
607 // Check return value from memory alloc.
609 if (EFI_ERROR (Status
)) {
610 gBS
->FreePool (CurrentTableList
);
611 return EFI_OUT_OF_RESOURCES
;
614 if (!CurrentTableList
->PoolAllocation
) {
615 CurrentTableList
->Table
= (EFI_ACPI_COMMON_HEADER
*)(UINTN
)AllocPhysAddress
;
619 // Initialize the table contents
621 CurrentTableList
->Signature
= EFI_ACPI_TABLE_LIST_SIGNATURE
;
622 CopyMem (CurrentTableList
->Table
, Table
, CurrentTableSize
);
623 CurrentTableList
->Handle
= AcpiTableInstance
->CurrentHandle
++;
624 *Handle
= CurrentTableList
->Handle
;
625 CurrentTableList
->Version
= Version
;
628 // Update internal pointers if this is a required table. If it is a required
629 // table and a table of that type already exists, return an error.
631 // Calculate the checksum if the table is not FACS.
633 switch (CurrentTableSignature
) {
634 case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
636 // We don't add the FADT in the standard way because some
637 // OS expect the FADT to be early in the table list.
638 // So we always add it as the first element in the list.
643 // Check that the table has not been previously added.
645 if ((((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) && (AcpiTableInstance
->Fadt1
!= NULL
)) ||
646 (((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) && (AcpiTableInstance
->Fadt3
!= NULL
))
649 FreeTableMemory (CurrentTableList
);
650 gBS
->FreePool (CurrentTableList
);
651 return EFI_ACCESS_DENIED
;
655 // Add the table to the appropriate table version
657 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
659 // Save a pointer to the table
661 AcpiTableInstance
->Fadt1
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*)CurrentTableList
->Table
;
664 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
666 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= (UINT32
)(UINTN
)AcpiTableInstance
->Facs1
;
667 AcpiTableInstance
->Fadt1
->Dsdt
= (UINT32
)(UINTN
)AcpiTableInstance
->Dsdt1
;
670 // RSDP OEM information is updated to match the FADT OEM information
673 &AcpiTableInstance
->Rsdp1
->OemId
,
674 &AcpiTableInstance
->Fadt1
->Header
.OemId
,
679 // RSDT OEM information is updated to match the FADT OEM information.
682 &AcpiTableInstance
->Rsdt1
->OemId
,
683 &AcpiTableInstance
->Fadt1
->Header
.OemId
,
688 &AcpiTableInstance
->Rsdt1
->OemTableId
,
689 &AcpiTableInstance
->Fadt1
->Header
.OemTableId
,
692 AcpiTableInstance
->Rsdt1
->OemRevision
= AcpiTableInstance
->Fadt1
->Header
.OemRevision
;
695 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
697 // Save a pointer to the table
699 AcpiTableInstance
->Fadt3
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*)CurrentTableList
->Table
;
702 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
703 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
706 if ((UINT64
)(UINTN
)AcpiTableInstance
->Facs3
< BASE_4GB
) {
707 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= (UINT32
)(UINTN
)AcpiTableInstance
->Facs3
;
708 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
710 Buffer64
= (UINT64
)(UINTN
)AcpiTableInstance
->Facs3
;
712 &AcpiTableInstance
->Fadt3
->XFirmwareCtrl
,
716 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
719 if ((UINT64
)(UINTN
)AcpiTableInstance
->Dsdt3
< BASE_4GB
) {
720 AcpiTableInstance
->Fadt3
->Dsdt
= (UINT32
)(UINTN
)AcpiTableInstance
->Dsdt3
;
722 // Comment block "the caller installs the tables in "DSDT, FADT" order"
723 // The below comments are also in "the caller installs the tables in "FADT, DSDT" order" comment block.
725 // The ACPI specification, up to and including revision 5.1 Errata A,
726 // allows the DSDT and X_DSDT fields to be both set in the FADT.
727 // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)
728 // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,
729 // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,
730 // but strangely an exception is 6.0 that has no this requirement.
732 // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally
733 // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT
734 // to have better compatibility as some OS may have assumption to only consume X_DSDT
735 // field even the DSDT address is < 4G.
737 Buffer64
= AcpiTableInstance
->Fadt3
->Dsdt
;
739 AcpiTableInstance
->Fadt3
->Dsdt
= 0;
740 Buffer64
= (UINT64
)(UINTN
)AcpiTableInstance
->Dsdt3
;
743 CopyMem (&AcpiTableInstance
->Fadt3
->XDsdt
, &Buffer64
, sizeof (UINT64
));
746 // RSDP OEM information is updated to match the FADT OEM information
749 &AcpiTableInstance
->Rsdp3
->OemId
,
750 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
754 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
756 // RSDT OEM information is updated to match FADT OEM information.
759 &AcpiTableInstance
->Rsdt3
->OemId
,
760 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
764 &AcpiTableInstance
->Rsdt3
->OemTableId
,
765 &AcpiTableInstance
->Fadt3
->Header
.OemTableId
,
768 AcpiTableInstance
->Rsdt3
->OemRevision
= AcpiTableInstance
->Fadt3
->Header
.OemRevision
;
772 // XSDT OEM information is updated to match FADT OEM information.
775 &AcpiTableInstance
->Xsdt
->OemId
,
776 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
780 &AcpiTableInstance
->Xsdt
->OemTableId
,
781 &AcpiTableInstance
->Fadt3
->Header
.OemTableId
,
784 AcpiTableInstance
->Xsdt
->OemRevision
= AcpiTableInstance
->Fadt3
->Header
.OemRevision
;
788 // Checksum the table
791 AcpiPlatformChecksum (
792 CurrentTableList
->Table
,
793 CurrentTableList
->Table
->Length
,
795 EFI_ACPI_DESCRIPTION_HEADER
,
803 case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
805 // Check that the table has not been previously added.
807 if ((((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) && (AcpiTableInstance
->Facs1
!= NULL
)) ||
808 (((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) && (AcpiTableInstance
->Facs3
!= NULL
))
811 FreeTableMemory (CurrentTableList
);
812 gBS
->FreePool (CurrentTableList
);
813 return EFI_ACCESS_DENIED
;
817 // FACS is referenced by FADT and is not part of RSDT
822 // Add the table to the appropriate table version
824 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
826 // Save a pointer to the table
828 AcpiTableInstance
->Facs1
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)CurrentTableList
->Table
;
831 // If FADT already exists, update table pointers.
833 if (AcpiTableInstance
->Fadt1
!= NULL
) {
834 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= (UINT32
)(UINTN
)AcpiTableInstance
->Facs1
;
837 // Checksum FADT table
839 AcpiPlatformChecksum (
840 AcpiTableInstance
->Fadt1
,
841 AcpiTableInstance
->Fadt1
->Header
.Length
,
843 EFI_ACPI_DESCRIPTION_HEADER
,
850 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
852 // Save a pointer to the table
854 AcpiTableInstance
->Facs3
= (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*)CurrentTableList
->Table
;
857 // If FADT already exists, update table pointers.
859 if (AcpiTableInstance
->Fadt3
!= NULL
) {
861 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
864 if ((UINT64
)(UINTN
)AcpiTableInstance
->Facs3
< BASE_4GB
) {
865 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= (UINT32
)(UINTN
)AcpiTableInstance
->Facs3
;
866 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
868 Buffer64
= (UINT64
)(UINTN
)AcpiTableInstance
->Facs3
;
870 &AcpiTableInstance
->Fadt3
->XFirmwareCtrl
,
874 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
878 // Checksum FADT table
880 AcpiPlatformChecksum (
881 AcpiTableInstance
->Fadt3
,
882 AcpiTableInstance
->Fadt3
->Header
.Length
,
884 EFI_ACPI_DESCRIPTION_HEADER
,
893 case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
895 // Check that the table has not been previously added.
897 if ((((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) && (AcpiTableInstance
->Dsdt1
!= NULL
)) ||
898 (((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) && (AcpiTableInstance
->Dsdt3
!= NULL
))
901 FreeTableMemory (CurrentTableList
);
902 gBS
->FreePool (CurrentTableList
);
903 return EFI_ACCESS_DENIED
;
907 // DSDT is referenced by FADT and is not part of RSDT
912 // Add the table to the appropriate table version
914 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
916 // Save a pointer to the table
918 AcpiTableInstance
->Dsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*)CurrentTableList
->Table
;
921 // If FADT already exists, update table pointers.
923 if (AcpiTableInstance
->Fadt1
!= NULL
) {
924 AcpiTableInstance
->Fadt1
->Dsdt
= (UINT32
)(UINTN
)AcpiTableInstance
->Dsdt1
;
927 // Checksum FADT table
929 AcpiPlatformChecksum (
930 AcpiTableInstance
->Fadt1
,
931 AcpiTableInstance
->Fadt1
->Header
.Length
,
933 EFI_ACPI_DESCRIPTION_HEADER
,
940 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
942 // Save a pointer to the table
944 AcpiTableInstance
->Dsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*)CurrentTableList
->Table
;
947 // If FADT already exists, update table pointers.
949 if (AcpiTableInstance
->Fadt3
!= NULL
) {
950 if ((UINT64
)(UINTN
)AcpiTableInstance
->Dsdt3
< BASE_4GB
) {
951 AcpiTableInstance
->Fadt3
->Dsdt
= (UINT32
)(UINTN
)AcpiTableInstance
->Dsdt3
;
953 // Comment block "the caller installs the tables in "FADT, DSDT" order"
954 // The below comments are also in "the caller installs the tables in "DSDT, FADT" order" comment block.
956 // The ACPI specification, up to and including revision 5.1 Errata A,
957 // allows the DSDT and X_DSDT fields to be both set in the FADT.
958 // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)
959 // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,
960 // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,
961 // but strangely an exception is 6.0 that has no this requirement.
963 // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally
964 // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT
965 // to have better compatibility as some OS may have assumption to only consume X_DSDT
966 // field even the DSDT address is < 4G.
968 Buffer64
= AcpiTableInstance
->Fadt3
->Dsdt
;
970 AcpiTableInstance
->Fadt3
->Dsdt
= 0;
971 Buffer64
= (UINT64
)(UINTN
)AcpiTableInstance
->Dsdt3
;
974 CopyMem (&AcpiTableInstance
->Fadt3
->XDsdt
, &Buffer64
, sizeof (UINT64
));
977 // Checksum FADT table
979 AcpiPlatformChecksum (
980 AcpiTableInstance
->Fadt3
,
981 AcpiTableInstance
->Fadt3
->Header
.Length
,
983 EFI_ACPI_DESCRIPTION_HEADER
,
991 // Checksum the table
994 AcpiPlatformChecksum (
995 CurrentTableList
->Table
,
996 CurrentTableList
->Table
->Length
,
998 EFI_ACPI_DESCRIPTION_HEADER
,
1008 // Checksum the table
1011 AcpiPlatformChecksum (
1012 CurrentTableList
->Table
,
1013 CurrentTableList
->Table
->Length
,
1015 EFI_ACPI_DESCRIPTION_HEADER
,
1025 // Add the table to the current list of tables
1027 InsertTailList (&AcpiTableInstance
->TableList
, &CurrentTableList
->Link
);
1030 // Add the table to RSDT and/or XSDT table entry lists.
1033 // Add to ACPI 1.0b table tree
1035 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1038 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1040 if (AcpiTableInstance
->NumberOfTableEntries1
>= mEfiAcpiMaxNumTables
) {
1041 Status
= ReallocateAcpiTableBuffer (AcpiTableInstance
);
1042 ASSERT_EFI_ERROR (Status
);
1045 CurrentRsdtEntry
= (UINT32
*)
1047 (UINT8
*)AcpiTableInstance
->Rsdt1
+
1048 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
1049 AcpiTableInstance
->NumberOfTableEntries1
*
1054 // Add entry to the RSDT unless its the FACS or DSDT
1056 *CurrentRsdtEntry
= (UINT32
)(UINTN
)CurrentTableList
->Table
;
1059 // Update RSDT length
1061 AcpiTableInstance
->Rsdt1
->Length
= AcpiTableInstance
->Rsdt1
->Length
+ sizeof (UINT32
);
1063 AcpiTableInstance
->NumberOfTableEntries1
++;
1068 // Add to ACPI 2.0/3.0 table tree
1070 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
1073 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1075 if (AcpiTableInstance
->NumberOfTableEntries3
>= mEfiAcpiMaxNumTables
) {
1076 Status
= ReallocateAcpiTableBuffer (AcpiTableInstance
);
1077 ASSERT_EFI_ERROR (Status
);
1080 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1082 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1083 // If it becomes necessary to maintain separate table lists, changes will be required.
1085 CurrentRsdtEntry
= (UINT32
*)
1087 (UINT8
*)AcpiTableInstance
->Rsdt3
+
1088 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
1089 AcpiTableInstance
->NumberOfTableEntries3
*
1094 // Add entry to the RSDT
1096 *CurrentRsdtEntry
= (UINT32
)(UINTN
)CurrentTableList
->Table
;
1099 // Update RSDT length
1101 AcpiTableInstance
->Rsdt3
->Length
= AcpiTableInstance
->Rsdt3
->Length
+ sizeof (UINT32
);
1105 // This pointer must not be directly dereferenced as the XSDT entries may not
1106 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1108 CurrentXsdtEntry
= (VOID
*)
1110 (UINT8
*)AcpiTableInstance
->Xsdt
+
1111 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
1112 AcpiTableInstance
->NumberOfTableEntries3
*
1117 // Add entry to XSDT, XSDT expects 64 bit pointers, but
1118 // the table pointers in XSDT are not aligned on 8 byte boundary.
1120 Buffer64
= (UINT64
)(UINTN
)CurrentTableList
->Table
;
1130 AcpiTableInstance
->Xsdt
->Length
= AcpiTableInstance
->Xsdt
->Length
+ sizeof (UINT64
);
1132 AcpiTableInstance
->NumberOfTableEntries3
++;
1136 ChecksumCommonTables (AcpiTableInstance
);
1141 This function finds the table specified by the handle and returns a pointer to it.
1142 If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are
1145 @param Handle Table to find.
1146 @param TableList Table list to search
1147 @param Table Pointer to table found.
1149 @return EFI_SUCCESS The function completed successfully.
1150 @return EFI_NOT_FOUND No table found matching the handle specified.
1156 IN LIST_ENTRY
*TableList
,
1157 OUT EFI_ACPI_TABLE_LIST
**Table
1160 LIST_ENTRY
*CurrentLink
;
1161 EFI_ACPI_TABLE_LIST
*CurrentTable
;
1164 // Check for invalid input parameters
1171 CurrentLink
= TableList
->ForwardLink
;
1173 while (CurrentLink
!= TableList
) {
1174 CurrentTable
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
1175 if (CurrentTable
->Handle
== Handle
) {
1177 // Found handle, so return this table.
1179 *Table
= CurrentTable
;
1183 CurrentLink
= CurrentLink
->ForwardLink
;
1189 return EFI_NOT_FOUND
;
1193 This function removes a basic table from the RSDT and/or XSDT.
1194 For Acpi 1.0 tables, pass in the Rsdt.
1195 For Acpi 2.0 tables, pass in both Rsdt and Xsdt.
1197 @param Table Pointer to table found.
1198 @param NumberOfTableEntries Current number of table entries in the RSDT/XSDT
1199 @param Rsdt Pointer to the RSDT to remove from
1200 @param Xsdt Pointer to the Xsdt to remove from
1202 @return EFI_SUCCESS The function completed successfully.
1203 @return EFI_INVALID_PARAMETER The table was not found in both Rsdt and Xsdt.
1207 RemoveTableFromRsdt (
1208 IN OUT EFI_ACPI_TABLE_LIST
*Table
,
1209 IN OUT UINTN
*NumberOfTableEntries
,
1210 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*Rsdt OPTIONAL
,
1211 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*Xsdt OPTIONAL
1214 UINT32
*CurrentRsdtEntry
;
1215 VOID
*CurrentXsdtEntry
;
1216 UINT64 CurrentTablePointer64
;
1220 // Check for invalid input parameters
1223 ASSERT (NumberOfTableEntries
);
1224 ASSERT (Rsdt
|| Xsdt
);
1227 // Find the table entry in the RSDT and XSDT
1229 for (Index
= 0; Index
< *NumberOfTableEntries
; Index
++) {
1231 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1232 // If it becomes necessary to maintain separate table lists, changes will be required.
1235 CurrentRsdtEntry
= (UINT32
*)((UINT8
*)Rsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + Index
* sizeof (UINT32
));
1237 CurrentRsdtEntry
= NULL
;
1242 // This pointer must not be directly dereferenced as the XSDT entries may not
1243 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1245 CurrentXsdtEntry
= (VOID
*)((UINT8
*)Xsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + Index
* sizeof (UINT64
));
1248 // Read the entry value out of the XSDT
1250 CopyMem (&CurrentTablePointer64
, CurrentXsdtEntry
, sizeof (UINT64
));
1253 // Initialize to NULL
1255 CurrentXsdtEntry
= 0;
1256 CurrentTablePointer64
= 0;
1260 // Check if we have found the corresponding entry in both RSDT and XSDT
1262 if (((Rsdt
== NULL
) || (*CurrentRsdtEntry
== (UINT32
)(UINTN
)Table
->Table
)) &&
1263 ((Xsdt
== NULL
) || (CurrentTablePointer64
== (UINT64
)(UINTN
)Table
->Table
))
1267 // Found entry, so copy all following entries and shrink table
1268 // We actually copy all + 1 to copy the initialized value of memory over
1272 CopyMem (CurrentRsdtEntry
, CurrentRsdtEntry
+ 1, (*NumberOfTableEntries
- Index
) * sizeof (UINT32
));
1273 Rsdt
->Length
= Rsdt
->Length
- sizeof (UINT32
);
1277 CopyMem (CurrentXsdtEntry
, ((UINT64
*)CurrentXsdtEntry
) + 1, (*NumberOfTableEntries
- Index
) * sizeof (UINT64
));
1278 Xsdt
->Length
= Xsdt
->Length
- sizeof (UINT64
);
1282 } else if (Index
+ 1 == *NumberOfTableEntries
) {
1284 // At the last entry, and table not found
1286 return EFI_INVALID_PARAMETER
;
1291 // Checksum the tables
1294 AcpiPlatformChecksum (
1298 EFI_ACPI_DESCRIPTION_HEADER
,
1305 AcpiPlatformChecksum (
1309 EFI_ACPI_DESCRIPTION_HEADER
,
1316 // Decrement the number of tables
1318 (*NumberOfTableEntries
)--;
1324 This function removes a table and frees any associated memory.
1326 @param AcpiTableInstance Instance of the protocol.
1327 @param Version Version(s) to delete.
1328 @param Table Pointer to table found.
1330 @return EFI_SUCCESS The function completed successfully.
1335 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
1336 IN EFI_ACPI_TABLE_VERSION Version
,
1337 IN OUT EFI_ACPI_TABLE_LIST
*Table
1340 UINT32 CurrentTableSignature
;
1341 BOOLEAN RemoveFromRsdt
;
1344 // Check for invalid input parameters
1346 ASSERT (AcpiTableInstance
);
1352 RemoveFromRsdt
= TRUE
;
1354 // Check for Table->Table
1356 ASSERT (Table
->Table
!= NULL
);
1357 CurrentTableSignature
= ((EFI_ACPI_COMMON_HEADER
*)Table
->Table
)->Signature
;
1360 // Basic tasks to accomplish delete are:
1361 // Determine removal requirements (in RSDT/XSDT or not)
1362 // Remove entry from RSDT/XSDT
1363 // Remove any table references to the table
1364 // If no one is using the table
1365 // Free the table (removing pointers from private data and tables)
1367 // Free list structure
1370 // Determine if this table is in the RSDT or XSDT
1372 if ((CurrentTableSignature
== EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) ||
1373 (CurrentTableSignature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) ||
1374 (CurrentTableSignature
== EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)
1377 RemoveFromRsdt
= FALSE
;
1381 // We don't remove the FADT in the standard way because some
1382 // OS expect the FADT to be early in the table list.
1383 // So we always put it as the first element in the list.
1385 if (CurrentTableSignature
== EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
) {
1386 RemoveFromRsdt
= FALSE
;
1390 // Remove the table from RSDT and XSDT
1392 if (Table
->Table
!= NULL
) {
1394 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
1396 if (Version
& EFI_ACPI_TABLE_VERSION_NONE
& Table
->Version
) {
1398 // Remove this version from the table
1400 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_NONE
;
1403 if (Version
& EFI_ACPI_TABLE_VERSION_1_0B
& Table
->Version
) {
1405 // Remove this version from the table
1407 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_1_0B
;
1410 // Remove from Rsdt. We don't care about the return value because it is
1411 // acceptable for the table to not exist in Rsdt.
1412 // We didn't add some tables so we don't remove them.
1414 if (RemoveFromRsdt
) {
1415 RemoveTableFromRsdt (
1417 &AcpiTableInstance
->NumberOfTableEntries1
,
1418 AcpiTableInstance
->Rsdt1
,
1424 if (Version
& ACPI_TABLE_VERSION_GTE_2_0
& Table
->Version
) {
1426 // Remove this version from the table
1428 Table
->Version
= Table
->Version
&~(Version
& ACPI_TABLE_VERSION_GTE_2_0
);
1431 // Remove from Rsdt and Xsdt. We don't care about the return value
1432 // because it is acceptable for the table to not exist in Rsdt/Xsdt.
1433 // We didn't add some tables so we don't remove them.
1435 if (RemoveFromRsdt
) {
1436 RemoveTableFromRsdt (
1438 &AcpiTableInstance
->NumberOfTableEntries3
,
1439 AcpiTableInstance
->Rsdt3
,
1440 AcpiTableInstance
->Xsdt
1446 // Free the table, clean up any dependent tables and our private data pointers.
1448 switch (Table
->Table
->Signature
) {
1449 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
1450 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1451 AcpiTableInstance
->Fadt1
= NULL
;
1454 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
1455 AcpiTableInstance
->Fadt3
= NULL
;
1460 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
1461 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1462 AcpiTableInstance
->Facs1
= NULL
;
1465 // Update FADT table pointers
1467 if (AcpiTableInstance
->Fadt1
!= NULL
) {
1468 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= 0;
1473 AcpiPlatformChecksum (
1474 AcpiTableInstance
->Fadt1
,
1475 AcpiTableInstance
->Fadt1
->Header
.Length
,
1477 EFI_ACPI_DESCRIPTION_HEADER
,
1484 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
1485 AcpiTableInstance
->Facs3
= NULL
;
1488 // Update FADT table pointers
1490 if (AcpiTableInstance
->Fadt3
!= NULL
) {
1491 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
1492 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
1497 AcpiPlatformChecksum (
1498 AcpiTableInstance
->Fadt3
,
1499 AcpiTableInstance
->Fadt3
->Header
.Length
,
1501 EFI_ACPI_DESCRIPTION_HEADER
,
1510 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
1511 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1512 AcpiTableInstance
->Dsdt1
= NULL
;
1515 // Update FADT table pointers
1517 if (AcpiTableInstance
->Fadt1
!= NULL
) {
1518 AcpiTableInstance
->Fadt1
->Dsdt
= 0;
1523 AcpiPlatformChecksum (
1524 AcpiTableInstance
->Fadt1
,
1525 AcpiTableInstance
->Fadt1
->Header
.Length
,
1527 EFI_ACPI_DESCRIPTION_HEADER
,
1534 if ((Version
& ACPI_TABLE_VERSION_GTE_2_0
) != 0) {
1535 AcpiTableInstance
->Dsdt3
= NULL
;
1538 // Update FADT table pointers
1540 if (AcpiTableInstance
->Fadt3
!= NULL
) {
1541 AcpiTableInstance
->Fadt3
->Dsdt
= 0;
1542 ZeroMem (&AcpiTableInstance
->Fadt3
->XDsdt
, sizeof (UINT64
));
1547 AcpiPlatformChecksum (
1548 AcpiTableInstance
->Fadt3
,
1549 AcpiTableInstance
->Fadt3
->Header
.Length
,
1551 EFI_ACPI_DESCRIPTION_HEADER
,
1569 // If no version is using this table anymore, remove and free list entry.
1571 if (Table
->Version
== 0) {
1575 FreeTableMemory (Table
);
1576 RemoveEntryList (&(Table
->Link
));
1577 gBS
->FreePool (Table
);
1587 This function finds and removes the table specified by the handle.
1589 @param AcpiTableInstance Instance of the protocol.
1590 @param Version Bitmask of which versions to remove.
1591 @param Handle Table to remove.
1593 @return EFI_SUCCESS The function completed successfully.
1594 @return EFI_ABORTED An error occurred.
1595 @return EFI_NOT_FOUND Handle not found in table list.
1599 RemoveTableFromList (
1600 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
1601 IN EFI_ACPI_TABLE_VERSION Version
,
1605 EFI_ACPI_TABLE_LIST
*Table
;
1608 Table
= (EFI_ACPI_TABLE_LIST
*)NULL
;
1611 // Check for invalid input parameters
1613 ASSERT (AcpiTableInstance
);
1618 Status
= FindTableByHandle (
1620 &AcpiTableInstance
->TableList
,
1623 if (EFI_ERROR (Status
)) {
1624 return EFI_NOT_FOUND
;
1630 Status
= DeleteTable (AcpiTableInstance
, Version
, Table
);
1631 if (EFI_ERROR (Status
)) {
1636 // Completed successfully
1642 This function calculates and updates an UINT8 checksum.
1644 @param Buffer Pointer to buffer to checksum
1645 @param Size Number of bytes to checksum
1646 @param ChecksumOffset Offset to place the checksum result in
1648 @return EFI_SUCCESS The function completed successfully.
1652 AcpiPlatformChecksum (
1655 IN UINTN ChecksumOffset
1663 // Initialize pointer
1668 // set checksum to 0 first
1670 Ptr
[ChecksumOffset
] = 0;
1673 // add all content of buffer
1675 while ((Size
--) != 0) {
1676 Sum
= (UINT8
)(Sum
+ (*Ptr
++));
1683 Ptr
[ChecksumOffset
] = (UINT8
)(0xff - Sum
+ 1);
1689 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
1691 @param AcpiTableInstance Protocol instance private data.
1693 @return EFI_SUCCESS The function completed successfully.
1697 ChecksumCommonTables (
1698 IN OUT EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1702 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure
1704 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1705 AcpiPlatformChecksum (
1706 AcpiTableInstance
->Rsdp1
,
1707 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1709 EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1716 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure
1718 AcpiPlatformChecksum (
1719 AcpiTableInstance
->Rsdp3
,
1720 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1722 EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1728 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
1730 AcpiPlatformChecksum (
1731 AcpiTableInstance
->Rsdp3
,
1732 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1734 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1739 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1743 AcpiPlatformChecksum (
1744 AcpiTableInstance
->Rsdt1
,
1745 AcpiTableInstance
->Rsdt1
->Length
,
1747 EFI_ACPI_DESCRIPTION_HEADER
,
1752 AcpiPlatformChecksum (
1753 AcpiTableInstance
->Rsdt3
,
1754 AcpiTableInstance
->Rsdt3
->Length
,
1756 EFI_ACPI_DESCRIPTION_HEADER
,
1765 AcpiPlatformChecksum (
1766 AcpiTableInstance
->Xsdt
,
1767 AcpiTableInstance
->Xsdt
->Length
,
1769 EFI_ACPI_DESCRIPTION_HEADER
,
1778 This function will find gUniversalPayloadAcpiTableGuid Guid Hob, and install Acpi table from it.
1780 @param AcpiTableInstance Protocol instance private data.
1782 @return EFI_SUCCESS The function completed successfully.
1783 @return EFI_NOT_FOUND The function doesn't find the gEfiAcpiTableGuid Guid Hob.
1784 @return EFI_ABORTED The function could not complete successfully.
1788 InstallAcpiTableFromHob (
1789 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1792 EFI_HOB_GUID_TYPE
*GuidHob
;
1793 EFI_ACPI_TABLE_VERSION Version
;
1794 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
;
1795 EFI_ACPI_DESCRIPTION_HEADER
*Rsdt
;
1796 EFI_ACPI_DESCRIPTION_HEADER
*ChildTable
;
1797 UINT64 ChildTableAddress
;
1803 UNIVERSAL_PAYLOAD_ACPI_TABLE
*AcpiTableAdress
;
1804 VOID
*TableToInstall
;
1805 EFI_ACPI_SDT_HEADER
*Table
;
1806 UNIVERSAL_PAYLOAD_GENERIC_HEADER
*GenericHeader
;
1809 Version
= PcdGet32 (PcdAcpiExposedTableVersions
);
1810 Status
= EFI_SUCCESS
;
1812 // HOB only contains the ACPI table in 2.0+ format.
1814 GuidHob
= GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid
);
1815 if (GuidHob
== NULL
) {
1816 return EFI_NOT_FOUND
;
1819 GenericHeader
= (UNIVERSAL_PAYLOAD_GENERIC_HEADER
*)GET_GUID_HOB_DATA (GuidHob
);
1820 if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER
) > GET_GUID_HOB_DATA_SIZE (GuidHob
)) || (GenericHeader
->Length
> GET_GUID_HOB_DATA_SIZE (GuidHob
))) {
1821 return EFI_NOT_FOUND
;
1824 if (GenericHeader
->Revision
== UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
) {
1826 // UNIVERSAL_PAYLOAD_ACPI_TABLE structure is used when Revision equals to UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
1828 AcpiTableAdress
= (UNIVERSAL_PAYLOAD_ACPI_TABLE
*)GET_GUID_HOB_DATA (GuidHob
);
1829 if (AcpiTableAdress
->Header
.Length
< UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_ACPI_TABLE
, Rsdp
)) {
1831 // Retrun if can't find the ACPI Info Hob with enough length
1833 return EFI_NOT_FOUND
;
1836 Rsdp
= (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)(UINTN
)(AcpiTableAdress
->Rsdp
);
1839 // An ACPI-compatible OS must use the XSDT if present.
1840 // It shouldn't happen that XsdtAddress points beyond 4G range in 32-bit environment.
1842 ASSERT ((UINTN
)Rsdp
->XsdtAddress
== Rsdp
->XsdtAddress
);
1844 EntrySize
= sizeof (UINT64
);
1845 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)Rsdp
->XsdtAddress
;
1848 // XsdtAddress is zero, then we use Rsdt which has 32 bit entry
1850 Rsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)Rsdp
->RsdtAddress
;
1851 EntrySize
= sizeof (UINT32
);
1854 if (Rsdt
->Length
<= sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) {
1858 Count
= (Rsdt
->Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / EntrySize
;
1860 for (Index
= 0; Index
< Count
; Index
++) {
1861 ChildTableAddress
= 0;
1862 CopyMem (&ChildTableAddress
, (UINT8
*)(Rsdt
+ 1) + EntrySize
* Index
, EntrySize
);
1864 // If the address is of UINT64 while this module runs at 32 bits,
1865 // make sure the upper bits are all-zeros.
1867 ASSERT (ChildTableAddress
== (UINTN
)ChildTableAddress
);
1868 if (ChildTableAddress
!= (UINTN
)ChildTableAddress
) {
1869 Status
= EFI_ABORTED
;
1873 ChildTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)ChildTableAddress
;
1874 Status
= AddTableToList (AcpiTableInstance
, ChildTable
, TRUE
, Version
, TRUE
, &TableKey
);
1875 if (EFI_ERROR (Status
)) {
1876 DEBUG ((DEBUG_ERROR
, "InstallAcpiTableFromHob: Fail to add ACPI table at 0x%p\n", ChildTable
));
1877 ASSERT_EFI_ERROR (Status
);
1881 if (ChildTable
->Signature
== EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
) {
1883 // Add the FACS and DSDT tables if it is not NULL.
1885 if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ChildTable
)->FirmwareCtrl
!= 0) {
1886 TableToInstall
= (VOID
*)(UINTN
)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ChildTable
)->FirmwareCtrl
;
1887 Status
= AddTableToList (AcpiTableInstance
, TableToInstall
, TRUE
, Version
, TRUE
, &TableKey
);
1888 if (EFI_ERROR (Status
)) {
1889 DEBUG ((DEBUG_ERROR
, "InstallAcpiTableFromHob: Fail to add ACPI table FACS\n"));
1890 ASSERT_EFI_ERROR (Status
);
1895 if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ChildTable
)->Dsdt
!= 0) {
1896 TableToInstall
= (VOID
*)(UINTN
)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*)ChildTable
)->Dsdt
;
1897 Status
= AddTableToList (AcpiTableInstance
, TableToInstall
, TRUE
, Version
, TRUE
, &TableKey
);
1898 if (EFI_ERROR (Status
)) {
1899 DEBUG ((DEBUG_ERROR
, "InstallAcpiTableFromHob: Fail to add ACPI table DSDT\n"));
1900 ASSERT_EFI_ERROR (Status
);
1907 return EFI_NOT_FOUND
;
1910 if (EFI_ERROR (Status
)) {
1912 // Error happens when trying to add ACPI table to the list.
1913 // Remove all of them from list because at this time, no other tables except from HOB are in the list
1915 while (SdtGetAcpiTable (AcpiTableInstance
, 0, &Table
, &Version
, &TableKey
) == EFI_SUCCESS
) {
1916 RemoveTableFromList (AcpiTableInstance
, Version
, TableKey
);
1919 Status
= PublishTables (AcpiTableInstance
, Version
);
1922 ASSERT_EFI_ERROR (Status
);
1927 Constructor for the ACPI table protocol. Initializes instance
1930 @param AcpiTableInstance Instance to construct
1932 @return EFI_SUCCESS Instance initialized.
1933 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
1937 AcpiTableAcpiTableConstructor (
1938 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1944 UINTN RsdpTableSize
;
1946 EFI_PHYSICAL_ADDRESS PageAddress
;
1949 // Check for invalid input parameters
1951 ASSERT (AcpiTableInstance
);
1954 // If ACPI v1.0b is among the ACPI versions we aim to support, we have to
1955 // ensure that all memory allocations are below 4 GB.
1957 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1958 mAcpiTableAllocType
= AllocateMaxAddress
;
1960 mAcpiTableAllocType
= AllocateAnyPages
;
1963 InitializeListHead (&AcpiTableInstance
->TableList
);
1964 AcpiTableInstance
->CurrentHandle
= 1;
1966 AcpiTableInstance
->AcpiTableProtocol
.InstallAcpiTable
= InstallAcpiTable
;
1967 AcpiTableInstance
->AcpiTableProtocol
.UninstallAcpiTable
= UninstallAcpiTable
;
1969 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol
)) {
1970 SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance
);
1974 // Create RSDP table
1976 RsdpTableSize
= sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1977 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1978 RsdpTableSize
+= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1981 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
1982 PageAddress
= 0xFFFFFFFF;
1983 Status
= gBS
->AllocatePages (
1984 mAcpiTableAllocType
,
1985 EfiACPIReclaimMemory
,
1986 EFI_SIZE_TO_PAGES (RsdpTableSize
),
1990 Status
= gBS
->AllocatePool (
1991 EfiACPIReclaimMemory
,
1997 if (EFI_ERROR (Status
)) {
1998 return EFI_OUT_OF_RESOURCES
;
2001 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
2002 Pointer
= (UINT8
*)(UINTN
)PageAddress
;
2005 ZeroMem (Pointer
, RsdpTableSize
);
2007 AcpiTableInstance
->Rsdp1
= (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)Pointer
;
2008 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
2009 Pointer
+= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
2012 AcpiTableInstance
->Rsdp3
= (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)Pointer
;
2015 // Create RSDT, XSDT structures
2017 TotalSize
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
2018 mEfiAcpiMaxNumTables
* sizeof (UINT64
);
2020 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
2021 TotalSize
+= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
2022 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
2023 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
2024 mEfiAcpiMaxNumTables
* sizeof (UINT32
);
2027 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
2029 // Allocate memory in the lower 32 bit of address range for
2030 // compatibility with ACPI 1.0 OS.
2032 // This is done because ACPI 1.0 pointers are 32 bit values.
2033 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
2034 // There is no architectural reason these should be below 4GB, it is purely
2035 // for convenience of implementation that we force memory below 4GB.
2037 PageAddress
= 0xFFFFFFFF;
2038 Status
= gBS
->AllocatePages (
2039 mAcpiTableAllocType
,
2040 EfiACPIReclaimMemory
,
2041 EFI_SIZE_TO_PAGES (TotalSize
),
2045 Status
= gBS
->AllocatePool (
2046 EfiACPIReclaimMemory
,
2052 if (EFI_ERROR (Status
)) {
2053 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
2055 (EFI_PHYSICAL_ADDRESS
)(UINTN
)AcpiTableInstance
->Rsdp1
,
2056 EFI_SIZE_TO_PAGES (RsdpTableSize
)
2059 gBS
->FreePool (AcpiTableInstance
->Rsdp1
);
2062 return EFI_OUT_OF_RESOURCES
;
2065 if (mAcpiTableAllocType
!= AllocateAnyPages
) {
2066 Pointer
= (UINT8
*)(UINTN
)PageAddress
;
2069 ZeroMem (Pointer
, TotalSize
);
2071 AcpiTableInstance
->Rsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*)Pointer
;
2072 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
2073 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + EFI_ACPI_MAX_NUM_TABLES
* sizeof (UINT32
));
2074 AcpiTableInstance
->Rsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*)Pointer
;
2075 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + EFI_ACPI_MAX_NUM_TABLES
* sizeof (UINT32
));
2078 AcpiTableInstance
->Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)Pointer
;
2083 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
2084 CurrentData
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
;
2085 CopyMem (&AcpiTableInstance
->Rsdp1
->Signature
, &CurrentData
, sizeof (UINT64
));
2086 CopyMem (AcpiTableInstance
->Rsdp1
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdp1
->OemId
));
2087 AcpiTableInstance
->Rsdp1
->Reserved
= EFI_ACPI_RESERVED_BYTE
;
2088 AcpiTableInstance
->Rsdp1
->RsdtAddress
= (UINT32
)(UINTN
)AcpiTableInstance
->Rsdt1
;
2091 CurrentData
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
;
2092 CopyMem (&AcpiTableInstance
->Rsdp3
->Signature
, &CurrentData
, sizeof (UINT64
));
2093 CopyMem (AcpiTableInstance
->Rsdp3
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdp3
->OemId
));
2094 AcpiTableInstance
->Rsdp3
->Revision
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION
;
2095 AcpiTableInstance
->Rsdp3
->Length
= sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
2096 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
2097 AcpiTableInstance
->Rsdp3
->RsdtAddress
= (UINT32
)(UINTN
)AcpiTableInstance
->Rsdt3
;
2100 CurrentData
= (UINT64
)(UINTN
)AcpiTableInstance
->Xsdt
;
2101 CopyMem (&AcpiTableInstance
->Rsdp3
->XsdtAddress
, &CurrentData
, sizeof (UINT64
));
2102 SetMem (AcpiTableInstance
->Rsdp3
->Reserved
, 3, EFI_ACPI_RESERVED_BYTE
);
2104 if ((PcdGet32 (PcdAcpiExposedTableVersions
) & EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
2108 // Note that we "reserve" one entry for the FADT so it can always be
2109 // at the beginning of the list of tables. Some OS don't seem
2110 // to find it correctly if it is too far down the list.
2112 AcpiTableInstance
->Rsdt1
->Signature
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
2113 AcpiTableInstance
->Rsdt1
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
2114 AcpiTableInstance
->Rsdt1
->Revision
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
;
2115 CopyMem (AcpiTableInstance
->Rsdt1
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdt1
->OemId
));
2116 CurrentData
= PcdGet64 (PcdAcpiDefaultOemTableId
);
2117 CopyMem (&AcpiTableInstance
->Rsdt1
->OemTableId
, &CurrentData
, sizeof (UINT64
));
2118 AcpiTableInstance
->Rsdt1
->OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
2119 AcpiTableInstance
->Rsdt1
->CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
2120 AcpiTableInstance
->Rsdt1
->CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
2122 // We always reserve first one for FADT
2124 AcpiTableInstance
->NumberOfTableEntries1
= 1;
2125 AcpiTableInstance
->Rsdt1
->Length
= AcpiTableInstance
->Rsdt1
->Length
+ sizeof (UINT32
);
2127 AcpiTableInstance
->Rsdt3
->Signature
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
2128 AcpiTableInstance
->Rsdt3
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
2129 AcpiTableInstance
->Rsdt3
->Revision
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
;
2130 CopyMem (AcpiTableInstance
->Rsdt3
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdt3
->OemId
));
2131 CurrentData
= PcdGet64 (PcdAcpiDefaultOemTableId
);
2132 CopyMem (&AcpiTableInstance
->Rsdt3
->OemTableId
, &CurrentData
, sizeof (UINT64
));
2133 AcpiTableInstance
->Rsdt3
->OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
2134 AcpiTableInstance
->Rsdt3
->CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
2135 AcpiTableInstance
->Rsdt3
->CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
2137 // We always reserve first one for FADT
2139 AcpiTableInstance
->Rsdt3
->Length
= AcpiTableInstance
->Rsdt3
->Length
+ sizeof (UINT32
);
2142 AcpiTableInstance
->NumberOfTableEntries3
= 1;
2147 AcpiTableInstance
->Xsdt
->Signature
= EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
2148 AcpiTableInstance
->Xsdt
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
2149 AcpiTableInstance
->Xsdt
->Revision
= EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION
;
2150 CopyMem (AcpiTableInstance
->Xsdt
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Xsdt
->OemId
));
2151 CurrentData
= PcdGet64 (PcdAcpiDefaultOemTableId
);
2152 CopyMem (&AcpiTableInstance
->Xsdt
->OemTableId
, &CurrentData
, sizeof (UINT64
));
2153 AcpiTableInstance
->Xsdt
->OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
2154 AcpiTableInstance
->Xsdt
->CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
2155 AcpiTableInstance
->Xsdt
->CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
2157 // We always reserve first one for FADT
2159 AcpiTableInstance
->Xsdt
->Length
= AcpiTableInstance
->Xsdt
->Length
+ sizeof (UINT64
);
2161 ChecksumCommonTables (AcpiTableInstance
);
2163 InstallAcpiTableFromHob (AcpiTableInstance
);
2166 // Completed successfully