2 ACPI Table Protocol Implementation
4 Copyright (c) 2006 - 2010, 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.
18 #include "AcpiTable.h"
20 // The maximum number of tables that pre-allocated.
22 UINTN mEfiAcpiMaxNumTables
= EFI_ACPI_MAX_NUM_TABLES
;
25 This function adds an ACPI table to the table list. It will detect FACS and
26 allocate the correct type of memory and properly align the table.
28 @param AcpiTableInstance Instance of the protocol.
29 @param Table Table to add.
30 @param Checksum Does the table require checksumming.
31 @param Version The version of the list to add the table to.
32 @param Handle Pointer for returning the handle.
34 @return EFI_SUCCESS The function completed successfully.
35 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
36 @return EFI_ABORTED The table is a duplicate of a table that is required
42 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
45 IN EFI_ACPI_TABLE_VERSION Version
,
50 This function finds and removes the table specified by the handle.
52 @param AcpiTableInstance Instance of the protocol.
53 @param Version Bitmask of which versions to remove.
54 @param Handle Table to remove.
56 @return EFI_SUCCESS The function completed successfully.
57 @return EFI_ABORTED An error occurred.
58 @return EFI_NOT_FOUND Handle not found in table list.
63 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
64 IN EFI_ACPI_TABLE_VERSION Version
,
69 This function calculates and updates an UINT8 checksum.
71 @param Buffer Pointer to buffer to checksum
72 @param Size Number of bytes to checksum
73 @param ChecksumOffset Offset to place the checksum result in
75 @return EFI_SUCCESS The function completed successfully.
78 AcpiPlatformChecksum (
81 IN UINTN ChecksumOffset
85 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
87 @param AcpiTableInstance Protocol instance private data.
89 @return EFI_SUCCESS The function completed successfully.
93 ChecksumCommonTables (
94 IN OUT EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
98 // Protocol function implementations.
102 This function adds, removes, or updates ACPI tables. If the address is not
103 null and the handle value is null, the table is added. If both the address and
104 handle are not null, the table at handle is updated with the table at address.
105 If the address is null and the handle is not, the table at handle is deleted.
107 @param AcpiTableInstance Instance of the protocol.
108 @param Table Pointer to a table.
109 @param Checksum Boolean indicating if the checksum should be calculated.
110 @param Version Version(s) to set.
111 @param Handle Handle of the table.
113 @return EFI_SUCCESS The function completed successfully.
114 @return EFI_INVALID_PARAMETER Both the Table and *Handle were NULL.
115 @return EFI_ABORTED Could not complete the desired request.
121 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
122 IN VOID
*Table OPTIONAL
,
124 IN EFI_ACPI_TABLE_VERSION Version
,
132 // Check for invalid input parameters
140 // Determine desired action
145 // Invalid parameter combination
147 return EFI_INVALID_PARAMETER
;
152 Status
= AddTableToList (AcpiTableInstance
, Table
, Checksum
, Version
, Handle
);
160 // Delete the table list entry
162 Status
= RemoveTableFromList (AcpiTableInstance
, Version
, *Handle
);
163 if (EFI_ERROR (Status
)) {
165 // Should not get an error here ever, but abort if we do.
170 // Set the handle to replace the table at the same handle
172 SavedHandle
= AcpiTableInstance
->CurrentHandle
;
173 AcpiTableInstance
->CurrentHandle
= *Handle
;
178 Status
= AddTableToList (AcpiTableInstance
, Table
, Checksum
, Version
, Handle
);
181 // Restore the saved current handle
183 AcpiTableInstance
->CurrentHandle
= SavedHandle
;
188 Status
= RemoveTableFromList (AcpiTableInstance
, Version
, *Handle
);
192 if (EFI_ERROR (Status
)) {
194 // Should not get an error here ever, but abort if we do.
205 This function publishes the specified versions of the ACPI tables by
206 installing EFI configuration table entries for them. Any combination of
207 table versions can be published.
209 @param AcpiTableInstance Instance of the protocol.
210 @param Version Version(s) to publish.
212 @return EFI_SUCCESS The function completed successfully.
213 @return EFI_ABORTED The function could not complete successfully.
219 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
220 IN EFI_ACPI_TABLE_VERSION Version
224 UINT32
*CurrentRsdtEntry
;
225 VOID
*CurrentXsdtEntry
;
229 // Reorder tables as some operating systems don't seem to find the
230 // FADT correctly if it is not in the first few entries
234 // Add FADT as the first entry
236 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
237 CurrentRsdtEntry
= (UINT32
*) ((UINT8
*) AcpiTableInstance
->Rsdt1
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
238 *CurrentRsdtEntry
= (UINT32
) (UINTN
) AcpiTableInstance
->Fadt1
;
240 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
241 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
242 CurrentRsdtEntry
= (UINT32
*) ((UINT8
*) AcpiTableInstance
->Rsdt3
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
243 *CurrentRsdtEntry
= (UINT32
) (UINTN
) AcpiTableInstance
->Fadt3
;
244 CurrentXsdtEntry
= (VOID
*) ((UINT8
*) AcpiTableInstance
->Xsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
246 // Add entry to XSDT, XSDT expects 64 bit pointers, but
247 // the table pointers in XSDT are not aligned on 8 byte boundary.
249 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Fadt3
;
258 // Do checksum again because Dsdt/Xsdt is updated.
260 ChecksumCommonTables (AcpiTableInstance
);
263 // Add the RSD_PTR to the system table and store that we have installed the
266 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) &&
267 !AcpiTableInstance
->TablesInstalled1
) {
268 Status
= gBS
->InstallConfigurationTable (&gEfiAcpi10TableGuid
, AcpiTableInstance
->Rsdp1
);
269 if (EFI_ERROR (Status
)) {
273 AcpiTableInstance
->TablesInstalled1
= TRUE
;
276 if (((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
277 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) &&
278 !AcpiTableInstance
->TablesInstalled3
) {
279 Status
= gBS
->InstallConfigurationTable (&gEfiAcpiTableGuid
, AcpiTableInstance
->Rsdp3
);
280 if (EFI_ERROR (Status
)) {
284 AcpiTableInstance
->TablesInstalled3
= TRUE
;
292 Installs an ACPI table into the RSDT/XSDT.
293 Note that the ACPI table should be checksumed before installing it.
294 Otherwise it will assert.
296 @param This Protocol instance pointer.
297 @param AcpiTableBuffer A pointer to a buffer containing the ACPI table to be installed.
298 @param AcpiTableBufferSize Specifies the size, in bytes, of the AcpiTableBuffer buffer.
299 @param TableKey Reurns a key to refer to the ACPI table.
301 @return EFI_SUCCESS The table was successfully inserted.
302 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize
303 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer
305 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
311 IN CONST EFI_ACPI_TABLE_PROTOCOL
*This
,
312 IN CONST VOID
*AcpiTableBuffer
,
313 IN UINTN AcpiTableBufferSize
,
317 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
319 VOID
*AcpiTableBufferConst
;
324 // Check for invalid input parameters
326 if ((AcpiTableBuffer
== NULL
) || (TableKey
== NULL
)
327 || (((EFI_ACPI_DESCRIPTION_HEADER
*) AcpiTableBuffer
)->Length
!= AcpiTableBufferSize
)) {
328 return EFI_INVALID_PARAMETER
;
331 Length
= ((EFI_ACPI_COMMON_HEADER
*) AcpiTableBuffer
)->Length
;
332 Checksum
= CalculateCheckSum8 ((UINT8
*)AcpiTableBuffer
, Length
);
334 AcpiPlatformChecksum (
335 (VOID
*)AcpiTableBuffer
,
337 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
, Checksum
)
342 // Get the instance of the ACPI table protocol
344 AcpiTableInstance
= EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This
);
347 // Install the ACPI table
349 AcpiTableBufferConst
= AllocateCopyPool (AcpiTableBufferSize
,AcpiTableBuffer
);
351 Status
= SetAcpiTable (
353 AcpiTableBufferConst
,
355 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
,
358 if (!EFI_ERROR (Status
)) {
359 Status
= PublishTables (
361 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
364 FreePool (AcpiTableBufferConst
);
367 // Add a new table successfully, notify registed callback
369 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol
)) {
370 if (!EFI_ERROR (Status
)) {
373 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
,
384 Removes an ACPI table from the RSDT/XSDT.
386 @param This Protocol instance pointer.
387 @param TableKey Specifies the table to uninstall. The key was returned from InstallAcpiTable().
389 @return EFI_SUCCESS The table was successfully uninstalled.
390 @return EFI_NOT_FOUND TableKey does not refer to a valid key for a table entry.
396 IN CONST EFI_ACPI_TABLE_PROTOCOL
*This
,
400 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
404 // Get the instance of the ACPI table protocol
406 AcpiTableInstance
= EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This
);
409 // Uninstall the ACPI table
411 Status
= SetAcpiTable (
415 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
,
418 if (!EFI_ERROR (Status
)) {
419 Status
= PublishTables (
421 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
425 if (EFI_ERROR (Status
)) {
426 return EFI_NOT_FOUND
;
433 If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.
435 @param AcpiTableInstance ACPI table protocol instance data structure.
437 @return EFI_SUCCESS reallocate the table beffer successfully.
438 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
442 ReallocateAcpiTableBuffer (
443 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
446 UINTN NewMaxTableNumber
;
449 EFI_PHYSICAL_ADDRESS PageAddress
;
450 EFI_ACPI_TABLE_INSTANCE TempPrivateData
;
454 CopyMem (&TempPrivateData
, AcpiTableInstance
, sizeof (EFI_ACPI_TABLE_INSTANCE
));
456 // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES
458 NewMaxTableNumber
= mEfiAcpiMaxNumTables
+ EFI_ACPI_MAX_NUM_TABLES
;
460 // Create RSDP, RSDT, XSDT structures and allocate all buffers
462 TotalSize
= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
463 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
464 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
465 NewMaxTableNumber
* sizeof (UINT32
) +
466 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
467 NewMaxTableNumber
* sizeof (UINT32
) +
468 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
469 NewMaxTableNumber
* sizeof (UINT64
);
472 // Allocate memory in the lower 32 bit of address range for
473 // compatibility with ACPI 1.0 OS.
475 // This is done because ACPI 1.0 pointers are 32 bit values.
476 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
477 // There is no architectural reason these should be below 4GB, it is purely
478 // for convenience of implementation that we force memory below 4GB.
480 PageAddress
= 0xFFFFFFFF;
481 Status
= gBS
->AllocatePages (
483 EfiACPIReclaimMemory
,
484 EFI_SIZE_TO_PAGES (TotalSize
),
488 if (EFI_ERROR (Status
)) {
489 return EFI_OUT_OF_RESOURCES
;
492 Pointer
= (UINT8
*) (UINTN
) PageAddress
;
493 ZeroMem (Pointer
, TotalSize
);
495 AcpiTableInstance
->Rsdp1
= (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*) Pointer
;
496 Pointer
+= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
497 AcpiTableInstance
->Rsdp3
= (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*) Pointer
;
498 Pointer
+= sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
500 AcpiTableInstance
->Rsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
501 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + NewMaxTableNumber
* sizeof (UINT32
));
502 AcpiTableInstance
->Rsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
503 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + NewMaxTableNumber
* sizeof (UINT32
));
505 AcpiTableInstance
->Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
510 CopyMem (AcpiTableInstance
->Rsdp1
, TempPrivateData
.Rsdp1
, sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
));
511 AcpiTableInstance
->Rsdp1
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt1
;
513 CopyMem (AcpiTableInstance
->Rsdp3
, TempPrivateData
.Rsdp3
, sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
));
514 AcpiTableInstance
->Rsdp3
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt3
;
515 CurrentData
= (UINT64
) (UINTN
) AcpiTableInstance
->Xsdt
;
516 CopyMem (&AcpiTableInstance
->Rsdp3
->XsdtAddress
, &CurrentData
, sizeof (UINT64
));
519 // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer
521 CopyMem (AcpiTableInstance
->Rsdt1
, TempPrivateData
.Rsdt1
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT32
)));
522 CopyMem (AcpiTableInstance
->Rsdt3
, TempPrivateData
.Rsdt3
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT32
)));
523 CopyMem (AcpiTableInstance
->Xsdt
, TempPrivateData
.Xsdt
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT64
)));
526 // Calculate orignal ACPI table buffer size
528 TotalSize
= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
529 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
530 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
531 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
532 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
533 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
534 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
535 mEfiAcpiMaxNumTables
* sizeof (UINT64
);
536 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)TempPrivateData
.Rsdp1
, EFI_SIZE_TO_PAGES (TotalSize
));
539 // Update the Max ACPI table number
541 mEfiAcpiMaxNumTables
= NewMaxTableNumber
;
545 This function adds an ACPI table to the table list. It will detect FACS and
546 allocate the correct type of memory and properly align the table.
548 @param AcpiTableInstance Instance of the protocol.
549 @param Table Table to add.
550 @param Checksum Does the table require checksumming.
551 @param Version The version of the list to add the table to.
552 @param Handle Pointer for returning the handle.
554 @return EFI_SUCCESS The function completed successfully.
555 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
556 @return EFI_ABORTED The table is a duplicate of a table that is required
562 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
565 IN EFI_ACPI_TABLE_VERSION Version
,
570 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
571 UINT32 CurrentTableSignature
;
572 UINT32 CurrentTableSize
;
573 UINT32
*CurrentRsdtEntry
;
574 VOID
*CurrentXsdtEntry
;
579 // Check for invalid input parameters
581 ASSERT (AcpiTableInstance
);
591 // Create a new list entry
593 CurrentTableList
= AllocatePool (sizeof (EFI_ACPI_TABLE_LIST
));
594 ASSERT (CurrentTableList
);
597 // Determine table type and size
599 CurrentTableSignature
= ((EFI_ACPI_COMMON_HEADER
*) Table
)->Signature
;
600 CurrentTableSize
= ((EFI_ACPI_COMMON_HEADER
*) Table
)->Length
;
603 // Allocate a buffer for the table. All tables are allocated in the lower 32 bits of address space
604 // for backwards compatibility with ACPI 1.0 OS.
606 // This is done because ACPI 1.0 pointers are 32 bit values.
607 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
608 // There is no architectural reason these should be below 4GB, it is purely
609 // for convenience of implementation that we force memory below 4GB.
611 CurrentTableList
->PageAddress
= 0xFFFFFFFF;
612 CurrentTableList
->NumberOfPages
= EFI_SIZE_TO_PAGES (CurrentTableSize
);
615 // Allocation memory type depends on the type of the table
617 if (CurrentTableSignature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
||
618 CurrentTableSignature
== EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
620 // Allocate memory for the FACS. This structure must be aligned
621 // on a 64 byte boundary and must be ACPI NVS memory.
622 // Using AllocatePages should ensure that it is always aligned.
624 ASSERT ((EFI_PAGE_SIZE
% 64) == 0);
625 Status
= gBS
->AllocatePages (
628 CurrentTableList
->NumberOfPages
,
629 &CurrentTableList
->PageAddress
633 // All other tables are ACPI reclaim memory, no alignment requirements.
635 Status
= gBS
->AllocatePages (
637 EfiACPIReclaimMemory
,
638 CurrentTableList
->NumberOfPages
,
639 &CurrentTableList
->PageAddress
643 // Check return value from memory alloc.
645 if (EFI_ERROR (Status
)) {
646 gBS
->FreePool (CurrentTableList
);
647 return EFI_OUT_OF_RESOURCES
;
650 // Update the table pointer with the allocated memory start
652 CurrentTableList
->Table
= (EFI_ACPI_COMMON_HEADER
*) (UINTN
) CurrentTableList
->PageAddress
;
655 // Initialize the table contents
657 CurrentTableList
->Signature
= EFI_ACPI_TABLE_LIST_SIGNATURE
;
658 CopyMem (CurrentTableList
->Table
, Table
, CurrentTableSize
);
659 CurrentTableList
->Handle
= AcpiTableInstance
->CurrentHandle
++;
660 *Handle
= CurrentTableList
->Handle
;
661 CurrentTableList
->Version
= Version
;
664 // Update internal pointers if this is a required table. If it is a required
665 // table and a table of that type already exists, return an error.
667 // Calculate the checksum if the table is not FACS.
669 switch (CurrentTableSignature
) {
671 case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
673 // We don't add the FADT in the standard way because some
674 // OS expect the FADT to be early in the table list.
675 // So we always add it as the first element in the list.
680 // Check that the table has not been previously added.
682 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0 && AcpiTableInstance
->Fadt1
!= NULL
) ||
683 ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 && AcpiTableInstance
->Fadt3
!= NULL
) ||
684 ((Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0 && AcpiTableInstance
->Fadt3
!= NULL
)
686 gBS
->FreePages (CurrentTableList
->PageAddress
, CurrentTableList
->NumberOfPages
);
687 gBS
->FreePool (CurrentTableList
);
691 // Add the table to the appropriate table version
693 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
695 // Save a pointer to the table
697 AcpiTableInstance
->Fadt1
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*) CurrentTableList
->Table
;
700 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
702 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs1
;
703 AcpiTableInstance
->Fadt1
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt1
;
706 // RSDP OEM information is updated to match the FADT OEM information
709 &AcpiTableInstance
->Rsdp1
->OemId
,
710 &AcpiTableInstance
->Fadt1
->Header
.OemId
,
715 // RSDT OEM information is updated to match the FADT OEM information.
718 &AcpiTableInstance
->Rsdt1
->OemId
,
719 &AcpiTableInstance
->Fadt1
->Header
.OemId
,
724 &AcpiTableInstance
->Rsdt1
->OemTableId
,
725 &AcpiTableInstance
->Fadt1
->Header
.OemTableId
,
728 AcpiTableInstance
->Rsdt1
->OemRevision
= AcpiTableInstance
->Fadt1
->Header
.OemRevision
;
731 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
732 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
734 // Save a pointer to the table
736 AcpiTableInstance
->Fadt3
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) CurrentTableList
->Table
;
739 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
741 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs3
;
742 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Facs3
;
744 &AcpiTableInstance
->Fadt3
->XFirmwareCtrl
,
748 AcpiTableInstance
->Fadt3
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt3
;
749 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Dsdt3
;
751 &AcpiTableInstance
->Fadt3
->XDsdt
,
757 // RSDP OEM information is updated to match the FADT OEM information
760 &AcpiTableInstance
->Rsdp3
->OemId
,
761 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
766 // RSDT OEM information is updated to match FADT OEM information.
769 &AcpiTableInstance
->Rsdt3
->OemId
,
770 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
774 &AcpiTableInstance
->Rsdt3
->OemTableId
,
775 &AcpiTableInstance
->Fadt3
->Header
.OemTableId
,
778 AcpiTableInstance
->Rsdt3
->OemRevision
= AcpiTableInstance
->Fadt3
->Header
.OemRevision
;
781 // XSDT OEM information is updated to match FADT OEM information.
784 &AcpiTableInstance
->Xsdt
->OemId
,
785 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
789 &AcpiTableInstance
->Xsdt
->OemTableId
,
790 &AcpiTableInstance
->Fadt3
->Header
.OemTableId
,
793 AcpiTableInstance
->Xsdt
->OemRevision
= AcpiTableInstance
->Fadt3
->Header
.OemRevision
;
796 // Checksum the table
799 AcpiPlatformChecksum (
800 CurrentTableList
->Table
,
801 CurrentTableList
->Table
->Length
,
802 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
808 case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
810 // Check that the table has not been previously added.
812 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0 && AcpiTableInstance
->Facs1
!= NULL
) ||
813 ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 && AcpiTableInstance
->Facs3
!= NULL
) ||
814 ((Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0 && AcpiTableInstance
->Facs3
!= NULL
)
816 gBS
->FreePages (CurrentTableList
->PageAddress
, CurrentTableList
->NumberOfPages
);
817 gBS
->FreePool (CurrentTableList
);
821 // FACS is referenced by FADT and is not part of RSDT
826 // Add the table to the appropriate table version
828 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
830 // Save a pointer to the table
832 AcpiTableInstance
->Facs1
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*) CurrentTableList
->Table
;
835 // If FADT already exists, update table pointers.
837 if (AcpiTableInstance
->Fadt1
!= NULL
) {
838 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs1
;
841 // Checksum FADT table
843 AcpiPlatformChecksum (
844 AcpiTableInstance
->Fadt1
,
845 AcpiTableInstance
->Fadt1
->Header
.Length
,
846 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
852 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
853 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
855 // Save a pointer to the table
857 AcpiTableInstance
->Facs3
= (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*) CurrentTableList
->Table
;
860 // If FADT already exists, update table pointers.
862 if (AcpiTableInstance
->Fadt3
!= NULL
) {
863 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs3
;
864 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Facs3
;
866 &AcpiTableInstance
->Fadt3
->XFirmwareCtrl
,
872 // Checksum FADT table
874 AcpiPlatformChecksum (
875 AcpiTableInstance
->Fadt3
,
876 AcpiTableInstance
->Fadt3
->Header
.Length
,
877 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
885 case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
887 // Check that the table has not been previously added.
889 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0 && AcpiTableInstance
->Dsdt1
!= NULL
) ||
890 ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 && AcpiTableInstance
->Dsdt3
!= NULL
) ||
891 ((Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0 && AcpiTableInstance
->Dsdt3
!= NULL
)
893 gBS
->FreePages (CurrentTableList
->PageAddress
, CurrentTableList
->NumberOfPages
);
894 gBS
->FreePool (CurrentTableList
);
898 // DSDT is referenced by FADT and is not part of RSDT
903 // Add the table to the appropriate table version
905 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
907 // Save a pointer to the table
909 AcpiTableInstance
->Dsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTableList
->Table
;
912 // If FADT already exists, update table pointers.
914 if (AcpiTableInstance
->Fadt1
!= NULL
) {
915 AcpiTableInstance
->Fadt1
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt1
;
918 // Checksum FADT table
920 AcpiPlatformChecksum (
921 AcpiTableInstance
->Fadt1
,
922 AcpiTableInstance
->Fadt1
->Header
.Length
,
923 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
929 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
930 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
932 // Save a pointer to the table
934 AcpiTableInstance
->Dsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTableList
->Table
;
937 // If FADT already exists, update table pointers.
939 if (AcpiTableInstance
->Fadt3
!= NULL
) {
940 AcpiTableInstance
->Fadt3
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt3
;
941 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Dsdt3
;
943 &AcpiTableInstance
->Fadt3
->XDsdt
,
949 // Checksum FADT table
951 AcpiPlatformChecksum (
952 AcpiTableInstance
->Fadt3
,
953 AcpiTableInstance
->Fadt3
->Header
.Length
,
954 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
960 // Checksum the table
963 AcpiPlatformChecksum (
964 CurrentTableList
->Table
,
965 CurrentTableList
->Table
->Length
,
966 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
974 // Checksum the table
977 AcpiPlatformChecksum (
978 CurrentTableList
->Table
,
979 CurrentTableList
->Table
->Length
,
980 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
987 // Add the table to the current list of tables
989 InsertTailList (&AcpiTableInstance
->TableList
, &CurrentTableList
->Link
);
992 // Add the table to RSDT and/or XSDT table entry lists.
995 // Add to ACPI 1.0b table tree
997 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1000 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1002 if (AcpiTableInstance
->NumberOfTableEntries1
>= mEfiAcpiMaxNumTables
) {
1003 Status
= ReallocateAcpiTableBuffer (AcpiTableInstance
);
1004 ASSERT_EFI_ERROR (Status
);
1006 CurrentRsdtEntry
= (UINT32
*)
1008 (UINT8
*) AcpiTableInstance
->Rsdt1
+
1009 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
1010 AcpiTableInstance
->NumberOfTableEntries1
*
1015 // Add entry to the RSDT unless its the FACS or DSDT
1017 *CurrentRsdtEntry
= (UINT32
) (UINTN
) CurrentTableList
->Table
;
1020 // Update RSDT length
1022 AcpiTableInstance
->Rsdt1
->Length
= AcpiTableInstance
->Rsdt1
->Length
+ sizeof (UINT32
);
1024 AcpiTableInstance
->NumberOfTableEntries1
++;
1028 // Add to ACPI 2.0/3.0 table tree
1030 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1031 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1034 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1036 if (AcpiTableInstance
->NumberOfTableEntries3
>= mEfiAcpiMaxNumTables
) {
1037 Status
= ReallocateAcpiTableBuffer (AcpiTableInstance
);
1038 ASSERT_EFI_ERROR (Status
);
1041 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1042 // If it becomes necessary to maintain separate table lists, changes will be required.
1044 CurrentRsdtEntry
= (UINT32
*)
1046 (UINT8
*) AcpiTableInstance
->Rsdt3
+
1047 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
1048 AcpiTableInstance
->NumberOfTableEntries3
*
1053 // This pointer must not be directly dereferenced as the XSDT entries may not
1054 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1056 CurrentXsdtEntry
= (VOID
*)
1058 (UINT8
*) AcpiTableInstance
->Xsdt
+
1059 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
1060 AcpiTableInstance
->NumberOfTableEntries3
*
1065 // Add entry to the RSDT
1067 *CurrentRsdtEntry
= (UINT32
) (UINTN
) CurrentTableList
->Table
;
1070 // Update RSDT length
1072 AcpiTableInstance
->Rsdt3
->Length
= AcpiTableInstance
->Rsdt3
->Length
+ sizeof (UINT32
);
1075 // Add entry to XSDT, XSDT expects 64 bit pointers, but
1076 // the table pointers in XSDT are not aligned on 8 byte boundary.
1078 Buffer64
= (UINT64
) (UINTN
) CurrentTableList
->Table
;
1088 AcpiTableInstance
->Xsdt
->Length
= AcpiTableInstance
->Xsdt
->Length
+ sizeof (UINT64
);
1090 AcpiTableInstance
->NumberOfTableEntries3
++;
1094 ChecksumCommonTables (AcpiTableInstance
);
1100 This function finds the table specified by the handle and returns a pointer to it.
1101 If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are
1104 @param Handle Table to find.
1105 @param TableList Table list to search
1106 @param Table Pointer to table found.
1108 @return EFI_SUCCESS The function completed successfully.
1109 @return EFI_NOT_FOUND No table found matching the handle specified.
1115 IN LIST_ENTRY
*TableList
,
1116 OUT EFI_ACPI_TABLE_LIST
**Table
1119 LIST_ENTRY
*CurrentLink
;
1120 EFI_ACPI_TABLE_LIST
*CurrentTable
;
1123 // Check for invalid input parameters
1130 CurrentLink
= TableList
->ForwardLink
;
1132 while (CurrentLink
!= TableList
) {
1133 CurrentTable
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
1134 if (CurrentTable
->Handle
== Handle
) {
1136 // Found handle, so return this table.
1138 *Table
= CurrentTable
;
1142 CurrentLink
= CurrentLink
->ForwardLink
;
1147 return EFI_NOT_FOUND
;
1152 This function removes a basic table from the RSDT and/or XSDT.
1153 For Acpi 1.0 tables, pass in the Rsdt.
1154 For Acpi 2.0 tables, pass in both Rsdt and Xsdt.
1156 @param Table Pointer to table found.
1157 @param NumberOfTableEntries Current number of table entries in the RSDT/XSDT
1158 @param Rsdt Pointer to the RSDT to remove from
1159 @param Xsdt Pointer to the Xsdt to remove from
1161 @return EFI_SUCCESS The function completed successfully.
1162 @return EFI_INVALID_PARAMETER The table was not found in both Rsdt and Xsdt.
1166 RemoveTableFromRsdt (
1167 IN OUT EFI_ACPI_TABLE_LIST
* Table
,
1168 IN OUT UINTN
*NumberOfTableEntries
,
1169 IN OUT EFI_ACPI_DESCRIPTION_HEADER
* Rsdt
,
1170 IN OUT EFI_ACPI_DESCRIPTION_HEADER
* Xsdt OPTIONAL
1173 UINT32
*CurrentRsdtEntry
;
1174 VOID
*CurrentXsdtEntry
;
1175 UINT64 CurrentTablePointer64
;
1179 // Check for invalid input parameters
1182 ASSERT (NumberOfTableEntries
);
1186 // Find the table entry in the RSDT and XSDT
1188 for (Index
= 0; Index
< *NumberOfTableEntries
; Index
++) {
1190 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1191 // If it becomes necessary to maintain separate table lists, changes will be required.
1193 CurrentRsdtEntry
= (UINT32
*) ((UINT8
*) Rsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + Index
* sizeof (UINT32
));
1196 // This pointer must not be directly dereferenced as the XSDT entries may not
1197 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1199 CurrentXsdtEntry
= (VOID
*) ((UINT8
*) Xsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + Index
* sizeof (UINT64
));
1202 // Read the entry value out of the XSDT
1204 CopyMem (&CurrentTablePointer64
, CurrentXsdtEntry
, sizeof (UINT64
));
1207 // Initialize to NULL
1209 CurrentXsdtEntry
= 0;
1210 CurrentTablePointer64
= 0;
1213 // Check if we have found the corresponding entry in both RSDT and XSDT
1215 if (*CurrentRsdtEntry
== (UINT32
) (UINTN
) Table
->Table
&&
1216 ((Xsdt
== NULL
) || CurrentTablePointer64
== (UINT64
) (UINTN
) Table
->Table
)
1219 // Found entry, so copy all following entries and shrink table
1220 // We actually copy all + 1 to copy the initialized value of memory over
1223 CopyMem (CurrentRsdtEntry
, CurrentRsdtEntry
+ 1, (*NumberOfTableEntries
- Index
) * sizeof (UINT32
));
1224 Rsdt
->Length
= Rsdt
->Length
- sizeof (UINT32
);
1226 CopyMem (CurrentXsdtEntry
, ((UINT64
*) CurrentXsdtEntry
) + 1, (*NumberOfTableEntries
- Index
) * sizeof (UINT64
));
1227 Xsdt
->Length
= Xsdt
->Length
- sizeof (UINT64
);
1230 } else if (Index
+ 1 == *NumberOfTableEntries
) {
1232 // At the last entry, and table not found
1234 return EFI_INVALID_PARAMETER
;
1238 // Checksum the tables
1240 AcpiPlatformChecksum (
1243 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1248 AcpiPlatformChecksum (
1251 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1256 // Decrement the number of tables
1258 (*NumberOfTableEntries
)--;
1265 This function removes a table and frees any associated memory.
1267 @param AcpiTableInstance Instance of the protocol.
1268 @param Version Version(s) to delete.
1269 @param Table Pointer to table found.
1271 @return EFI_SUCCESS The function completed successfully.
1276 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
1277 IN EFI_ACPI_TABLE_VERSION Version
,
1278 IN OUT EFI_ACPI_TABLE_LIST
*Table
1281 UINT32 CurrentTableSignature
;
1282 BOOLEAN RemoveFromRsdt
;
1285 // Check for invalid input parameters
1287 ASSERT (AcpiTableInstance
);
1293 RemoveFromRsdt
= TRUE
;
1295 // Check for Table->Table
1297 ASSERT (Table
->Table
!= NULL
);
1298 CurrentTableSignature
= ((EFI_ACPI_COMMON_HEADER
*) Table
->Table
)->Signature
;
1301 // Basic tasks to accomplish delete are:
1302 // Determine removal requirements (in RSDT/XSDT or not)
1303 // Remove entry from RSDT/XSDT
1304 // Remove any table references to the table
1305 // If no one is using the table
1306 // Free the table (removing pointers from private data and tables)
1308 // Free list structure
1311 // Determine if this table is in the RSDT or XSDT
1313 if ((CurrentTableSignature
== EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) ||
1314 (CurrentTableSignature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) ||
1315 (CurrentTableSignature
== EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)
1317 RemoveFromRsdt
= FALSE
;
1320 // We don't remove the FADT in the standard way because some
1321 // OS expect the FADT to be early in the table list.
1322 // So we always put it as the first element in the list.
1324 if (CurrentTableSignature
== EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
) {
1325 RemoveFromRsdt
= FALSE
;
1329 // Remove the table from RSDT and XSDT
1331 if (Table
->Table
!= NULL
) {
1333 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
1335 if (Version
& EFI_ACPI_TABLE_VERSION_NONE
& Table
->Version
) {
1337 // Remove this version from the table
1339 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_NONE
;
1342 if (Version
& EFI_ACPI_TABLE_VERSION_1_0B
& Table
->Version
) {
1344 // Remove this version from the table
1346 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_1_0B
;
1349 // Remove from Rsdt. We don't care about the return value because it is
1350 // acceptable for the table to not exist in Rsdt.
1351 // We didn't add some tables so we don't remove them.
1353 if (RemoveFromRsdt
) {
1354 RemoveTableFromRsdt (
1356 &AcpiTableInstance
->NumberOfTableEntries1
,
1357 AcpiTableInstance
->Rsdt1
,
1363 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
& Table
->Version
) ||
1364 (Version
& EFI_ACPI_TABLE_VERSION_3_0
& Table
->Version
)) {
1366 // Remove this version from the table
1368 if (Version
& EFI_ACPI_TABLE_VERSION_2_0
& Table
->Version
) {
1369 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_2_0
;
1371 if (Version
& EFI_ACPI_TABLE_VERSION_3_0
& Table
->Version
) {
1372 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_3_0
;
1376 // Remove from Rsdt and Xsdt. We don't care about the return value
1377 // because it is acceptable for the table to not exist in Rsdt/Xsdt.
1378 // We didn't add some tables so we don't remove them.
1380 if (RemoveFromRsdt
) {
1381 RemoveTableFromRsdt (
1383 &AcpiTableInstance
->NumberOfTableEntries3
,
1384 AcpiTableInstance
->Rsdt3
,
1385 AcpiTableInstance
->Xsdt
1390 // Free the table, clean up any dependent tables and our private data pointers.
1392 switch (Table
->Table
->Signature
) {
1394 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
1395 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1396 AcpiTableInstance
->Fadt1
= NULL
;
1399 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1400 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1401 AcpiTableInstance
->Fadt3
= NULL
;
1405 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
1406 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1407 AcpiTableInstance
->Facs1
= NULL
;
1410 // Update FADT table pointers
1412 if (AcpiTableInstance
->Fadt1
!= NULL
) {
1413 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= 0;
1418 AcpiPlatformChecksum (
1419 AcpiTableInstance
->Fadt1
,
1420 AcpiTableInstance
->Fadt1
->Header
.Length
,
1421 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1427 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1428 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1429 AcpiTableInstance
->Facs3
= NULL
;
1432 // Update FADT table pointers
1434 if (AcpiTableInstance
->Fadt3
!= NULL
) {
1435 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
1436 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
1441 AcpiPlatformChecksum (
1442 AcpiTableInstance
->Fadt3
,
1443 AcpiTableInstance
->Fadt3
->Header
.Length
,
1444 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1451 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
1452 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1453 AcpiTableInstance
->Dsdt1
= NULL
;
1456 // Update FADT table pointers
1458 if (AcpiTableInstance
->Fadt1
!= NULL
) {
1459 AcpiTableInstance
->Fadt1
->Dsdt
= 0;
1464 AcpiPlatformChecksum (
1465 AcpiTableInstance
->Fadt1
,
1466 AcpiTableInstance
->Fadt1
->Header
.Length
,
1467 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1474 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1475 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1476 AcpiTableInstance
->Dsdt3
= NULL
;
1479 // Update FADT table pointers
1481 if (AcpiTableInstance
->Fadt3
!= NULL
) {
1482 AcpiTableInstance
->Fadt3
->Dsdt
= 0;
1483 ZeroMem (&AcpiTableInstance
->Fadt3
->XDsdt
, sizeof (UINT64
));
1488 AcpiPlatformChecksum (
1489 AcpiTableInstance
->Fadt3
,
1490 AcpiTableInstance
->Fadt3
->Header
.Length
,
1491 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1506 // If no version is using this table anymore, remove and free list entry.
1508 if (Table
->Version
== 0) {
1512 gBS
->FreePages (Table
->PageAddress
, Table
->NumberOfPages
);
1513 RemoveEntryList (&(Table
->Link
));
1514 gBS
->FreePool (Table
);
1524 This function finds and removes the table specified by the handle.
1526 @param AcpiTableInstance Instance of the protocol.
1527 @param Version Bitmask of which versions to remove.
1528 @param Handle Table to remove.
1530 @return EFI_SUCCESS The function completed successfully.
1531 @return EFI_ABORTED An error occurred.
1532 @return EFI_NOT_FOUND Handle not found in table list.
1536 RemoveTableFromList (
1537 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
1538 IN EFI_ACPI_TABLE_VERSION Version
,
1542 EFI_ACPI_TABLE_LIST
*Table
;
1545 Table
= (EFI_ACPI_TABLE_LIST
*) NULL
;
1548 // Check for invalid input parameters
1550 ASSERT (AcpiTableInstance
);
1555 Status
= FindTableByHandle (
1557 &AcpiTableInstance
->TableList
,
1560 if (EFI_ERROR (Status
)) {
1561 return EFI_NOT_FOUND
;
1566 Status
= DeleteTable (AcpiTableInstance
, Version
, Table
);
1567 if (EFI_ERROR (Status
)) {
1571 // Completed successfully
1578 This function calculates and updates an UINT8 checksum.
1580 @param Buffer Pointer to buffer to checksum
1581 @param Size Number of bytes to checksum
1582 @param ChecksumOffset Offset to place the checksum result in
1584 @return EFI_SUCCESS The function completed successfully.
1588 AcpiPlatformChecksum (
1591 IN UINTN ChecksumOffset
1599 // Initialize pointer
1604 // set checksum to 0 first
1606 Ptr
[ChecksumOffset
] = 0;
1609 // add all content of buffer
1611 while ((Size
--) != 0) {
1612 Sum
= (UINT8
) (Sum
+ (*Ptr
++));
1618 Ptr
[ChecksumOffset
] = (UINT8
) (0xff - Sum
+ 1);
1625 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
1627 @param AcpiTableInstance Protocol instance private data.
1629 @return EFI_SUCCESS The function completed successfully.
1633 ChecksumCommonTables (
1634 IN OUT EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1638 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure
1640 AcpiPlatformChecksum (
1641 AcpiTableInstance
->Rsdp1
,
1642 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1643 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1648 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure
1650 AcpiPlatformChecksum (
1651 AcpiTableInstance
->Rsdp3
,
1652 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1653 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1658 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
1660 AcpiPlatformChecksum (
1661 AcpiTableInstance
->Rsdp3
,
1662 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1663 OFFSET_OF (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1670 AcpiPlatformChecksum (
1671 AcpiTableInstance
->Rsdt1
,
1672 AcpiTableInstance
->Rsdt1
->Length
,
1673 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1677 AcpiPlatformChecksum (
1678 AcpiTableInstance
->Rsdt3
,
1679 AcpiTableInstance
->Rsdt3
->Length
,
1680 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1687 AcpiPlatformChecksum (
1688 AcpiTableInstance
->Xsdt
,
1689 AcpiTableInstance
->Xsdt
->Length
,
1690 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1699 Constructor for the ACPI table protocol. Initializes instance
1702 @param AcpiTableInstance Instance to construct
1704 @return EFI_SUCCESS Instance initialized.
1705 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
1709 AcpiTableAcpiTableConstructor (
1710 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1717 EFI_PHYSICAL_ADDRESS PageAddress
;
1720 // Check for invalid input parameters
1722 ASSERT (AcpiTableInstance
);
1724 InitializeListHead (&AcpiTableInstance
->TableList
);
1725 AcpiTableInstance
->CurrentHandle
= 1;
1727 AcpiTableInstance
->AcpiTableProtocol
.InstallAcpiTable
= InstallAcpiTable
;
1728 AcpiTableInstance
->AcpiTableProtocol
.UninstallAcpiTable
= UninstallAcpiTable
;
1730 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol
)) {
1731 SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance
);
1735 // Create RSDP, RSDT, XSDT structures
1736 // Allocate all buffers
1738 TotalSize
= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
1739 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
1740 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
1741 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
1742 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
1743 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
1744 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
1745 mEfiAcpiMaxNumTables
* sizeof (UINT64
);
1748 // Allocate memory in the lower 32 bit of address range for
1749 // compatibility with ACPI 1.0 OS.
1751 // This is done because ACPI 1.0 pointers are 32 bit values.
1752 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
1753 // There is no architectural reason these should be below 4GB, it is purely
1754 // for convenience of implementation that we force memory below 4GB.
1756 PageAddress
= 0xFFFFFFFF;
1757 Status
= gBS
->AllocatePages (
1759 EfiACPIReclaimMemory
,
1760 EFI_SIZE_TO_PAGES (TotalSize
),
1764 if (EFI_ERROR (Status
)) {
1765 return EFI_OUT_OF_RESOURCES
;
1768 Pointer
= (UINT8
*) (UINTN
) PageAddress
;
1769 ZeroMem (Pointer
, TotalSize
);
1771 AcpiTableInstance
->Rsdp1
= (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*) Pointer
;
1772 Pointer
+= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1773 AcpiTableInstance
->Rsdp3
= (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*) Pointer
;
1774 Pointer
+= sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1776 AcpiTableInstance
->Rsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
1777 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + EFI_ACPI_MAX_NUM_TABLES
* sizeof (UINT32
));
1778 AcpiTableInstance
->Rsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
1779 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + EFI_ACPI_MAX_NUM_TABLES
* sizeof (UINT32
));
1781 AcpiTableInstance
->Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
1786 CurrentData
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
;
1787 CopyMem (&AcpiTableInstance
->Rsdp1
->Signature
, &CurrentData
, sizeof (UINT64
));
1788 CopyMem (AcpiTableInstance
->Rsdp1
->OemId
, EFI_ACPI_OEM_ID
, 6);
1789 AcpiTableInstance
->Rsdp1
->Reserved
= EFI_ACPI_RESERVED_BYTE
;
1790 AcpiTableInstance
->Rsdp1
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt1
;
1792 CurrentData
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
;
1793 CopyMem (&AcpiTableInstance
->Rsdp3
->Signature
, &CurrentData
, sizeof (UINT64
));
1794 CopyMem (AcpiTableInstance
->Rsdp3
->OemId
, EFI_ACPI_OEM_ID
, 6);
1795 AcpiTableInstance
->Rsdp3
->Revision
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION
;
1796 AcpiTableInstance
->Rsdp3
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt3
;
1797 AcpiTableInstance
->Rsdp3
->Length
= sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1798 CurrentData
= (UINT64
) (UINTN
) AcpiTableInstance
->Xsdt
;
1799 CopyMem (&AcpiTableInstance
->Rsdp3
->XsdtAddress
, &CurrentData
, sizeof (UINT64
));
1800 SetMem (AcpiTableInstance
->Rsdp3
->Reserved
, 3, EFI_ACPI_RESERVED_BYTE
);
1805 // Note that we "reserve" one entry for the FADT so it can always be
1806 // at the beginning of the list of tables. Some OS don't seem
1807 // to find it correctly if it is too far down the list.
1809 AcpiTableInstance
->Rsdt1
->Signature
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
1810 AcpiTableInstance
->Rsdt1
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
1811 AcpiTableInstance
->Rsdt1
->Revision
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
;
1812 CopyMem (AcpiTableInstance
->Rsdt1
->OemId
, EFI_ACPI_OEM_ID
, 6);
1813 CurrentData
= EFI_ACPI_OEM_TABLE_ID
;
1814 CopyMem (&AcpiTableInstance
->Rsdt1
->OemTableId
, &CurrentData
, sizeof (UINT64
));
1815 AcpiTableInstance
->Rsdt1
->OemRevision
= EFI_ACPI_OEM_REVISION
;
1816 AcpiTableInstance
->Rsdt1
->CreatorId
= EFI_ACPI_CREATOR_ID
;
1817 AcpiTableInstance
->Rsdt1
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
1819 // We always reserve first one for FADT
1821 AcpiTableInstance
->NumberOfTableEntries1
= 1;
1822 AcpiTableInstance
->Rsdt1
->Length
= AcpiTableInstance
->Rsdt1
->Length
+ sizeof(UINT32
);
1824 AcpiTableInstance
->Rsdt3
->Signature
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
1825 AcpiTableInstance
->Rsdt3
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
1826 AcpiTableInstance
->Rsdt3
->Revision
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
;
1827 CopyMem (AcpiTableInstance
->Rsdt3
->OemId
, EFI_ACPI_OEM_ID
, 6);
1828 CurrentData
= EFI_ACPI_OEM_TABLE_ID
;
1829 CopyMem (&AcpiTableInstance
->Rsdt3
->OemTableId
, &CurrentData
, sizeof (UINT64
));
1830 AcpiTableInstance
->Rsdt3
->OemRevision
= EFI_ACPI_OEM_REVISION
;
1831 AcpiTableInstance
->Rsdt3
->CreatorId
= EFI_ACPI_CREATOR_ID
;
1832 AcpiTableInstance
->Rsdt3
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
1834 // We always reserve first one for FADT
1836 AcpiTableInstance
->NumberOfTableEntries3
= 1;
1837 AcpiTableInstance
->Rsdt3
->Length
= AcpiTableInstance
->Rsdt3
->Length
+ sizeof(UINT32
);
1842 AcpiTableInstance
->Xsdt
->Signature
= EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
1843 AcpiTableInstance
->Xsdt
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
1844 AcpiTableInstance
->Xsdt
->Revision
= EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION
;
1845 CopyMem (AcpiTableInstance
->Xsdt
->OemId
, EFI_ACPI_OEM_ID
, 6);
1846 CurrentData
= EFI_ACPI_OEM_TABLE_ID
;
1847 CopyMem (&AcpiTableInstance
->Xsdt
->OemTableId
, &CurrentData
, sizeof (UINT64
));
1848 AcpiTableInstance
->Xsdt
->OemRevision
= EFI_ACPI_OEM_REVISION
;
1849 AcpiTableInstance
->Xsdt
->CreatorId
= EFI_ACPI_CREATOR_ID
;
1850 AcpiTableInstance
->Xsdt
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
1852 // We always reserve first one for FADT
1854 AcpiTableInstance
->Xsdt
->Length
= AcpiTableInstance
->Xsdt
->Length
+ sizeof(UINT64
);
1856 ChecksumCommonTables (AcpiTableInstance
);
1859 // Completed successfully