2 ACPI Table Protocol Implementation
4 Copyright (c) 2006 - 2014, 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 publishes the specified versions of the ACPI tables by
103 installing EFI configuration table entries for them. Any combination of
104 table versions can be published.
106 @param AcpiTableInstance Instance of the protocol.
107 @param Version Version(s) to publish.
109 @return EFI_SUCCESS The function completed successfully.
110 @return EFI_ABORTED The function could not complete successfully.
116 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
117 IN EFI_ACPI_TABLE_VERSION Version
121 UINT32
*CurrentRsdtEntry
;
122 VOID
*CurrentXsdtEntry
;
126 // Reorder tables as some operating systems don't seem to find the
127 // FADT correctly if it is not in the first few entries
131 // Add FADT as the first entry
133 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
134 CurrentRsdtEntry
= (UINT32
*) ((UINT8
*) AcpiTableInstance
->Rsdt1
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
135 *CurrentRsdtEntry
= (UINT32
) (UINTN
) AcpiTableInstance
->Fadt1
;
137 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
138 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
139 CurrentRsdtEntry
= (UINT32
*) ((UINT8
*) AcpiTableInstance
->Rsdt3
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
140 *CurrentRsdtEntry
= (UINT32
) (UINTN
) AcpiTableInstance
->Fadt3
;
141 CurrentXsdtEntry
= (VOID
*) ((UINT8
*) AcpiTableInstance
->Xsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
));
143 // Add entry to XSDT, XSDT expects 64 bit pointers, but
144 // the table pointers in XSDT are not aligned on 8 byte boundary.
146 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Fadt3
;
155 // Do checksum again because Dsdt/Xsdt is updated.
157 ChecksumCommonTables (AcpiTableInstance
);
160 // Add the RSD_PTR to the system table and store that we have installed the
163 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) &&
164 !AcpiTableInstance
->TablesInstalled1
) {
165 Status
= gBS
->InstallConfigurationTable (&gEfiAcpi10TableGuid
, AcpiTableInstance
->Rsdp1
);
166 if (EFI_ERROR (Status
)) {
170 AcpiTableInstance
->TablesInstalled1
= TRUE
;
173 if (((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
174 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) &&
175 !AcpiTableInstance
->TablesInstalled3
) {
176 Status
= gBS
->InstallConfigurationTable (&gEfiAcpiTableGuid
, AcpiTableInstance
->Rsdp3
);
177 if (EFI_ERROR (Status
)) {
181 AcpiTableInstance
->TablesInstalled3
= TRUE
;
189 Installs an ACPI table into the RSDT/XSDT.
190 Note that the ACPI table should be checksumed before installing it.
191 Otherwise it will assert.
193 @param This Protocol instance pointer.
194 @param AcpiTableBuffer A pointer to a buffer containing the ACPI table to be installed.
195 @param AcpiTableBufferSize Specifies the size, in bytes, of the AcpiTableBuffer buffer.
196 @param TableKey Reurns a key to refer to the ACPI table.
198 @return EFI_SUCCESS The table was successfully inserted.
199 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize
200 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer
202 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
203 @retval EFI_ACCESS_DENIED The table signature matches a table already
204 present in the system and platform policy
205 does not allow duplicate tables of this type.
211 IN EFI_ACPI_TABLE_PROTOCOL
*This
,
212 IN VOID
*AcpiTableBuffer
,
213 IN UINTN AcpiTableBufferSize
,
217 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
219 VOID
*AcpiTableBufferConst
;
222 // Check for invalid input parameters
224 if ((AcpiTableBuffer
== NULL
) || (TableKey
== NULL
)
225 || (((EFI_ACPI_DESCRIPTION_HEADER
*) AcpiTableBuffer
)->Length
!= AcpiTableBufferSize
)) {
226 return EFI_INVALID_PARAMETER
;
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
,
243 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
,
246 if (!EFI_ERROR (Status
)) {
247 Status
= PublishTables (
249 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
252 FreePool (AcpiTableBufferConst
);
255 // Add a new table successfully, notify registed callback
257 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol
)) {
258 if (!EFI_ERROR (Status
)) {
261 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
,
272 Removes an ACPI table from the RSDT/XSDT.
274 @param This Protocol instance pointer.
275 @param TableKey Specifies the table to uninstall. The key was returned from InstallAcpiTable().
277 @return EFI_SUCCESS The table was successfully uninstalled.
278 @return EFI_NOT_FOUND TableKey does not refer to a valid key for a table entry.
284 IN EFI_ACPI_TABLE_PROTOCOL
*This
,
288 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
;
292 // Get the instance of the ACPI table protocol
294 AcpiTableInstance
= EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This
);
297 // Uninstall the ACPI table
299 Status
= RemoveTableFromList (
301 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
,
304 if (!EFI_ERROR (Status
)) {
305 Status
= PublishTables (
307 EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
311 if (EFI_ERROR (Status
)) {
312 return EFI_NOT_FOUND
;
319 If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.
321 @param AcpiTableInstance ACPI table protocol instance data structure.
323 @return EFI_SUCCESS reallocate the table beffer successfully.
324 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
328 ReallocateAcpiTableBuffer (
329 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
332 UINTN NewMaxTableNumber
;
335 EFI_PHYSICAL_ADDRESS PageAddress
;
336 EFI_ACPI_TABLE_INSTANCE TempPrivateData
;
340 CopyMem (&TempPrivateData
, AcpiTableInstance
, sizeof (EFI_ACPI_TABLE_INSTANCE
));
342 // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES
344 NewMaxTableNumber
= mEfiAcpiMaxNumTables
+ EFI_ACPI_MAX_NUM_TABLES
;
346 // Create RSDT, XSDT structures and allocate buffers.
348 TotalSize
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
349 NewMaxTableNumber
* sizeof (UINT32
) +
350 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
351 NewMaxTableNumber
* sizeof (UINT32
) +
352 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
353 NewMaxTableNumber
* sizeof (UINT64
);
356 // Allocate memory in the lower 32 bit of address range for
357 // compatibility with ACPI 1.0 OS.
359 // This is done because ACPI 1.0 pointers are 32 bit values.
360 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
361 // There is no architectural reason these should be below 4GB, it is purely
362 // for convenience of implementation that we force memory below 4GB.
364 PageAddress
= 0xFFFFFFFF;
365 Status
= gBS
->AllocatePages (
367 EfiACPIReclaimMemory
,
368 EFI_SIZE_TO_PAGES (TotalSize
),
372 if (EFI_ERROR (Status
)) {
373 return EFI_OUT_OF_RESOURCES
;
376 Pointer
= (UINT8
*) (UINTN
) PageAddress
;
377 ZeroMem (Pointer
, TotalSize
);
379 AcpiTableInstance
->Rsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
380 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + NewMaxTableNumber
* sizeof (UINT32
));
381 AcpiTableInstance
->Rsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
382 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + NewMaxTableNumber
* sizeof (UINT32
));
383 AcpiTableInstance
->Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
386 // Update RSDP to point to the new Rsdt and Xsdt address.
388 AcpiTableInstance
->Rsdp1
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt1
;
389 AcpiTableInstance
->Rsdp3
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt3
;
390 CurrentData
= (UINT64
) (UINTN
) AcpiTableInstance
->Xsdt
;
391 CopyMem (&AcpiTableInstance
->Rsdp3
->XsdtAddress
, &CurrentData
, sizeof (UINT64
));
394 // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer
396 CopyMem (AcpiTableInstance
->Rsdt1
, TempPrivateData
.Rsdt1
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT32
)));
397 CopyMem (AcpiTableInstance
->Rsdt3
, TempPrivateData
.Rsdt3
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT32
)));
398 CopyMem (AcpiTableInstance
->Xsdt
, TempPrivateData
.Xsdt
, (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + mEfiAcpiMaxNumTables
* sizeof (UINT64
)));
401 // Calculate orignal ACPI table buffer size
403 TotalSize
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
404 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
405 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
406 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
407 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
408 mEfiAcpiMaxNumTables
* sizeof (UINT64
);
409 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)TempPrivateData
.Rsdt1
, EFI_SIZE_TO_PAGES (TotalSize
));
412 // Update the Max ACPI table number
414 mEfiAcpiMaxNumTables
= NewMaxTableNumber
;
418 This function adds an ACPI table to the table list. It will detect FACS and
419 allocate the correct type of memory and properly align the table.
421 @param AcpiTableInstance Instance of the protocol.
422 @param Table Table to add.
423 @param Checksum Does the table require checksumming.
424 @param Version The version of the list to add the table to.
425 @param Handle Pointer for returning the handle.
427 @return EFI_SUCCESS The function completed successfully.
428 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
429 @retval EFI_ACCESS_DENIED The table signature matches a table already
430 present in the system and platform policy
431 does not allow duplicate tables of this type.
436 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
439 IN EFI_ACPI_TABLE_VERSION Version
,
444 EFI_ACPI_TABLE_LIST
*CurrentTableList
;
445 UINT32 CurrentTableSignature
;
446 UINT32 CurrentTableSize
;
447 UINT32
*CurrentRsdtEntry
;
448 VOID
*CurrentXsdtEntry
;
453 // Check for invalid input parameters
455 ASSERT (AcpiTableInstance
);
465 // Create a new list entry
467 CurrentTableList
= AllocatePool (sizeof (EFI_ACPI_TABLE_LIST
));
468 ASSERT (CurrentTableList
);
471 // Determine table type and size
473 CurrentTableSignature
= ((EFI_ACPI_COMMON_HEADER
*) Table
)->Signature
;
474 CurrentTableSize
= ((EFI_ACPI_COMMON_HEADER
*) Table
)->Length
;
477 // Allocate a buffer for the table. All tables are allocated in the lower 32 bits of address space
478 // for backwards compatibility with ACPI 1.0 OS.
480 // This is done because ACPI 1.0 pointers are 32 bit values.
481 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
482 // There is no architectural reason these should be below 4GB, it is purely
483 // for convenience of implementation that we force memory below 4GB.
485 CurrentTableList
->PageAddress
= 0xFFFFFFFF;
486 CurrentTableList
->NumberOfPages
= EFI_SIZE_TO_PAGES (CurrentTableSize
);
489 // Allocation memory type depends on the type of the table
491 if ((CurrentTableSignature
== EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) ||
492 (CurrentTableSignature
== EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE
)) {
494 // Allocate memory for the FACS. This structure must be aligned
495 // on a 64 byte boundary and must be ACPI NVS memory.
496 // Using AllocatePages should ensure that it is always aligned.
497 // Do not change signature for new ACPI version because they are same.
499 // UEFI table also need to be in ACPI NVS memory, because some data field
500 // could be updated by OS present agent. For example, BufferPtrAddress in
501 // SMM communication ACPI table.
503 ASSERT ((EFI_PAGE_SIZE
% 64) == 0);
504 Status
= gBS
->AllocatePages (
507 CurrentTableList
->NumberOfPages
,
508 &CurrentTableList
->PageAddress
512 // All other tables are ACPI reclaim memory, no alignment requirements.
514 Status
= gBS
->AllocatePages (
516 EfiACPIReclaimMemory
,
517 CurrentTableList
->NumberOfPages
,
518 &CurrentTableList
->PageAddress
522 // Check return value from memory alloc.
524 if (EFI_ERROR (Status
)) {
525 gBS
->FreePool (CurrentTableList
);
526 return EFI_OUT_OF_RESOURCES
;
529 // Update the table pointer with the allocated memory start
531 CurrentTableList
->Table
= (EFI_ACPI_COMMON_HEADER
*) (UINTN
) CurrentTableList
->PageAddress
;
534 // Initialize the table contents
536 CurrentTableList
->Signature
= EFI_ACPI_TABLE_LIST_SIGNATURE
;
537 CopyMem (CurrentTableList
->Table
, Table
, CurrentTableSize
);
538 CurrentTableList
->Handle
= AcpiTableInstance
->CurrentHandle
++;
539 *Handle
= CurrentTableList
->Handle
;
540 CurrentTableList
->Version
= Version
;
543 // Update internal pointers if this is a required table. If it is a required
544 // table and a table of that type already exists, return an error.
546 // Calculate the checksum if the table is not FACS.
548 switch (CurrentTableSignature
) {
550 case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
552 // We don't add the FADT in the standard way because some
553 // OS expect the FADT to be early in the table list.
554 // So we always add it as the first element in the list.
559 // Check that the table has not been previously added.
561 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0 && AcpiTableInstance
->Fadt1
!= NULL
) ||
562 ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 && AcpiTableInstance
->Fadt3
!= NULL
) ||
563 ((Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0 && AcpiTableInstance
->Fadt3
!= NULL
)
565 gBS
->FreePages (CurrentTableList
->PageAddress
, CurrentTableList
->NumberOfPages
);
566 gBS
->FreePool (CurrentTableList
);
567 return EFI_ACCESS_DENIED
;
570 // Add the table to the appropriate table version
572 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
574 // Save a pointer to the table
576 AcpiTableInstance
->Fadt1
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*) CurrentTableList
->Table
;
579 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
581 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs1
;
582 AcpiTableInstance
->Fadt1
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt1
;
585 // RSDP OEM information is updated to match the FADT OEM information
588 &AcpiTableInstance
->Rsdp1
->OemId
,
589 &AcpiTableInstance
->Fadt1
->Header
.OemId
,
594 // RSDT OEM information is updated to match the FADT OEM information.
597 &AcpiTableInstance
->Rsdt1
->OemId
,
598 &AcpiTableInstance
->Fadt1
->Header
.OemId
,
603 &AcpiTableInstance
->Rsdt1
->OemTableId
,
604 &AcpiTableInstance
->Fadt1
->Header
.OemTableId
,
607 AcpiTableInstance
->Rsdt1
->OemRevision
= AcpiTableInstance
->Fadt1
->Header
.OemRevision
;
610 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
611 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
613 // Save a pointer to the table
615 AcpiTableInstance
->Fadt3
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) CurrentTableList
->Table
;
618 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
619 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
622 if ((UINT64
)(UINTN
)AcpiTableInstance
->Facs3
< BASE_4GB
) {
623 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs3
;
624 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
626 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Facs3
;
628 &AcpiTableInstance
->Fadt3
->XFirmwareCtrl
,
632 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
634 AcpiTableInstance
->Fadt3
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt3
;
635 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Dsdt3
;
637 &AcpiTableInstance
->Fadt3
->XDsdt
,
643 // RSDP OEM information is updated to match the FADT OEM information
646 &AcpiTableInstance
->Rsdp3
->OemId
,
647 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
652 // RSDT OEM information is updated to match FADT OEM information.
655 &AcpiTableInstance
->Rsdt3
->OemId
,
656 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
660 &AcpiTableInstance
->Rsdt3
->OemTableId
,
661 &AcpiTableInstance
->Fadt3
->Header
.OemTableId
,
664 AcpiTableInstance
->Rsdt3
->OemRevision
= AcpiTableInstance
->Fadt3
->Header
.OemRevision
;
667 // XSDT OEM information is updated to match FADT OEM information.
670 &AcpiTableInstance
->Xsdt
->OemId
,
671 &AcpiTableInstance
->Fadt3
->Header
.OemId
,
675 &AcpiTableInstance
->Xsdt
->OemTableId
,
676 &AcpiTableInstance
->Fadt3
->Header
.OemTableId
,
679 AcpiTableInstance
->Xsdt
->OemRevision
= AcpiTableInstance
->Fadt3
->Header
.OemRevision
;
682 // Checksum the table
685 AcpiPlatformChecksum (
686 CurrentTableList
->Table
,
687 CurrentTableList
->Table
->Length
,
688 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
694 case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
696 // Check that the table has not been previously added.
698 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0 && AcpiTableInstance
->Facs1
!= NULL
) ||
699 ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 && AcpiTableInstance
->Facs3
!= NULL
) ||
700 ((Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0 && AcpiTableInstance
->Facs3
!= NULL
)
702 gBS
->FreePages (CurrentTableList
->PageAddress
, CurrentTableList
->NumberOfPages
);
703 gBS
->FreePool (CurrentTableList
);
704 return EFI_ACCESS_DENIED
;
707 // FACS is referenced by FADT and is not part of RSDT
712 // Add the table to the appropriate table version
714 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
716 // Save a pointer to the table
718 AcpiTableInstance
->Facs1
= (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*) CurrentTableList
->Table
;
721 // If FADT already exists, update table pointers.
723 if (AcpiTableInstance
->Fadt1
!= NULL
) {
724 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs1
;
727 // Checksum FADT table
729 AcpiPlatformChecksum (
730 AcpiTableInstance
->Fadt1
,
731 AcpiTableInstance
->Fadt1
->Header
.Length
,
732 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
738 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
739 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
741 // Save a pointer to the table
743 AcpiTableInstance
->Facs3
= (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE
*) CurrentTableList
->Table
;
746 // If FADT already exists, update table pointers.
748 if (AcpiTableInstance
->Fadt3
!= NULL
) {
750 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
753 if ((UINT64
)(UINTN
)AcpiTableInstance
->Facs3
< BASE_4GB
) {
754 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= (UINT32
) (UINTN
) AcpiTableInstance
->Facs3
;
755 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
757 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Facs3
;
759 &AcpiTableInstance
->Fadt3
->XFirmwareCtrl
,
763 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
767 // Checksum FADT table
769 AcpiPlatformChecksum (
770 AcpiTableInstance
->Fadt3
,
771 AcpiTableInstance
->Fadt3
->Header
.Length
,
772 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
780 case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
782 // Check that the table has not been previously added.
784 if (((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0 && AcpiTableInstance
->Dsdt1
!= NULL
) ||
785 ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 && AcpiTableInstance
->Dsdt3
!= NULL
) ||
786 ((Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0 && AcpiTableInstance
->Dsdt3
!= NULL
)
788 gBS
->FreePages (CurrentTableList
->PageAddress
, CurrentTableList
->NumberOfPages
);
789 gBS
->FreePool (CurrentTableList
);
790 return EFI_ACCESS_DENIED
;
793 // DSDT is referenced by FADT and is not part of RSDT
798 // Add the table to the appropriate table version
800 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
802 // Save a pointer to the table
804 AcpiTableInstance
->Dsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTableList
->Table
;
807 // If FADT already exists, update table pointers.
809 if (AcpiTableInstance
->Fadt1
!= NULL
) {
810 AcpiTableInstance
->Fadt1
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt1
;
813 // Checksum FADT table
815 AcpiPlatformChecksum (
816 AcpiTableInstance
->Fadt1
,
817 AcpiTableInstance
->Fadt1
->Header
.Length
,
818 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
824 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
825 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
827 // Save a pointer to the table
829 AcpiTableInstance
->Dsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTableList
->Table
;
832 // If FADT already exists, update table pointers.
834 if (AcpiTableInstance
->Fadt3
!= NULL
) {
835 AcpiTableInstance
->Fadt3
->Dsdt
= (UINT32
) (UINTN
) AcpiTableInstance
->Dsdt3
;
836 Buffer64
= (UINT64
) (UINTN
) AcpiTableInstance
->Dsdt3
;
838 &AcpiTableInstance
->Fadt3
->XDsdt
,
844 // Checksum FADT table
846 AcpiPlatformChecksum (
847 AcpiTableInstance
->Fadt3
,
848 AcpiTableInstance
->Fadt3
->Header
.Length
,
849 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
855 // Checksum the table
858 AcpiPlatformChecksum (
859 CurrentTableList
->Table
,
860 CurrentTableList
->Table
->Length
,
861 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
869 // Checksum the table
872 AcpiPlatformChecksum (
873 CurrentTableList
->Table
,
874 CurrentTableList
->Table
->Length
,
875 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
882 // Add the table to the current list of tables
884 InsertTailList (&AcpiTableInstance
->TableList
, &CurrentTableList
->Link
);
887 // Add the table to RSDT and/or XSDT table entry lists.
890 // Add to ACPI 1.0b table tree
892 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
895 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
897 if (AcpiTableInstance
->NumberOfTableEntries1
>= mEfiAcpiMaxNumTables
) {
898 Status
= ReallocateAcpiTableBuffer (AcpiTableInstance
);
899 ASSERT_EFI_ERROR (Status
);
901 CurrentRsdtEntry
= (UINT32
*)
903 (UINT8
*) AcpiTableInstance
->Rsdt1
+
904 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
905 AcpiTableInstance
->NumberOfTableEntries1
*
910 // Add entry to the RSDT unless its the FACS or DSDT
912 *CurrentRsdtEntry
= (UINT32
) (UINTN
) CurrentTableList
->Table
;
915 // Update RSDT length
917 AcpiTableInstance
->Rsdt1
->Length
= AcpiTableInstance
->Rsdt1
->Length
+ sizeof (UINT32
);
919 AcpiTableInstance
->NumberOfTableEntries1
++;
923 // Add to ACPI 2.0/3.0 table tree
925 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
926 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
929 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
931 if (AcpiTableInstance
->NumberOfTableEntries3
>= mEfiAcpiMaxNumTables
) {
932 Status
= ReallocateAcpiTableBuffer (AcpiTableInstance
);
933 ASSERT_EFI_ERROR (Status
);
936 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
937 // If it becomes necessary to maintain separate table lists, changes will be required.
939 CurrentRsdtEntry
= (UINT32
*)
941 (UINT8
*) AcpiTableInstance
->Rsdt3
+
942 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
943 AcpiTableInstance
->NumberOfTableEntries3
*
948 // This pointer must not be directly dereferenced as the XSDT entries may not
949 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
951 CurrentXsdtEntry
= (VOID
*)
953 (UINT8
*) AcpiTableInstance
->Xsdt
+
954 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
955 AcpiTableInstance
->NumberOfTableEntries3
*
960 // Add entry to the RSDT
962 *CurrentRsdtEntry
= (UINT32
) (UINTN
) CurrentTableList
->Table
;
965 // Update RSDT length
967 AcpiTableInstance
->Rsdt3
->Length
= AcpiTableInstance
->Rsdt3
->Length
+ sizeof (UINT32
);
970 // Add entry to XSDT, XSDT expects 64 bit pointers, but
971 // the table pointers in XSDT are not aligned on 8 byte boundary.
973 Buffer64
= (UINT64
) (UINTN
) CurrentTableList
->Table
;
983 AcpiTableInstance
->Xsdt
->Length
= AcpiTableInstance
->Xsdt
->Length
+ sizeof (UINT64
);
985 AcpiTableInstance
->NumberOfTableEntries3
++;
989 ChecksumCommonTables (AcpiTableInstance
);
995 This function finds the table specified by the handle and returns a pointer to it.
996 If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are
999 @param Handle Table to find.
1000 @param TableList Table list to search
1001 @param Table Pointer to table found.
1003 @return EFI_SUCCESS The function completed successfully.
1004 @return EFI_NOT_FOUND No table found matching the handle specified.
1010 IN LIST_ENTRY
*TableList
,
1011 OUT EFI_ACPI_TABLE_LIST
**Table
1014 LIST_ENTRY
*CurrentLink
;
1015 EFI_ACPI_TABLE_LIST
*CurrentTable
;
1018 // Check for invalid input parameters
1025 CurrentLink
= TableList
->ForwardLink
;
1027 while (CurrentLink
!= TableList
) {
1028 CurrentTable
= EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink
);
1029 if (CurrentTable
->Handle
== Handle
) {
1031 // Found handle, so return this table.
1033 *Table
= CurrentTable
;
1037 CurrentLink
= CurrentLink
->ForwardLink
;
1042 return EFI_NOT_FOUND
;
1047 This function removes a basic table from the RSDT and/or XSDT.
1048 For Acpi 1.0 tables, pass in the Rsdt.
1049 For Acpi 2.0 tables, pass in both Rsdt and Xsdt.
1051 @param Table Pointer to table found.
1052 @param NumberOfTableEntries Current number of table entries in the RSDT/XSDT
1053 @param Rsdt Pointer to the RSDT to remove from
1054 @param Xsdt Pointer to the Xsdt to remove from
1056 @return EFI_SUCCESS The function completed successfully.
1057 @return EFI_INVALID_PARAMETER The table was not found in both Rsdt and Xsdt.
1061 RemoveTableFromRsdt (
1062 IN OUT EFI_ACPI_TABLE_LIST
* Table
,
1063 IN OUT UINTN
*NumberOfTableEntries
,
1064 IN OUT EFI_ACPI_DESCRIPTION_HEADER
* Rsdt
,
1065 IN OUT EFI_ACPI_DESCRIPTION_HEADER
* Xsdt OPTIONAL
1068 UINT32
*CurrentRsdtEntry
;
1069 VOID
*CurrentXsdtEntry
;
1070 UINT64 CurrentTablePointer64
;
1074 // Check for invalid input parameters
1077 ASSERT (NumberOfTableEntries
);
1081 // Find the table entry in the RSDT and XSDT
1083 for (Index
= 0; Index
< *NumberOfTableEntries
; Index
++) {
1085 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1086 // If it becomes necessary to maintain separate table lists, changes will be required.
1088 CurrentRsdtEntry
= (UINT32
*) ((UINT8
*) Rsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + Index
* sizeof (UINT32
));
1091 // This pointer must not be directly dereferenced as the XSDT entries may not
1092 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1094 CurrentXsdtEntry
= (VOID
*) ((UINT8
*) Xsdt
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + Index
* sizeof (UINT64
));
1097 // Read the entry value out of the XSDT
1099 CopyMem (&CurrentTablePointer64
, CurrentXsdtEntry
, sizeof (UINT64
));
1102 // Initialize to NULL
1104 CurrentXsdtEntry
= 0;
1105 CurrentTablePointer64
= 0;
1108 // Check if we have found the corresponding entry in both RSDT and XSDT
1110 if (*CurrentRsdtEntry
== (UINT32
) (UINTN
) Table
->Table
&&
1111 ((Xsdt
== NULL
) || CurrentTablePointer64
== (UINT64
) (UINTN
) Table
->Table
)
1114 // Found entry, so copy all following entries and shrink table
1115 // We actually copy all + 1 to copy the initialized value of memory over
1118 CopyMem (CurrentRsdtEntry
, CurrentRsdtEntry
+ 1, (*NumberOfTableEntries
- Index
) * sizeof (UINT32
));
1119 Rsdt
->Length
= Rsdt
->Length
- sizeof (UINT32
);
1121 CopyMem (CurrentXsdtEntry
, ((UINT64
*) CurrentXsdtEntry
) + 1, (*NumberOfTableEntries
- Index
) * sizeof (UINT64
));
1122 Xsdt
->Length
= Xsdt
->Length
- sizeof (UINT64
);
1125 } else if (Index
+ 1 == *NumberOfTableEntries
) {
1127 // At the last entry, and table not found
1129 return EFI_INVALID_PARAMETER
;
1133 // Checksum the tables
1135 AcpiPlatformChecksum (
1138 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1143 AcpiPlatformChecksum (
1146 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1151 // Decrement the number of tables
1153 (*NumberOfTableEntries
)--;
1160 This function removes a table and frees any associated memory.
1162 @param AcpiTableInstance Instance of the protocol.
1163 @param Version Version(s) to delete.
1164 @param Table Pointer to table found.
1166 @return EFI_SUCCESS The function completed successfully.
1171 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
1172 IN EFI_ACPI_TABLE_VERSION Version
,
1173 IN OUT EFI_ACPI_TABLE_LIST
*Table
1176 UINT32 CurrentTableSignature
;
1177 BOOLEAN RemoveFromRsdt
;
1180 // Check for invalid input parameters
1182 ASSERT (AcpiTableInstance
);
1188 RemoveFromRsdt
= TRUE
;
1190 // Check for Table->Table
1192 ASSERT (Table
->Table
!= NULL
);
1193 CurrentTableSignature
= ((EFI_ACPI_COMMON_HEADER
*) Table
->Table
)->Signature
;
1196 // Basic tasks to accomplish delete are:
1197 // Determine removal requirements (in RSDT/XSDT or not)
1198 // Remove entry from RSDT/XSDT
1199 // Remove any table references to the table
1200 // If no one is using the table
1201 // Free the table (removing pointers from private data and tables)
1203 // Free list structure
1206 // Determine if this table is in the RSDT or XSDT
1208 if ((CurrentTableSignature
== EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) ||
1209 (CurrentTableSignature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) ||
1210 (CurrentTableSignature
== EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)
1212 RemoveFromRsdt
= FALSE
;
1215 // We don't remove the FADT in the standard way because some
1216 // OS expect the FADT to be early in the table list.
1217 // So we always put it as the first element in the list.
1219 if (CurrentTableSignature
== EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
) {
1220 RemoveFromRsdt
= FALSE
;
1224 // Remove the table from RSDT and XSDT
1226 if (Table
->Table
!= NULL
) {
1228 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
1230 if (Version
& EFI_ACPI_TABLE_VERSION_NONE
& Table
->Version
) {
1232 // Remove this version from the table
1234 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_NONE
;
1237 if (Version
& EFI_ACPI_TABLE_VERSION_1_0B
& Table
->Version
) {
1239 // Remove this version from the table
1241 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_1_0B
;
1244 // Remove from Rsdt. We don't care about the return value because it is
1245 // acceptable for the table to not exist in Rsdt.
1246 // We didn't add some tables so we don't remove them.
1248 if (RemoveFromRsdt
) {
1249 RemoveTableFromRsdt (
1251 &AcpiTableInstance
->NumberOfTableEntries1
,
1252 AcpiTableInstance
->Rsdt1
,
1258 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
& Table
->Version
) ||
1259 (Version
& EFI_ACPI_TABLE_VERSION_3_0
& Table
->Version
)) {
1261 // Remove this version from the table
1263 if (Version
& EFI_ACPI_TABLE_VERSION_2_0
& Table
->Version
) {
1264 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_2_0
;
1266 if (Version
& EFI_ACPI_TABLE_VERSION_3_0
& Table
->Version
) {
1267 Table
->Version
= Table
->Version
&~EFI_ACPI_TABLE_VERSION_3_0
;
1271 // Remove from Rsdt and Xsdt. We don't care about the return value
1272 // because it is acceptable for the table to not exist in Rsdt/Xsdt.
1273 // We didn't add some tables so we don't remove them.
1275 if (RemoveFromRsdt
) {
1276 RemoveTableFromRsdt (
1278 &AcpiTableInstance
->NumberOfTableEntries3
,
1279 AcpiTableInstance
->Rsdt3
,
1280 AcpiTableInstance
->Xsdt
1285 // Free the table, clean up any dependent tables and our private data pointers.
1287 switch (Table
->Table
->Signature
) {
1289 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
1290 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1291 AcpiTableInstance
->Fadt1
= NULL
;
1294 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1295 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1296 AcpiTableInstance
->Fadt3
= NULL
;
1300 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
1301 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1302 AcpiTableInstance
->Facs1
= NULL
;
1305 // Update FADT table pointers
1307 if (AcpiTableInstance
->Fadt1
!= NULL
) {
1308 AcpiTableInstance
->Fadt1
->FirmwareCtrl
= 0;
1313 AcpiPlatformChecksum (
1314 AcpiTableInstance
->Fadt1
,
1315 AcpiTableInstance
->Fadt1
->Header
.Length
,
1316 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1322 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1323 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1324 AcpiTableInstance
->Facs3
= NULL
;
1327 // Update FADT table pointers
1329 if (AcpiTableInstance
->Fadt3
!= NULL
) {
1330 AcpiTableInstance
->Fadt3
->FirmwareCtrl
= 0;
1331 ZeroMem (&AcpiTableInstance
->Fadt3
->XFirmwareCtrl
, sizeof (UINT64
));
1336 AcpiPlatformChecksum (
1337 AcpiTableInstance
->Fadt3
,
1338 AcpiTableInstance
->Fadt3
->Header
.Length
,
1339 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1346 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
1347 if ((Version
& EFI_ACPI_TABLE_VERSION_1_0B
) != 0) {
1348 AcpiTableInstance
->Dsdt1
= NULL
;
1351 // Update FADT table pointers
1353 if (AcpiTableInstance
->Fadt1
!= NULL
) {
1354 AcpiTableInstance
->Fadt1
->Dsdt
= 0;
1359 AcpiPlatformChecksum (
1360 AcpiTableInstance
->Fadt1
,
1361 AcpiTableInstance
->Fadt1
->Header
.Length
,
1362 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1369 if ((Version
& EFI_ACPI_TABLE_VERSION_2_0
) != 0 ||
1370 (Version
& EFI_ACPI_TABLE_VERSION_3_0
) != 0) {
1371 AcpiTableInstance
->Dsdt3
= NULL
;
1374 // Update FADT table pointers
1376 if (AcpiTableInstance
->Fadt3
!= NULL
) {
1377 AcpiTableInstance
->Fadt3
->Dsdt
= 0;
1378 ZeroMem (&AcpiTableInstance
->Fadt3
->XDsdt
, sizeof (UINT64
));
1383 AcpiPlatformChecksum (
1384 AcpiTableInstance
->Fadt3
,
1385 AcpiTableInstance
->Fadt3
->Header
.Length
,
1386 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1401 // If no version is using this table anymore, remove and free list entry.
1403 if (Table
->Version
== 0) {
1407 gBS
->FreePages (Table
->PageAddress
, Table
->NumberOfPages
);
1408 RemoveEntryList (&(Table
->Link
));
1409 gBS
->FreePool (Table
);
1419 This function finds and removes the table specified by the handle.
1421 @param AcpiTableInstance Instance of the protocol.
1422 @param Version Bitmask of which versions to remove.
1423 @param Handle Table to remove.
1425 @return EFI_SUCCESS The function completed successfully.
1426 @return EFI_ABORTED An error occurred.
1427 @return EFI_NOT_FOUND Handle not found in table list.
1431 RemoveTableFromList (
1432 IN EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
,
1433 IN EFI_ACPI_TABLE_VERSION Version
,
1437 EFI_ACPI_TABLE_LIST
*Table
;
1440 Table
= (EFI_ACPI_TABLE_LIST
*) NULL
;
1443 // Check for invalid input parameters
1445 ASSERT (AcpiTableInstance
);
1450 Status
= FindTableByHandle (
1452 &AcpiTableInstance
->TableList
,
1455 if (EFI_ERROR (Status
)) {
1456 return EFI_NOT_FOUND
;
1461 Status
= DeleteTable (AcpiTableInstance
, Version
, Table
);
1462 if (EFI_ERROR (Status
)) {
1466 // Completed successfully
1473 This function calculates and updates an UINT8 checksum.
1475 @param Buffer Pointer to buffer to checksum
1476 @param Size Number of bytes to checksum
1477 @param ChecksumOffset Offset to place the checksum result in
1479 @return EFI_SUCCESS The function completed successfully.
1483 AcpiPlatformChecksum (
1486 IN UINTN ChecksumOffset
1494 // Initialize pointer
1499 // set checksum to 0 first
1501 Ptr
[ChecksumOffset
] = 0;
1504 // add all content of buffer
1506 while ((Size
--) != 0) {
1507 Sum
= (UINT8
) (Sum
+ (*Ptr
++));
1513 Ptr
[ChecksumOffset
] = (UINT8
) (0xff - Sum
+ 1);
1520 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
1522 @param AcpiTableInstance Protocol instance private data.
1524 @return EFI_SUCCESS The function completed successfully.
1528 ChecksumCommonTables (
1529 IN OUT EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1533 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure
1535 AcpiPlatformChecksum (
1536 AcpiTableInstance
->Rsdp1
,
1537 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1538 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1543 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure
1545 AcpiPlatformChecksum (
1546 AcpiTableInstance
->Rsdp3
,
1547 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1548 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1553 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
1555 AcpiPlatformChecksum (
1556 AcpiTableInstance
->Rsdp3
,
1557 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
),
1558 OFFSET_OF (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
,
1565 AcpiPlatformChecksum (
1566 AcpiTableInstance
->Rsdt1
,
1567 AcpiTableInstance
->Rsdt1
->Length
,
1568 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1572 AcpiPlatformChecksum (
1573 AcpiTableInstance
->Rsdt3
,
1574 AcpiTableInstance
->Rsdt3
->Length
,
1575 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1582 AcpiPlatformChecksum (
1583 AcpiTableInstance
->Xsdt
,
1584 AcpiTableInstance
->Xsdt
->Length
,
1585 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER
,
1594 Constructor for the ACPI table protocol. Initializes instance
1597 @param AcpiTableInstance Instance to construct
1599 @return EFI_SUCCESS Instance initialized.
1600 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
1604 AcpiTableAcpiTableConstructor (
1605 EFI_ACPI_TABLE_INSTANCE
*AcpiTableInstance
1611 UINTN RsdpTableSize
;
1613 EFI_PHYSICAL_ADDRESS PageAddress
;
1616 // Check for invalid input parameters
1618 ASSERT (AcpiTableInstance
);
1620 InitializeListHead (&AcpiTableInstance
->TableList
);
1621 AcpiTableInstance
->CurrentHandle
= 1;
1623 AcpiTableInstance
->AcpiTableProtocol
.InstallAcpiTable
= InstallAcpiTable
;
1624 AcpiTableInstance
->AcpiTableProtocol
.UninstallAcpiTable
= UninstallAcpiTable
;
1626 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol
)) {
1627 SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance
);
1631 // Create RSDP table
1633 RsdpTableSize
= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
) +
1634 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1636 PageAddress
= 0xFFFFFFFF;
1637 Status
= gBS
->AllocatePages (
1639 EfiACPIReclaimMemory
,
1640 EFI_SIZE_TO_PAGES (RsdpTableSize
),
1644 if (EFI_ERROR (Status
)) {
1645 return EFI_OUT_OF_RESOURCES
;
1648 Pointer
= (UINT8
*) (UINTN
) PageAddress
;
1649 ZeroMem (Pointer
, RsdpTableSize
);
1651 AcpiTableInstance
->Rsdp1
= (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*) Pointer
;
1652 Pointer
+= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1653 AcpiTableInstance
->Rsdp3
= (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*) Pointer
;
1656 // Create RSDT, XSDT structures
1658 TotalSize
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 1.0 RSDT
1659 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
1660 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 RSDT
1661 mEfiAcpiMaxNumTables
* sizeof (UINT32
) +
1662 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + // for ACPI 2.0/3.0 XSDT
1663 mEfiAcpiMaxNumTables
* sizeof (UINT64
);
1666 // Allocate memory in the lower 32 bit of address range for
1667 // compatibility with ACPI 1.0 OS.
1669 // This is done because ACPI 1.0 pointers are 32 bit values.
1670 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
1671 // There is no architectural reason these should be below 4GB, it is purely
1672 // for convenience of implementation that we force memory below 4GB.
1674 PageAddress
= 0xFFFFFFFF;
1675 Status
= gBS
->AllocatePages (
1677 EfiACPIReclaimMemory
,
1678 EFI_SIZE_TO_PAGES (TotalSize
),
1682 if (EFI_ERROR (Status
)) {
1683 gBS
->FreePages ((EFI_PHYSICAL_ADDRESS
)(UINTN
)AcpiTableInstance
->Rsdp1
, EFI_SIZE_TO_PAGES (RsdpTableSize
));
1684 return EFI_OUT_OF_RESOURCES
;
1687 Pointer
= (UINT8
*) (UINTN
) PageAddress
;
1688 ZeroMem (Pointer
, TotalSize
);
1690 AcpiTableInstance
->Rsdt1
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
1691 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + EFI_ACPI_MAX_NUM_TABLES
* sizeof (UINT32
));
1692 AcpiTableInstance
->Rsdt3
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
1693 Pointer
+= (sizeof (EFI_ACPI_DESCRIPTION_HEADER
) + EFI_ACPI_MAX_NUM_TABLES
* sizeof (UINT32
));
1694 AcpiTableInstance
->Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) Pointer
;
1699 CurrentData
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
;
1700 CopyMem (&AcpiTableInstance
->Rsdp1
->Signature
, &CurrentData
, sizeof (UINT64
));
1701 CopyMem (AcpiTableInstance
->Rsdp1
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdp1
->OemId
));
1702 AcpiTableInstance
->Rsdp1
->Reserved
= EFI_ACPI_RESERVED_BYTE
;
1703 AcpiTableInstance
->Rsdp1
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt1
;
1705 CurrentData
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
;
1706 CopyMem (&AcpiTableInstance
->Rsdp3
->Signature
, &CurrentData
, sizeof (UINT64
));
1707 CopyMem (AcpiTableInstance
->Rsdp3
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdp3
->OemId
));
1708 AcpiTableInstance
->Rsdp3
->Revision
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION
;
1709 AcpiTableInstance
->Rsdp3
->RsdtAddress
= (UINT32
) (UINTN
) AcpiTableInstance
->Rsdt3
;
1710 AcpiTableInstance
->Rsdp3
->Length
= sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1711 CurrentData
= (UINT64
) (UINTN
) AcpiTableInstance
->Xsdt
;
1712 CopyMem (&AcpiTableInstance
->Rsdp3
->XsdtAddress
, &CurrentData
, sizeof (UINT64
));
1713 SetMem (AcpiTableInstance
->Rsdp3
->Reserved
, 3, EFI_ACPI_RESERVED_BYTE
);
1718 // Note that we "reserve" one entry for the FADT so it can always be
1719 // at the beginning of the list of tables. Some OS don't seem
1720 // to find it correctly if it is too far down the list.
1722 AcpiTableInstance
->Rsdt1
->Signature
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
1723 AcpiTableInstance
->Rsdt1
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
1724 AcpiTableInstance
->Rsdt1
->Revision
= EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
;
1725 CopyMem (AcpiTableInstance
->Rsdt1
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdt1
->OemId
));
1726 CurrentData
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1727 CopyMem (&AcpiTableInstance
->Rsdt1
->OemTableId
, &CurrentData
, sizeof (UINT64
));
1728 AcpiTableInstance
->Rsdt1
->OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1729 AcpiTableInstance
->Rsdt1
->CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1730 AcpiTableInstance
->Rsdt1
->CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1732 // We always reserve first one for FADT
1734 AcpiTableInstance
->NumberOfTableEntries1
= 1;
1735 AcpiTableInstance
->Rsdt1
->Length
= AcpiTableInstance
->Rsdt1
->Length
+ sizeof(UINT32
);
1737 AcpiTableInstance
->Rsdt3
->Signature
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
1738 AcpiTableInstance
->Rsdt3
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
1739 AcpiTableInstance
->Rsdt3
->Revision
= EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
;
1740 CopyMem (AcpiTableInstance
->Rsdt3
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Rsdt3
->OemId
));
1741 CurrentData
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1742 CopyMem (&AcpiTableInstance
->Rsdt3
->OemTableId
, &CurrentData
, sizeof (UINT64
));
1743 AcpiTableInstance
->Rsdt3
->OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1744 AcpiTableInstance
->Rsdt3
->CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1745 AcpiTableInstance
->Rsdt3
->CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1747 // We always reserve first one for FADT
1749 AcpiTableInstance
->NumberOfTableEntries3
= 1;
1750 AcpiTableInstance
->Rsdt3
->Length
= AcpiTableInstance
->Rsdt3
->Length
+ sizeof(UINT32
);
1755 AcpiTableInstance
->Xsdt
->Signature
= EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
;
1756 AcpiTableInstance
->Xsdt
->Length
= sizeof (EFI_ACPI_DESCRIPTION_HEADER
);
1757 AcpiTableInstance
->Xsdt
->Revision
= EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION
;
1758 CopyMem (AcpiTableInstance
->Xsdt
->OemId
, PcdGetPtr (PcdAcpiDefaultOemId
), sizeof (AcpiTableInstance
->Xsdt
->OemId
));
1759 CurrentData
= PcdGet64 (PcdAcpiDefaultOemTableId
);
1760 CopyMem (&AcpiTableInstance
->Xsdt
->OemTableId
, &CurrentData
, sizeof (UINT64
));
1761 AcpiTableInstance
->Xsdt
->OemRevision
= PcdGet32 (PcdAcpiDefaultOemRevision
);
1762 AcpiTableInstance
->Xsdt
->CreatorId
= PcdGet32 (PcdAcpiDefaultCreatorId
);
1763 AcpiTableInstance
->Xsdt
->CreatorRevision
= PcdGet32 (PcdAcpiDefaultCreatorRevision
);
1765 // We always reserve first one for FADT
1767 AcpiTableInstance
->Xsdt
->Length
= AcpiTableInstance
->Xsdt
->Length
+ sizeof(UINT64
);
1769 ChecksumCommonTables (AcpiTableInstance
);
1772 // Completed successfully