TianoCore EDK2 master
Loading...
Searching...
No Matches
AcpiTableProtocol.c
Go to the documentation of this file.
1
10//
11// Includes
12//
13#include "AcpiTable.h"
14//
15// The maximum number of tables that pre-allocated.
16//
17UINTN mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES;
18
19//
20// Allocation strategy to use for AllocatePages ().
21// Runtime value depends on PcdExposedAcpiTableVersions.
22//
23STATIC EFI_ALLOCATE_TYPE mAcpiTableAllocType;
24
44 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
45 IN VOID *Table,
46 IN BOOLEAN Checksum,
47 IN EFI_ACPI_TABLE_VERSION Version,
48 IN BOOLEAN IsFromHob,
49 OUT UINTN *Handle
50 );
51
66 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
67 IN EFI_ACPI_TABLE_VERSION Version,
68 IN UINTN Handle
69 );
70
82 IN VOID *Buffer,
83 IN UINTN Size,
84 IN UINTN ChecksumOffset
85 );
86
97 IN OUT EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
98 );
99
100//
101// Protocol function implementations.
102//
103
117EFIAPI
119 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
120 IN EFI_ACPI_TABLE_VERSION Version
121 )
122{
123 EFI_STATUS Status;
124 UINT32 *CurrentRsdtEntry;
125 VOID *CurrentXsdtEntry;
126 UINT64 Buffer64;
127
128 //
129 // Reorder tables as some operating systems don't seem to find the
130 // FADT correctly if it is not in the first few entries
131 //
132
133 //
134 // Add FADT as the first entry
135 //
136 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
137 CurrentRsdtEntry = (UINT32 *)((UINT8 *)AcpiTableInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
138 *CurrentRsdtEntry = (UINT32)(UINTN)AcpiTableInstance->Fadt1;
139
140 CurrentRsdtEntry = (UINT32 *)((UINT8 *)AcpiTableInstance->Rsdt3 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
141 *CurrentRsdtEntry = (UINT32)(UINTN)AcpiTableInstance->Fadt3;
142 }
143
144 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
145 CurrentXsdtEntry = (VOID *)((UINT8 *)AcpiTableInstance->Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
146 //
147 // Add entry to XSDT, XSDT expects 64 bit pointers, but
148 // the table pointers in XSDT are not aligned on 8 byte boundary.
149 //
150 Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Fadt3;
151 CopyMem (
152 CurrentXsdtEntry,
153 &Buffer64,
154 sizeof (UINT64)
155 );
156 }
157
158 //
159 // Do checksum again because Dsdt/Xsdt is updated.
160 //
161 ChecksumCommonTables (AcpiTableInstance);
162
163 //
164 // Add the RSD_PTR to the system table and store that we have installed the
165 // tables.
166 //
167 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
168 Status = gBS->InstallConfigurationTable (&gEfiAcpi10TableGuid, AcpiTableInstance->Rsdp1);
169 if (EFI_ERROR (Status)) {
170 return EFI_ABORTED;
171 }
172 }
173
174 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
175 Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, AcpiTableInstance->Rsdp3);
176 if (EFI_ERROR (Status)) {
177 return EFI_ABORTED;
178 }
179 }
180
181 return EFI_SUCCESS;
182}
183
205EFIAPI
208 IN VOID *AcpiTableBuffer,
209 IN UINTN AcpiTableBufferSize,
210 OUT UINTN *TableKey
211 )
212{
213 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;
214 EFI_STATUS Status;
215 VOID *AcpiTableBufferConst;
216 EFI_ACPI_TABLE_VERSION Version;
217
218 //
219 // Check for invalid input parameters
220 //
221 if ( (AcpiTableBuffer == NULL) || (TableKey == NULL)
222 || (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTableBuffer)->Length != AcpiTableBufferSize))
223 {
224 return EFI_INVALID_PARAMETER;
225 }
226
227 Version = PcdGet32 (PcdAcpiExposedTableVersions);
228
229 //
230 // Get the instance of the ACPI table protocol
231 //
232 AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);
233
234 //
235 // Install the ACPI table
236 //
237 AcpiTableBufferConst = AllocateCopyPool (AcpiTableBufferSize, AcpiTableBuffer);
238 *TableKey = 0;
239 Status = AddTableToList (
240 AcpiTableInstance,
241 AcpiTableBufferConst,
242 TRUE,
243 Version,
244 FALSE,
245 TableKey
246 );
247 if (!EFI_ERROR (Status)) {
248 Status = PublishTables (
249 AcpiTableInstance,
250 Version
251 );
252 }
253
254 FreePool (AcpiTableBufferConst);
255
256 //
257 // Add a new table successfully, notify registed callback
258 //
259 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
260 if (!EFI_ERROR (Status)) {
262 AcpiTableInstance,
263 Version,
264 *TableKey
265 );
266 }
267 }
268
269 return Status;
270}
271
283EFIAPI
286 IN UINTN TableKey
287 )
288{
289 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;
290 EFI_STATUS Status;
291 EFI_ACPI_TABLE_VERSION Version;
292
293 //
294 // Get the instance of the ACPI table protocol
295 //
296 AcpiTableInstance = EFI_ACPI_TABLE_INSTANCE_FROM_THIS (This);
297
298 Version = PcdGet32 (PcdAcpiExposedTableVersions);
299
300 //
301 // Uninstall the ACPI table
302 //
303 Status = RemoveTableFromList (
304 AcpiTableInstance,
305 Version,
306 TableKey
307 );
308 if (!EFI_ERROR (Status)) {
309 Status = PublishTables (
310 AcpiTableInstance,
311 Version
312 );
313 }
314
315 if (EFI_ERROR (Status)) {
316 return EFI_NOT_FOUND;
317 } else {
318 return EFI_SUCCESS;
319 }
320}
321
333 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
334 )
335{
336 UINTN NewMaxTableNumber;
337 UINTN TotalSize;
338 UINT8 *Pointer;
339 EFI_PHYSICAL_ADDRESS PageAddress;
340 EFI_ACPI_TABLE_INSTANCE TempPrivateData;
341 EFI_STATUS Status;
342 UINT64 CurrentData;
343 EFI_MEMORY_TYPE AcpiAllocateMemoryType;
344
345 CopyMem (&TempPrivateData, AcpiTableInstance, sizeof (EFI_ACPI_TABLE_INSTANCE));
346 //
347 // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES
348 //
349 NewMaxTableNumber = mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES;
350 //
351 // Create RSDT, XSDT structures and allocate buffers.
352 //
353 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
354 NewMaxTableNumber * sizeof (UINT64);
355
356 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
357 TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
358 NewMaxTableNumber * sizeof (UINT32) +
359 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
360 NewMaxTableNumber * sizeof (UINT32);
361 }
362
363 if (PcdGetBool (PcdNoACPIReclaimMemory)) {
364 AcpiAllocateMemoryType = EfiACPIMemoryNVS;
365 } else {
366 AcpiAllocateMemoryType = EfiACPIReclaimMemory;
367 }
368
369 if (mAcpiTableAllocType != AllocateAnyPages) {
370 //
371 // Allocate memory in the lower 32 bit of address range for
372 // compatibility with ACPI 1.0 OS.
373 //
374 // This is done because ACPI 1.0 pointers are 32 bit values.
375 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
376 // There is no architectural reason these should be below 4GB, it is purely
377 // for convenience of implementation that we force memory below 4GB.
378 //
379 PageAddress = 0xFFFFFFFF;
380 Status = gBS->AllocatePages (
381 mAcpiTableAllocType,
382 AcpiAllocateMemoryType,
383 EFI_SIZE_TO_PAGES (TotalSize),
384 &PageAddress
385 );
386 } else {
387 Status = gBS->AllocatePool (
388 AcpiAllocateMemoryType,
389 TotalSize,
390 (VOID **)&Pointer
391 );
392 }
393
394 if (EFI_ERROR (Status)) {
395 return EFI_OUT_OF_RESOURCES;
396 }
397
398 if (mAcpiTableAllocType != AllocateAnyPages) {
399 Pointer = (UINT8 *)(UINTN)PageAddress;
400 }
401
402 ZeroMem (Pointer, TotalSize);
403
404 AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
405 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
406 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));
407 AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
408 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));
409 }
410
411 AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
412
413 //
414 // Update RSDP to point to the new Rsdt and Xsdt address.
415 //
416 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
417 AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt1;
418 AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt3;
419 }
420
421 CurrentData = (UINT64)(UINTN)AcpiTableInstance->Xsdt;
422 CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));
423
424 //
425 // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer
426 //
427 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
428 CopyMem (AcpiTableInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));
429 CopyMem (AcpiTableInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));
430 }
431
432 CopyMem (AcpiTableInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));
433
434 if (mAcpiTableAllocType != AllocateAnyPages) {
435 //
436 // Calculate orignal ACPI table buffer size
437 //
438 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
439 mEfiAcpiMaxNumTables * sizeof (UINT64);
440
441 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
442 TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
443 mEfiAcpiMaxNumTables * sizeof (UINT32) +
444 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
445 mEfiAcpiMaxNumTables * sizeof (UINT32);
446 }
447
448 gBS->FreePages (
449 (EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1,
450 EFI_SIZE_TO_PAGES (TotalSize)
451 );
452 } else {
453 gBS->FreePool (TempPrivateData.Rsdt1);
454 }
455
456 //
457 // Update the Max ACPI table number
458 //
459 mEfiAcpiMaxNumTables = NewMaxTableNumber;
460 return EFI_SUCCESS;
461}
462
469STATIC
470VOID
472 EFI_ACPI_TABLE_LIST *TableEntry
473 )
474{
475 if (TableEntry->PoolAllocation) {
476 gBS->FreePool (TableEntry->Table);
477 } else {
478 gBS->FreePages (
479 (EFI_PHYSICAL_ADDRESS)(UINTN)TableEntry->Table,
480 EFI_SIZE_TO_PAGES (TableEntry->TableSize)
481 );
482 }
483}
484
505 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
506 IN VOID *Table,
507 IN BOOLEAN Checksum,
508 IN EFI_ACPI_TABLE_VERSION Version,
509 IN BOOLEAN IsFromHob,
510 OUT UINTN *Handle
511 )
512{
513 EFI_STATUS Status;
514 EFI_ACPI_TABLE_LIST *CurrentTableList;
515 UINT32 CurrentTableSignature;
516 UINT32 CurrentTableSize;
517 UINT32 *CurrentRsdtEntry;
518 VOID *CurrentXsdtEntry;
519 EFI_PHYSICAL_ADDRESS AllocPhysAddress;
520 UINT64 Buffer64;
521 BOOLEAN AddToRsdt;
522 EFI_MEMORY_TYPE AcpiAllocateMemoryType;
523
524 //
525 // Check for invalid input parameters
526 //
527 ASSERT (AcpiTableInstance);
528 ASSERT (Table);
529 ASSERT (Handle);
530
531 //
532 // Init locals
533 //
534 AddToRsdt = TRUE;
535
536 //
537 // Create a new list entry
538 //
539 CurrentTableList = AllocatePool (sizeof (EFI_ACPI_TABLE_LIST));
540 ASSERT (CurrentTableList);
541
542 //
543 // Determine table type and size
544 //
545 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *)Table)->Signature;
546 CurrentTableSize = ((EFI_ACPI_COMMON_HEADER *)Table)->Length;
547
548 //
549 // Allocate a buffer for the table. All tables are allocated in the lower 32 bits of address space
550 // for backwards compatibility with ACPI 1.0 OS.
551 //
552 // This is done because ACPI 1.0 pointers are 32 bit values.
553 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
554 // There is no architectural reason these should be below 4GB, it is purely
555 // for convenience of implementation that we force memory below 4GB.
556 //
557 AllocPhysAddress = 0xFFFFFFFF;
558 CurrentTableList->TableSize = CurrentTableSize;
559 CurrentTableList->PoolAllocation = FALSE;
560
561 if (PcdGetBool (PcdNoACPIReclaimMemory)) {
562 AcpiAllocateMemoryType = EfiACPIMemoryNVS;
563 } else {
564 AcpiAllocateMemoryType = EfiACPIReclaimMemory;
565 }
566
567 //
568 // Allocation memory type depends on the type of the table
569 //
570 if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
571 (CurrentTableSignature == EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE))
572 {
573 //
574 // Allocate memory for the FACS. This structure must be aligned
575 // on a 64 byte boundary and must be ACPI NVS memory.
576 // Using AllocatePages should ensure that it is always aligned.
577 // Do not change signature for new ACPI version because they are same.
578 //
579 // UEFI table also need to be in ACPI NVS memory, because some data field
580 // could be updated by OS present agent. For example, BufferPtrAddress in
581 // SMM communication ACPI table.
582 //
583 ASSERT ((EFI_PAGE_SIZE % 64) == 0);
584 if (IsFromHob) {
585 AllocPhysAddress = (UINTN)Table;
586 Status = EFI_SUCCESS;
587 } else {
588 Status = gBS->AllocatePages (
591 EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),
592 &AllocPhysAddress
593 );
594 }
595 } else if (mAcpiTableAllocType == AllocateAnyPages) {
596 //
597 // If there is no allocation limit, there is also no need to use page
598 // based allocations for ACPI tables, which may be wasteful on platforms
599 // such as AArch64 that allocate multiples of 64 KB
600 //
601 Status = gBS->AllocatePool (
602 AcpiAllocateMemoryType,
603 CurrentTableList->TableSize,
604 (VOID **)&CurrentTableList->Table
605 );
606 CurrentTableList->PoolAllocation = TRUE;
607 } else {
608 //
609 // All other tables are ACPI reclaim memory, no alignment requirements.
610 //
611 Status = gBS->AllocatePages (
612 mAcpiTableAllocType,
613 AcpiAllocateMemoryType,
614 EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),
615 &AllocPhysAddress
616 );
617 CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *)(UINTN)AllocPhysAddress;
618 }
619
620 //
621 // Check return value from memory alloc.
622 //
623 if (EFI_ERROR (Status)) {
624 gBS->FreePool (CurrentTableList);
625 return EFI_OUT_OF_RESOURCES;
626 }
627
628 if (!CurrentTableList->PoolAllocation) {
629 CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *)(UINTN)AllocPhysAddress;
630 }
631
632 //
633 // Initialize the table contents
634 //
635 CurrentTableList->Signature = EFI_ACPI_TABLE_LIST_SIGNATURE;
636 CopyMem (CurrentTableList->Table, Table, CurrentTableSize);
637 CurrentTableList->Handle = AcpiTableInstance->CurrentHandle++;
638 *Handle = CurrentTableList->Handle;
639 CurrentTableList->Version = Version;
640
641 //
642 // Update internal pointers if this is a required table. If it is a required
643 // table and a table of that type already exists, return an error.
644 //
645 // Calculate the checksum if the table is not FACS.
646 //
647 switch (CurrentTableSignature) {
649 //
650 // We don't add the FADT in the standard way because some
651 // OS expect the FADT to be early in the table list.
652 // So we always add it as the first element in the list.
653 //
654 AddToRsdt = FALSE;
655
656 //
657 // Check that the table has not been previously added.
658 //
659 if ((((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) && (AcpiTableInstance->Fadt1 != NULL)) ||
660 (((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) && (AcpiTableInstance->Fadt3 != NULL))
661 )
662 {
663 FreeTableMemory (CurrentTableList);
664 gBS->FreePool (CurrentTableList);
665 return EFI_ACCESS_DENIED;
666 }
667
668 //
669 // Add the table to the appropriate table version
670 //
671 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
672 //
673 // Save a pointer to the table
674 //
675 AcpiTableInstance->Fadt1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)CurrentTableList->Table;
676
677 //
678 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
679 //
680 AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs1;
681 AcpiTableInstance->Fadt1->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt1;
682
683 //
684 // RSDP OEM information is updated to match the FADT OEM information
685 //
686 CopyMem (
687 &AcpiTableInstance->Rsdp1->OemId,
688 &AcpiTableInstance->Fadt1->Header.OemId,
689 6
690 );
691
692 //
693 // RSDT OEM information is updated to match the FADT OEM information.
694 //
695 CopyMem (
696 &AcpiTableInstance->Rsdt1->OemId,
697 &AcpiTableInstance->Fadt1->Header.OemId,
698 6
699 );
700
701 CopyMem (
702 &AcpiTableInstance->Rsdt1->OemTableId,
703 &AcpiTableInstance->Fadt1->Header.OemTableId,
704 sizeof (UINT64)
705 );
706 AcpiTableInstance->Rsdt1->OemRevision = AcpiTableInstance->Fadt1->Header.OemRevision;
707 }
708
709 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
710 //
711 // Save a pointer to the table
712 //
713 AcpiTableInstance->Fadt3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)CurrentTableList->Table;
714
715 //
716 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
717 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
718 // vice-versa.
719 //
720 if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
721 AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs3;
722 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
723 } else {
724 Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Facs3;
725 CopyMem (
726 &AcpiTableInstance->Fadt3->XFirmwareCtrl,
727 &Buffer64,
728 sizeof (UINT64)
729 );
730 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
731 }
732
733 if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {
734 AcpiTableInstance->Fadt3->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt3;
735 //
736 // Comment block "the caller installs the tables in "DSDT, FADT" order"
737 // The below comments are also in "the caller installs the tables in "FADT, DSDT" order" comment block.
738 //
739 // The ACPI specification, up to and including revision 5.1 Errata A,
740 // allows the DSDT and X_DSDT fields to be both set in the FADT.
741 // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)
742 // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,
743 // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,
744 // but strangely an exception is 6.0 that has no this requirement.
745 //
746 // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally
747 // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT
748 // to have better compatibility as some OS may have assumption to only consume X_DSDT
749 // field even the DSDT address is < 4G.
750 //
751 Buffer64 = AcpiTableInstance->Fadt3->Dsdt;
752 } else {
753 AcpiTableInstance->Fadt3->Dsdt = 0;
754 Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Dsdt3;
755 }
756
757 CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));
758
759 //
760 // RSDP OEM information is updated to match the FADT OEM information
761 //
762 CopyMem (
763 &AcpiTableInstance->Rsdp3->OemId,
764 &AcpiTableInstance->Fadt3->Header.OemId,
765 6
766 );
767
768 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
769 //
770 // RSDT OEM information is updated to match FADT OEM information.
771 //
772 CopyMem (
773 &AcpiTableInstance->Rsdt3->OemId,
774 &AcpiTableInstance->Fadt3->Header.OemId,
775 6
776 );
777 CopyMem (
778 &AcpiTableInstance->Rsdt3->OemTableId,
779 &AcpiTableInstance->Fadt3->Header.OemTableId,
780 sizeof (UINT64)
781 );
782 AcpiTableInstance->Rsdt3->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;
783 }
784
785 //
786 // XSDT OEM information is updated to match FADT OEM information.
787 //
788 CopyMem (
789 &AcpiTableInstance->Xsdt->OemId,
790 &AcpiTableInstance->Fadt3->Header.OemId,
791 6
792 );
793 CopyMem (
794 &AcpiTableInstance->Xsdt->OemTableId,
795 &AcpiTableInstance->Fadt3->Header.OemTableId,
796 sizeof (UINT64)
797 );
798 AcpiTableInstance->Xsdt->OemRevision = AcpiTableInstance->Fadt3->Header.OemRevision;
799 }
800
801 //
802 // Checksum the table
803 //
804 if (Checksum) {
806 CurrentTableList->Table,
807 CurrentTableList->Table->Length,
808 OFFSET_OF (
810 Checksum
811 )
812 );
813 }
814
815 break;
816
818 //
819 // Check that the table has not been previously added.
820 //
821 if ((((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) && (AcpiTableInstance->Facs1 != NULL)) ||
822 (((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) && (AcpiTableInstance->Facs3 != NULL))
823 )
824 {
825 FreeTableMemory (CurrentTableList);
826 gBS->FreePool (CurrentTableList);
827 return EFI_ACCESS_DENIED;
828 }
829
830 //
831 // FACS is referenced by FADT and is not part of RSDT
832 //
833 AddToRsdt = FALSE;
834
835 //
836 // Add the table to the appropriate table version
837 //
838 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
839 //
840 // Save a pointer to the table
841 //
842 AcpiTableInstance->Facs1 = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)CurrentTableList->Table;
843
844 //
845 // If FADT already exists, update table pointers.
846 //
847 if (AcpiTableInstance->Fadt1 != NULL) {
848 AcpiTableInstance->Fadt1->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs1;
849
850 //
851 // Checksum FADT table
852 //
854 AcpiTableInstance->Fadt1,
855 AcpiTableInstance->Fadt1->Header.Length,
856 OFFSET_OF (
858 Checksum
859 )
860 );
861 }
862 }
863
864 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
865 //
866 // Save a pointer to the table
867 //
868 AcpiTableInstance->Facs3 = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)CurrentTableList->Table;
869
870 //
871 // If FADT already exists, update table pointers.
872 //
873 if (AcpiTableInstance->Fadt3 != NULL) {
874 //
875 // Note: If the FIRMWARE_CTRL is non-zero, then X_FIRMWARE_CTRL must be zero, and
876 // vice-versa.
877 //
878 if ((UINT64)(UINTN)AcpiTableInstance->Facs3 < BASE_4GB) {
879 AcpiTableInstance->Fadt3->FirmwareCtrl = (UINT32)(UINTN)AcpiTableInstance->Facs3;
880 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
881 } else {
882 Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Facs3;
883 CopyMem (
884 &AcpiTableInstance->Fadt3->XFirmwareCtrl,
885 &Buffer64,
886 sizeof (UINT64)
887 );
888 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
889 }
890
891 //
892 // Checksum FADT table
893 //
895 AcpiTableInstance->Fadt3,
896 AcpiTableInstance->Fadt3->Header.Length,
897 OFFSET_OF (
899 Checksum
900 )
901 );
902 }
903 }
904
905 break;
906
908 //
909 // Check that the table has not been previously added.
910 //
911 if ((((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) && (AcpiTableInstance->Dsdt1 != NULL)) ||
912 (((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) && (AcpiTableInstance->Dsdt3 != NULL))
913 )
914 {
915 FreeTableMemory (CurrentTableList);
916 gBS->FreePool (CurrentTableList);
917 return EFI_ACCESS_DENIED;
918 }
919
920 //
921 // DSDT is referenced by FADT and is not part of RSDT
922 //
923 AddToRsdt = FALSE;
924
925 //
926 // Add the table to the appropriate table version
927 //
928 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
929 //
930 // Save a pointer to the table
931 //
932 AcpiTableInstance->Dsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTableList->Table;
933
934 //
935 // If FADT already exists, update table pointers.
936 //
937 if (AcpiTableInstance->Fadt1 != NULL) {
938 AcpiTableInstance->Fadt1->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt1;
939
940 //
941 // Checksum FADT table
942 //
944 AcpiTableInstance->Fadt1,
945 AcpiTableInstance->Fadt1->Header.Length,
946 OFFSET_OF (
948 Checksum
949 )
950 );
951 }
952 }
953
954 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
955 //
956 // Save a pointer to the table
957 //
958 AcpiTableInstance->Dsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTableList->Table;
959
960 //
961 // If FADT already exists, update table pointers.
962 //
963 if (AcpiTableInstance->Fadt3 != NULL) {
964 if ((UINT64)(UINTN)AcpiTableInstance->Dsdt3 < BASE_4GB) {
965 AcpiTableInstance->Fadt3->Dsdt = (UINT32)(UINTN)AcpiTableInstance->Dsdt3;
966 //
967 // Comment block "the caller installs the tables in "FADT, DSDT" order"
968 // The below comments are also in "the caller installs the tables in "DSDT, FADT" order" comment block.
969 //
970 // The ACPI specification, up to and including revision 5.1 Errata A,
971 // allows the DSDT and X_DSDT fields to be both set in the FADT.
972 // (Obviously, this only makes sense if the DSDT address is representable in 4 bytes.)
973 // Starting with 5.1 Errata B, specifically for Mantis 1393 <https://mantis.uefi.org/mantis/view.php?id=1393>,
974 // the spec requires at most one of DSDT and X_DSDT fields to be set to a nonzero value,
975 // but strangely an exception is 6.0 that has no this requirement.
976 //
977 // Here we do not make the DSDT and X_DSDT fields mutual exclusion conditionally
978 // by checking FADT revision, but always set both DSDT and X_DSDT fields in the FADT
979 // to have better compatibility as some OS may have assumption to only consume X_DSDT
980 // field even the DSDT address is < 4G.
981 //
982 Buffer64 = AcpiTableInstance->Fadt3->Dsdt;
983 } else {
984 AcpiTableInstance->Fadt3->Dsdt = 0;
985 Buffer64 = (UINT64)(UINTN)AcpiTableInstance->Dsdt3;
986 }
987
988 CopyMem (&AcpiTableInstance->Fadt3->XDsdt, &Buffer64, sizeof (UINT64));
989
990 //
991 // Checksum FADT table
992 //
994 AcpiTableInstance->Fadt3,
995 AcpiTableInstance->Fadt3->Header.Length,
996 OFFSET_OF (
998 Checksum
999 )
1000 );
1001 }
1002 }
1003
1004 //
1005 // Checksum the table
1006 //
1007 if (Checksum) {
1009 CurrentTableList->Table,
1010 CurrentTableList->Table->Length,
1011 OFFSET_OF (
1013 Checksum
1014 )
1015 );
1016 }
1017
1018 break;
1019
1020 default:
1021 //
1022 // Checksum the table
1023 //
1024 if (Checksum) {
1026 CurrentTableList->Table,
1027 CurrentTableList->Table->Length,
1028 OFFSET_OF (
1030 Checksum
1031 )
1032 );
1033 }
1034
1035 break;
1036 }
1037
1038 //
1039 // Add the table to the current list of tables
1040 //
1041 InsertTailList (&AcpiTableInstance->TableList, &CurrentTableList->Link);
1042
1043 //
1044 // Add the table to RSDT and/or XSDT table entry lists.
1045 //
1046 //
1047 // Add to ACPI 1.0b table tree
1048 //
1049 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1050 if (AddToRsdt) {
1051 //
1052 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1053 //
1054 if (AcpiTableInstance->NumberOfTableEntries1 >= mEfiAcpiMaxNumTables) {
1055 Status = ReallocateAcpiTableBuffer (AcpiTableInstance);
1056 ASSERT_EFI_ERROR (Status);
1057 }
1058
1059 CurrentRsdtEntry = (UINT32 *)
1060 (
1061 (UINT8 *)AcpiTableInstance->Rsdt1 +
1063 AcpiTableInstance->NumberOfTableEntries1 *
1064 sizeof (UINT32)
1065 );
1066
1067 //
1068 // Add entry to the RSDT unless its the FACS or DSDT
1069 //
1070 *CurrentRsdtEntry = (UINT32)(UINTN)CurrentTableList->Table;
1071
1072 //
1073 // Update RSDT length
1074 //
1075 AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);
1076
1077 AcpiTableInstance->NumberOfTableEntries1++;
1078 }
1079 }
1080
1081 //
1082 // Add to ACPI 2.0/3.0 table tree
1083 //
1084 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
1085 if (AddToRsdt) {
1086 //
1087 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1088 //
1089 if (AcpiTableInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {
1090 Status = ReallocateAcpiTableBuffer (AcpiTableInstance);
1091 ASSERT_EFI_ERROR (Status);
1092 }
1093
1094 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1095 //
1096 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1097 // If it becomes necessary to maintain separate table lists, changes will be required.
1098 //
1099 CurrentRsdtEntry = (UINT32 *)
1100 (
1101 (UINT8 *)AcpiTableInstance->Rsdt3 +
1103 AcpiTableInstance->NumberOfTableEntries3 *
1104 sizeof (UINT32)
1105 );
1106
1107 //
1108 // Add entry to the RSDT
1109 //
1110 *CurrentRsdtEntry = (UINT32)(UINTN)CurrentTableList->Table;
1111
1112 //
1113 // Update RSDT length
1114 //
1115 AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
1116 }
1117
1118 //
1119 // This pointer must not be directly dereferenced as the XSDT entries may not
1120 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1121 //
1122 CurrentXsdtEntry = (VOID *)
1123 (
1124 (UINT8 *)AcpiTableInstance->Xsdt +
1126 AcpiTableInstance->NumberOfTableEntries3 *
1127 sizeof (UINT64)
1128 );
1129
1130 //
1131 // Add entry to XSDT, XSDT expects 64 bit pointers, but
1132 // the table pointers in XSDT are not aligned on 8 byte boundary.
1133 //
1134 Buffer64 = (UINT64)(UINTN)CurrentTableList->Table;
1135 CopyMem (
1136 CurrentXsdtEntry,
1137 &Buffer64,
1138 sizeof (UINT64)
1139 );
1140
1141 //
1142 // Update length
1143 //
1144 AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);
1145
1146 AcpiTableInstance->NumberOfTableEntries3++;
1147 }
1148 }
1149
1150 ChecksumCommonTables (AcpiTableInstance);
1151 return EFI_SUCCESS;
1152}
1153
1169 IN UINTN Handle,
1170 IN LIST_ENTRY *TableList,
1171 OUT EFI_ACPI_TABLE_LIST **Table
1172 )
1173{
1174 LIST_ENTRY *CurrentLink;
1175 EFI_ACPI_TABLE_LIST *CurrentTable;
1176
1177 //
1178 // Check for invalid input parameters
1179 //
1180 ASSERT (Table);
1181
1182 //
1183 // Find the table
1184 //
1185 CurrentLink = TableList->ForwardLink;
1186
1187 while (CurrentLink != TableList) {
1188 CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);
1189 if (CurrentTable->Handle == Handle) {
1190 //
1191 // Found handle, so return this table.
1192 //
1193 *Table = CurrentTable;
1194 return EFI_SUCCESS;
1195 }
1196
1197 CurrentLink = CurrentLink->ForwardLink;
1198 }
1199
1200 //
1201 // Table not found
1202 //
1203 return EFI_NOT_FOUND;
1204}
1205
1222 IN OUT EFI_ACPI_TABLE_LIST *Table,
1223 IN OUT UINTN *NumberOfTableEntries,
1224 IN OUT EFI_ACPI_DESCRIPTION_HEADER *Rsdt OPTIONAL,
1225 IN OUT EFI_ACPI_DESCRIPTION_HEADER *Xsdt OPTIONAL
1226 )
1227{
1228 UINT32 *CurrentRsdtEntry;
1229 VOID *CurrentXsdtEntry;
1230 UINT64 CurrentTablePointer64;
1231 UINTN Index;
1232
1233 //
1234 // Check for invalid input parameters
1235 //
1236 ASSERT (Table);
1237 ASSERT (NumberOfTableEntries);
1238 ASSERT (Rsdt || Xsdt);
1239
1240 //
1241 // Find the table entry in the RSDT and XSDT
1242 //
1243 for (Index = 0; Index < *NumberOfTableEntries; Index++) {
1244 //
1245 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1246 // If it becomes necessary to maintain separate table lists, changes will be required.
1247 //
1248 if (Rsdt != NULL) {
1249 CurrentRsdtEntry = (UINT32 *)((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT32));
1250 } else {
1251 CurrentRsdtEntry = NULL;
1252 }
1253
1254 if (Xsdt != NULL) {
1255 //
1256 // This pointer must not be directly dereferenced as the XSDT entries may not
1257 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1258 //
1259 CurrentXsdtEntry = (VOID *)((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + Index * sizeof (UINT64));
1260
1261 //
1262 // Read the entry value out of the XSDT
1263 //
1264 CopyMem (&CurrentTablePointer64, CurrentXsdtEntry, sizeof (UINT64));
1265 } else {
1266 //
1267 // Initialize to NULL
1268 //
1269 CurrentXsdtEntry = 0;
1270 CurrentTablePointer64 = 0;
1271 }
1272
1273 //
1274 // Check if we have found the corresponding entry in both RSDT and XSDT
1275 //
1276 if (((Rsdt == NULL) || (*CurrentRsdtEntry == (UINT32)(UINTN)Table->Table)) &&
1277 ((Xsdt == NULL) || (CurrentTablePointer64 == (UINT64)(UINTN)Table->Table))
1278 )
1279 {
1280 //
1281 // Found entry, so copy all following entries and shrink table
1282 //
1283 if (Rsdt != NULL) {
1284 CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - Index - 1) * sizeof (UINT32));
1285 ZeroMem ((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ((*NumberOfTableEntries - 1) * sizeof (UINT32)), sizeof (UINT32));
1286 Rsdt->Length = Rsdt->Length - sizeof (UINT32);
1287 }
1288
1289 if (Xsdt != NULL) {
1290 CopyMem (CurrentXsdtEntry, ((UINT64 *)CurrentXsdtEntry) + 1, (*NumberOfTableEntries - Index - 1) * sizeof (UINT64));
1291 ZeroMem ((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ((*NumberOfTableEntries - 1) * sizeof (UINT64)), sizeof (UINT64));
1292 Xsdt->Length = Xsdt->Length - sizeof (UINT64);
1293 }
1294
1295 break;
1296 } else if (Index + 1 == *NumberOfTableEntries) {
1297 //
1298 // At the last entry, and table not found
1299 //
1300 return EFI_INVALID_PARAMETER;
1301 }
1302 }
1303
1304 //
1305 // Checksum the tables
1306 //
1307 if (Rsdt != NULL) {
1309 Rsdt,
1310 Rsdt->Length,
1311 OFFSET_OF (
1313 Checksum
1314 )
1315 );
1316 }
1317
1318 if (Xsdt != NULL) {
1320 Xsdt,
1321 Xsdt->Length,
1322 OFFSET_OF (
1324 Checksum
1325 )
1326 );
1327 }
1328
1329 //
1330 // Decrement the number of tables
1331 //
1332 (*NumberOfTableEntries)--;
1333
1334 return EFI_SUCCESS;
1335}
1336
1349 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
1350 IN EFI_ACPI_TABLE_VERSION Version,
1352 )
1353{
1354 UINT32 CurrentTableSignature;
1355 BOOLEAN RemoveFromRsdt;
1356
1357 //
1358 // Check for invalid input parameters
1359 //
1360 ASSERT (AcpiTableInstance);
1361 ASSERT (Table);
1362
1363 //
1364 // Init locals
1365 //
1366 RemoveFromRsdt = TRUE;
1367 //
1368 // Check for Table->Table
1369 //
1370 ASSERT (Table->Table != NULL);
1371 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *)Table->Table)->Signature;
1372
1373 //
1374 // Basic tasks to accomplish delete are:
1375 // Determine removal requirements (in RSDT/XSDT or not)
1376 // Remove entry from RSDT/XSDT
1377 // Remove any table references to the table
1378 // If no one is using the table
1379 // Free the table (removing pointers from private data and tables)
1380 // Remove from list
1381 // Free list structure
1382 //
1383 //
1384 // Determine if this table is in the RSDT or XSDT
1385 //
1386 if ((CurrentTableSignature == EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
1389 )
1390 {
1391 RemoveFromRsdt = FALSE;
1392 }
1393
1394 //
1395 // We don't remove the FADT in the standard way because some
1396 // OS expect the FADT to be early in the table list.
1397 // So we always put it as the first element in the list.
1398 //
1399 if (CurrentTableSignature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
1400 RemoveFromRsdt = FALSE;
1401 }
1402
1403 //
1404 // Remove the table from RSDT and XSDT
1405 //
1406 if (Table->Table != NULL) {
1407 //
1408 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
1409 //
1410 if (Version & EFI_ACPI_TABLE_VERSION_NONE & Table->Version) {
1411 //
1412 // Remove this version from the table
1413 //
1414 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_NONE;
1415 }
1416
1417 if (Version & EFI_ACPI_TABLE_VERSION_1_0B & Table->Version) {
1418 //
1419 // Remove this version from the table
1420 //
1421 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_1_0B;
1422
1423 //
1424 // Remove from Rsdt. We don't care about the return value because it is
1425 // acceptable for the table to not exist in Rsdt.
1426 // We didn't add some tables so we don't remove them.
1427 //
1428 if (RemoveFromRsdt) {
1430 Table,
1431 &AcpiTableInstance->NumberOfTableEntries1,
1432 AcpiTableInstance->Rsdt1,
1433 NULL
1434 );
1435 }
1436 }
1437
1438 if (Version & ACPI_TABLE_VERSION_GTE_2_0 & Table->Version) {
1439 //
1440 // Remove this version from the table
1441 //
1442 Table->Version = Table->Version &~(Version & ACPI_TABLE_VERSION_GTE_2_0);
1443
1444 //
1445 // Remove from Rsdt and Xsdt. We don't care about the return value
1446 // because it is acceptable for the table to not exist in Rsdt/Xsdt.
1447 // We didn't add some tables so we don't remove them.
1448 //
1449 if (RemoveFromRsdt) {
1451 Table,
1452 &AcpiTableInstance->NumberOfTableEntries3,
1453 AcpiTableInstance->Rsdt3,
1454 AcpiTableInstance->Xsdt
1455 );
1456 }
1457 }
1458
1459 //
1460 // Free the table, clean up any dependent tables and our private data pointers.
1461 //
1462 switch (Table->Table->Signature) {
1464 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1465 AcpiTableInstance->Fadt1 = NULL;
1466 }
1467
1468 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
1469 AcpiTableInstance->Fadt3 = NULL;
1470 }
1471
1472 break;
1473
1475 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1476 AcpiTableInstance->Facs1 = NULL;
1477
1478 //
1479 // Update FADT table pointers
1480 //
1481 if (AcpiTableInstance->Fadt1 != NULL) {
1482 AcpiTableInstance->Fadt1->FirmwareCtrl = 0;
1483
1484 //
1485 // Checksum table
1486 //
1488 AcpiTableInstance->Fadt1,
1489 AcpiTableInstance->Fadt1->Header.Length,
1490 OFFSET_OF (
1492 Checksum
1493 )
1494 );
1495 }
1496 }
1497
1498 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
1499 AcpiTableInstance->Facs3 = NULL;
1500
1501 //
1502 // Update FADT table pointers
1503 //
1504 if (AcpiTableInstance->Fadt3 != NULL) {
1505 AcpiTableInstance->Fadt3->FirmwareCtrl = 0;
1506 ZeroMem (&AcpiTableInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
1507
1508 //
1509 // Checksum table
1510 //
1512 AcpiTableInstance->Fadt3,
1513 AcpiTableInstance->Fadt3->Header.Length,
1514 OFFSET_OF (
1516 Checksum
1517 )
1518 );
1519 }
1520 }
1521
1522 break;
1523
1525 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1526 AcpiTableInstance->Dsdt1 = NULL;
1527
1528 //
1529 // Update FADT table pointers
1530 //
1531 if (AcpiTableInstance->Fadt1 != NULL) {
1532 AcpiTableInstance->Fadt1->Dsdt = 0;
1533
1534 //
1535 // Checksum table
1536 //
1538 AcpiTableInstance->Fadt1,
1539 AcpiTableInstance->Fadt1->Header.Length,
1540 OFFSET_OF (
1542 Checksum
1543 )
1544 );
1545 }
1546 }
1547
1548 if ((Version & ACPI_TABLE_VERSION_GTE_2_0) != 0) {
1549 AcpiTableInstance->Dsdt3 = NULL;
1550
1551 //
1552 // Update FADT table pointers
1553 //
1554 if (AcpiTableInstance->Fadt3 != NULL) {
1555 AcpiTableInstance->Fadt3->Dsdt = 0;
1556 ZeroMem (&AcpiTableInstance->Fadt3->XDsdt, sizeof (UINT64));
1557
1558 //
1559 // Checksum table
1560 //
1562 AcpiTableInstance->Fadt3,
1563 AcpiTableInstance->Fadt3->Header.Length,
1564 OFFSET_OF (
1566 Checksum
1567 )
1568 );
1569 }
1570 }
1571
1572 break;
1573
1574 default:
1575 //
1576 // Do nothing
1577 //
1578 break;
1579 }
1580 }
1581
1582 //
1583 // If no version is using this table anymore, remove and free list entry.
1584 //
1585 if (Table->Version == 0) {
1586 //
1587 // Free the Table
1588 //
1589 FreeTableMemory (Table);
1590 RemoveEntryList (&(Table->Link));
1591 gBS->FreePool (Table);
1592 }
1593
1594 //
1595 // Done
1596 //
1597 return EFI_SUCCESS;
1598}
1599
1614 IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
1615 IN EFI_ACPI_TABLE_VERSION Version,
1616 IN UINTN Handle
1617 )
1618{
1619 EFI_ACPI_TABLE_LIST *Table;
1620 EFI_STATUS Status;
1621
1622 Table = (EFI_ACPI_TABLE_LIST *)NULL;
1623
1624 //
1625 // Check for invalid input parameters
1626 //
1627 ASSERT (AcpiTableInstance);
1628
1629 //
1630 // Find the table
1631 //
1632 Status = FindTableByHandle (
1633 Handle,
1634 &AcpiTableInstance->TableList,
1635 &Table
1636 );
1637 if (EFI_ERROR (Status)) {
1638 return EFI_NOT_FOUND;
1639 }
1640
1641 //
1642 // Remove the table
1643 //
1644 Status = DeleteTable (AcpiTableInstance, Version, Table);
1645 if (EFI_ERROR (Status)) {
1646 return EFI_ABORTED;
1647 }
1648
1649 //
1650 // Completed successfully
1651 //
1652 return EFI_SUCCESS;
1653}
1654
1667 IN VOID *Buffer,
1668 IN UINTN Size,
1669 IN UINTN ChecksumOffset
1670 )
1671{
1672 UINT8 Sum;
1673 UINT8 *Ptr;
1674
1675 Sum = 0;
1676 //
1677 // Initialize pointer
1678 //
1679 Ptr = Buffer;
1680
1681 //
1682 // set checksum to 0 first
1683 //
1684 Ptr[ChecksumOffset] = 0;
1685
1686 //
1687 // add all content of buffer
1688 //
1689 while ((Size--) != 0) {
1690 Sum = (UINT8)(Sum + (*Ptr++));
1691 }
1692
1693 //
1694 // set checksum
1695 //
1696 Ptr = Buffer;
1697 Ptr[ChecksumOffset] = (UINT8)(0xff - Sum + 1);
1698
1699 return EFI_SUCCESS;
1700}
1701
1712 IN OUT EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
1713 )
1714{
1715 //
1716 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure
1717 //
1718 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1720 AcpiTableInstance->Rsdp1,
1722 OFFSET_OF (
1724 Checksum
1725 )
1726 );
1727 }
1728
1729 //
1730 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure
1731 //
1733 AcpiTableInstance->Rsdp3,
1735 OFFSET_OF (
1737 Checksum
1738 )
1739 );
1740
1741 //
1742 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
1743 //
1745 AcpiTableInstance->Rsdp3,
1747 OFFSET_OF (
1749 ExtendedChecksum
1750 )
1751 );
1752
1753 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1754 //
1755 // RSDT checksums
1756 //
1758 AcpiTableInstance->Rsdt1,
1759 AcpiTableInstance->Rsdt1->Length,
1760 OFFSET_OF (
1762 Checksum
1763 )
1764 );
1765
1767 AcpiTableInstance->Rsdt3,
1768 AcpiTableInstance->Rsdt3->Length,
1769 OFFSET_OF (
1771 Checksum
1772 )
1773 );
1774 }
1775
1776 //
1777 // XSDT checksum
1778 //
1780 AcpiTableInstance->Xsdt,
1781 AcpiTableInstance->Xsdt->Length,
1782 OFFSET_OF (
1784 Checksum
1785 )
1786 );
1787
1788 return EFI_SUCCESS;
1789}
1790
1803 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
1804 )
1805{
1806 EFI_HOB_GUID_TYPE *GuidHob;
1807 EFI_ACPI_TABLE_VERSION Version;
1810 EFI_ACPI_DESCRIPTION_HEADER *ChildTable;
1811 UINT64 ChildTableAddress;
1812 UINTN Count;
1813 UINTN Index;
1814 UINTN TableKey;
1815 EFI_STATUS Status;
1816 UINTN EntrySize;
1817 UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTableAdress;
1818 VOID *TableToInstall;
1819 EFI_ACPI_SDT_HEADER *Table;
1820 UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
1821
1822 TableKey = 0;
1823 Version = PcdGet32 (PcdAcpiExposedTableVersions);
1824 Status = EFI_SUCCESS;
1825 //
1826 // HOB only contains the ACPI table in 2.0+ format.
1827 //
1828 GuidHob = GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid);
1829 if (GuidHob == NULL) {
1830 return EFI_NOT_FOUND;
1831 }
1832
1833 GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
1834 if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob)) || (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
1835 return EFI_NOT_FOUND;
1836 }
1837
1838 if (GenericHeader->Revision == UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION) {
1839 //
1840 // UNIVERSAL_PAYLOAD_ACPI_TABLE structure is used when Revision equals to UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
1841 //
1842 AcpiTableAdress = (UNIVERSAL_PAYLOAD_ACPI_TABLE *)GET_GUID_HOB_DATA (GuidHob);
1843 if (AcpiTableAdress->Header.Length < UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_ACPI_TABLE, Rsdp)) {
1844 //
1845 // Retrun if can't find the ACPI Info Hob with enough length
1846 //
1847 return EFI_NOT_FOUND;
1848 }
1849
1850 Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)(AcpiTableAdress->Rsdp);
1851
1852 //
1853 // An ACPI-compatible OS must use the XSDT if present.
1854 // It shouldn't happen that XsdtAddress points beyond 4G range in 32-bit environment.
1855 //
1856 ASSERT ((UINTN)Rsdp->XsdtAddress == Rsdp->XsdtAddress);
1857
1858 EntrySize = sizeof (UINT64);
1859 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;
1860 if (Rsdt == NULL) {
1861 //
1862 // XsdtAddress is zero, then we use Rsdt which has 32 bit entry
1863 //
1864 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
1865 EntrySize = sizeof (UINT32);
1866 }
1867
1868 if (Rsdt->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
1869 return EFI_ABORTED;
1870 }
1871
1872 Count = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / EntrySize;
1873
1874 for (Index = 0; Index < Count; Index++) {
1875 ChildTableAddress = 0;
1876 CopyMem (&ChildTableAddress, (UINT8 *)(Rsdt + 1) + EntrySize * Index, EntrySize);
1877 //
1878 // If the address is of UINT64 while this module runs at 32 bits,
1879 // make sure the upper bits are all-zeros.
1880 //
1881 ASSERT (ChildTableAddress == (UINTN)ChildTableAddress);
1882 if (ChildTableAddress != (UINTN)ChildTableAddress) {
1883 Status = EFI_ABORTED;
1884 break;
1885 }
1886
1887 ChildTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)ChildTableAddress;
1888 Status = AddTableToList (AcpiTableInstance, ChildTable, TRUE, Version, TRUE, &TableKey);
1889 if (EFI_ERROR (Status)) {
1890 DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table at 0x%p\n", ChildTable));
1891 ASSERT_EFI_ERROR (Status);
1892 break;
1893 }
1894
1895 if (ChildTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
1896 //
1897 // Add the FACS and DSDT tables if it is not NULL.
1898 //
1899 if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->FirmwareCtrl != 0) {
1900 TableToInstall = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->FirmwareCtrl;
1901 Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);
1902 if (EFI_ERROR (Status)) {
1903 DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table FACS\n"));
1904 ASSERT_EFI_ERROR (Status);
1905 break;
1906 }
1907 }
1908
1909 //
1910 // First check if xDSDT is available, as that is preferred as per
1911 // ACPI Spec 6.5+ Table 5-9 X_DSDT definition
1912 //
1913 if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->XDsdt != 0) {
1914 TableToInstall = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->XDsdt;
1915 } else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->Dsdt != 0) {
1916 TableToInstall = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)ChildTable)->Dsdt;
1917 } else {
1918 DEBUG ((DEBUG_ERROR, "DSDT table not found\n"));
1919 continue;
1920 }
1921
1922 Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);
1923 if (EFI_ERROR (Status)) {
1924 DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table DSDT\n"));
1925 ASSERT_EFI_ERROR (Status);
1926 break;
1927 }
1928 }
1929 }
1930 } else {
1931 return EFI_NOT_FOUND;
1932 }
1933
1934 if (EFI_ERROR (Status)) {
1935 //
1936 // Error happens when trying to add ACPI table to the list.
1937 // Remove all of them from list because at this time, no other tables except from HOB are in the list
1938 //
1939 while (SdtGetAcpiTable (AcpiTableInstance, 0, &Table, &Version, &TableKey) == EFI_SUCCESS) {
1940 RemoveTableFromList (AcpiTableInstance, Version, TableKey);
1941 }
1942 } else {
1943 Status = PublishTables (AcpiTableInstance, Version);
1944 }
1945
1946 ASSERT_EFI_ERROR (Status);
1947 return Status;
1948}
1949
1963 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
1964 EFI_HOB_GUID_TYPE *GuidHob
1965 )
1966{
1967 ACPI_SILICON_HOB *AcpiSiliconHob;
1969 EFI_ACPI_DESCRIPTION_HEADER *SiCommonAcpiTable;
1970 EFI_STATUS Status;
1971 UINT8 *TempBuffer;
1972 UINTN NumOfTblEntries;
1973
1974 DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob\n"));
1975 //
1976 // Initial variable.
1977 //
1978 SiAcpiHobRsdp = NULL;
1979 SiCommonAcpiTable = NULL;
1980 AcpiSiliconHob = GET_GUID_HOB_DATA (GuidHob);
1981 Status = EFI_SUCCESS;
1982 //
1983 // Got RSDP table from ACPI Silicon Hob.
1984 //
1985 SiAcpiHobRsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)(AcpiSiliconHob->Rsdp);
1986 if (SiAcpiHobRsdp == NULL) {
1987 DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to locate RSDP Acpi table!!\n"));
1988 return EFI_NOT_FOUND;
1989 }
1990
1991 DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%lx\n", SiAcpiHobRsdp));
1992 AcpiTableInstance->Rsdp3 = SiAcpiHobRsdp;
1993
1994 if (SiAcpiHobRsdp->RsdtAddress != 0x00000000) {
1995 //
1996 // Initial RSDT.
1997 //
1998 TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->RsdtAddress);
1999 SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
2000 AcpiTableInstance->Rsdt3 = SiCommonAcpiTable;
2001
2002 if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
2003 DEBUG ((DEBUG_ERROR, "RSDT length is incorrect\n"));
2004 return EFI_ABORTED;
2005 }
2006
2007 //
2008 // Calcaue 32bit Acpi table number.
2009 //
2010 NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32);
2011 AcpiTableInstance->NumberOfTableEntries1 = NumOfTblEntries;
2012 DEBUG ((DEBUG_INFO, "32bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
2013 //
2014 // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
2015 //
2016 if (AcpiTableInstance->NumberOfTableEntries1 >= EFI_ACPI_MAX_NUM_TABLES) {
2017 mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries1 + EFI_ACPI_MAX_NUM_TABLES;
2018 DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
2019 }
2020 } else {
2021 //
2022 // Initial XSDT.
2023 //
2024 TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
2025 SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
2026 AcpiTableInstance->Xsdt = SiCommonAcpiTable;
2027
2028 if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
2029 DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
2030 return EFI_ABORTED;
2031 }
2032
2033 //
2034 // Calcaue 64bit Acpi table number.
2035 //
2036 NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
2037 AcpiTableInstance->NumberOfTableEntries3 = NumOfTblEntries;
2038 DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
2039 //
2040 // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
2041 //
2042 if (AcpiTableInstance->NumberOfTableEntries3 >= EFI_ACPI_MAX_NUM_TABLES) {
2043 mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries3 + EFI_ACPI_MAX_NUM_TABLES;
2044 DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
2045 }
2046 }
2047
2048 return Status;
2049}
2050
2063 EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
2064 )
2065{
2066 EFI_STATUS Status;
2067 UINT64 CurrentData;
2068 UINTN TotalSize;
2069 UINTN RsdpTableSize;
2070 UINT8 *Pointer;
2071 EFI_PHYSICAL_ADDRESS PageAddress;
2072 EFI_MEMORY_TYPE AcpiAllocateMemoryType;
2073 EFI_HOB_GUID_TYPE *GuidHob;
2074
2075 //
2076 // Check for invalid input parameters
2077 //
2078 ASSERT (AcpiTableInstance);
2079
2080 //
2081 // If ACPI v1.0b is among the ACPI versions we aim to support, we have to
2082 // ensure that all memory allocations are below 4 GB.
2083 //
2084 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2085 mAcpiTableAllocType = AllocateMaxAddress;
2086 } else {
2087 mAcpiTableAllocType = AllocateAnyPages;
2088 }
2089
2090 InitializeListHead (&AcpiTableInstance->TableList);
2091 AcpiTableInstance->CurrentHandle = 1;
2092
2093 AcpiTableInstance->AcpiTableProtocol.InstallAcpiTable = InstallAcpiTable;
2094 AcpiTableInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;
2095
2096 if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) {
2097 SdtAcpiTableAcpiSdtConstructor (AcpiTableInstance);
2098 }
2099
2100 //
2101 // Check Silicon ACPI Hob.
2102 //
2103 GuidHob = GetFirstGuidHob (&gAcpiTableHobGuid);
2104 if (GuidHob != NULL) {
2105 Status = InstallAcpiTableFromAcpiSiliconHob (AcpiTableInstance, GuidHob);
2106 if (Status == EFI_SUCCESS) {
2107 DEBUG ((DEBUG_INFO, "Installed ACPI Table from AcpiSiliconHob.\n"));
2108 return EFI_SUCCESS;
2109 } else {
2110 DEBUG ((DEBUG_ERROR, "Fail to Installed ACPI Table from AcpiSiliconHob!!\n"));
2111 ASSERT (Status != EFI_SUCCESS);
2112 }
2113 } else {
2114 DEBUG ((DEBUG_INFO, "Fail to locate AcpiSiliconHob!!\n"));
2115 }
2116
2117 //
2118 // Create RSDP table
2119 //
2120 RsdpTableSize = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
2121 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2122 RsdpTableSize += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
2123 }
2124
2125 if (PcdGetBool (PcdNoACPIReclaimMemory)) {
2126 AcpiAllocateMemoryType = EfiACPIMemoryNVS;
2127 } else {
2128 AcpiAllocateMemoryType = EfiACPIReclaimMemory;
2129 }
2130
2131 if (mAcpiTableAllocType != AllocateAnyPages) {
2132 PageAddress = 0xFFFFFFFF;
2133 Status = gBS->AllocatePages (
2134 mAcpiTableAllocType,
2135 AcpiAllocateMemoryType,
2136 EFI_SIZE_TO_PAGES (RsdpTableSize),
2137 &PageAddress
2138 );
2139 } else {
2140 Status = gBS->AllocatePool (
2141 AcpiAllocateMemoryType,
2142 RsdpTableSize,
2143 (VOID **)&Pointer
2144 );
2145 }
2146
2147 if (EFI_ERROR (Status)) {
2148 return EFI_OUT_OF_RESOURCES;
2149 }
2150
2151 if (mAcpiTableAllocType != AllocateAnyPages) {
2152 Pointer = (UINT8 *)(UINTN)PageAddress;
2153 }
2154
2155 ZeroMem (Pointer, RsdpTableSize);
2156
2157 AcpiTableInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Pointer;
2158 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2160 }
2161
2162 AcpiTableInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Pointer;
2163
2164 //
2165 // Create RSDT, XSDT structures
2166 //
2167 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
2168 mEfiAcpiMaxNumTables * sizeof (UINT64);
2169
2170 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2171 TotalSize += sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
2172 mEfiAcpiMaxNumTables * sizeof (UINT32) +
2173 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
2174 mEfiAcpiMaxNumTables * sizeof (UINT32);
2175 }
2176
2177 if (mAcpiTableAllocType != AllocateAnyPages) {
2178 //
2179 // Allocate memory in the lower 32 bit of address range for
2180 // compatibility with ACPI 1.0 OS.
2181 //
2182 // This is done because ACPI 1.0 pointers are 32 bit values.
2183 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
2184 // There is no architectural reason these should be below 4GB, it is purely
2185 // for convenience of implementation that we force memory below 4GB.
2186 //
2187 PageAddress = 0xFFFFFFFF;
2188 Status = gBS->AllocatePages (
2189 mAcpiTableAllocType,
2190 AcpiAllocateMemoryType,
2191 EFI_SIZE_TO_PAGES (TotalSize),
2192 &PageAddress
2193 );
2194 } else {
2195 Status = gBS->AllocatePool (
2196 AcpiAllocateMemoryType,
2197 TotalSize,
2198 (VOID **)&Pointer
2199 );
2200 }
2201
2202 if (EFI_ERROR (Status)) {
2203 if (mAcpiTableAllocType != AllocateAnyPages) {
2204 gBS->FreePages (
2205 (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiTableInstance->Rsdp1,
2206 EFI_SIZE_TO_PAGES (RsdpTableSize)
2207 );
2208 } else {
2209 gBS->FreePool (AcpiTableInstance->Rsdp1);
2210 }
2211
2212 return EFI_OUT_OF_RESOURCES;
2213 }
2214
2215 if (mAcpiTableAllocType != AllocateAnyPages) {
2216 Pointer = (UINT8 *)(UINTN)PageAddress;
2217 }
2218
2219 ZeroMem (Pointer, TotalSize);
2220
2221 AcpiTableInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
2222 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2223 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
2224 AcpiTableInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
2225 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
2226 }
2227
2228 AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)Pointer;
2229
2230 //
2231 // Initialize RSDP
2232 //
2233 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2235 CopyMem (&AcpiTableInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));
2236 CopyMem (AcpiTableInstance->Rsdp1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp1->OemId));
2237 AcpiTableInstance->Rsdp1->Reserved = EFI_ACPI_RESERVED_BYTE;
2238 AcpiTableInstance->Rsdp1->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt1;
2239 }
2240
2242 CopyMem (&AcpiTableInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));
2243 CopyMem (AcpiTableInstance->Rsdp3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdp3->OemId));
2244 AcpiTableInstance->Rsdp3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;
2245 AcpiTableInstance->Rsdp3->Length = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
2246 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2247 AcpiTableInstance->Rsdp3->RsdtAddress = (UINT32)(UINTN)AcpiTableInstance->Rsdt3;
2248 }
2249
2250 CurrentData = (UINT64)(UINTN)AcpiTableInstance->Xsdt;
2251 CopyMem (&AcpiTableInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));
2252 SetMem (AcpiTableInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);
2253
2254 if ((PcdGet32 (PcdAcpiExposedTableVersions) & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
2255 //
2256 // Initialize Rsdt
2257 //
2258 // Note that we "reserve" one entry for the FADT so it can always be
2259 // at the beginning of the list of tables. Some OS don't seem
2260 // to find it correctly if it is too far down the list.
2261 //
2262 AcpiTableInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
2263 AcpiTableInstance->Rsdt1->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
2264 AcpiTableInstance->Rsdt1->Revision = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
2265 CopyMem (AcpiTableInstance->Rsdt1->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt1->OemId));
2266 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
2267 CopyMem (&AcpiTableInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));
2268 AcpiTableInstance->Rsdt1->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
2269 AcpiTableInstance->Rsdt1->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
2270 AcpiTableInstance->Rsdt1->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
2271 //
2272 // We always reserve first one for FADT
2273 //
2274 AcpiTableInstance->NumberOfTableEntries1 = 1;
2275 AcpiTableInstance->Rsdt1->Length = AcpiTableInstance->Rsdt1->Length + sizeof (UINT32);
2276
2277 AcpiTableInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
2278 AcpiTableInstance->Rsdt3->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
2279 AcpiTableInstance->Rsdt3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
2280 CopyMem (AcpiTableInstance->Rsdt3->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Rsdt3->OemId));
2281 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
2282 CopyMem (&AcpiTableInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));
2283 AcpiTableInstance->Rsdt3->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
2284 AcpiTableInstance->Rsdt3->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
2285 AcpiTableInstance->Rsdt3->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
2286 //
2287 // We always reserve first one for FADT
2288 //
2289 AcpiTableInstance->Rsdt3->Length = AcpiTableInstance->Rsdt3->Length + sizeof (UINT32);
2290 }
2291
2292 AcpiTableInstance->NumberOfTableEntries3 = 1;
2293
2294 //
2295 // Initialize Xsdt
2296 //
2297 AcpiTableInstance->Xsdt->Signature = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
2298 AcpiTableInstance->Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
2299 AcpiTableInstance->Xsdt->Revision = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION;
2300 CopyMem (AcpiTableInstance->Xsdt->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (AcpiTableInstance->Xsdt->OemId));
2301 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
2302 CopyMem (&AcpiTableInstance->Xsdt->OemTableId, &CurrentData, sizeof (UINT64));
2303 AcpiTableInstance->Xsdt->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
2304 AcpiTableInstance->Xsdt->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
2305 AcpiTableInstance->Xsdt->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
2306 //
2307 // We always reserve first one for FADT
2308 //
2309 AcpiTableInstance->Xsdt->Length = AcpiTableInstance->Xsdt->Length + sizeof (UINT64);
2310
2311 ChecksumCommonTables (AcpiTableInstance);
2312
2313 InstallAcpiTableFromHob (AcpiTableInstance);
2314
2315 //
2316 // Completed successfully
2317 //
2318 return EFI_SUCCESS;
2319}
UINT64 UINTN
#define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
Definition: Acpi10.h:637
#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi10.h:652
#define EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi10.h:642
#define EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi10.h:632
#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
Definition: Acpi10.h:418
#define EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
Definition: Acpi10.h:622
#define EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi20.h:460
#define EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
Definition: Acpi20.h:475
#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION
Definition: Acpi30.h:157
#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi30.h:618
#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi30.h:668
#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
Definition: Acpi30.h:633
#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi30.h:643
#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE
Definition: Acpi30.h:608
#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION
Definition: Acpi30.h:146
#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi30.h:628
#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION
ACPISpec (Revision 3.0b) says current value is 2.
Definition: Acpi30.h:126
#define EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE
Definition: Acpi40.h:1290
VOID SdtAcpiTableAcpiSdtConstructor(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance)
Definition: AcpiSdt.c:1091
VOID SdtNotifyAcpiList(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, IN EFI_ACPI_TABLE_VERSION Version, IN UINTN Handle)
Definition: AcpiSdt.c:150
EFI_STATUS SdtGetAcpiTable(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, IN UINTN Index, OUT EFI_ACPI_SDT_HEADER **Table, OUT EFI_ACPI_TABLE_VERSION *Version, OUT UINTN *TableKey)
Definition: AcpiSdt.c:218
EFI_STATUS ChecksumCommonTables(IN OUT EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance)
EFI_STATUS InstallAcpiTableFromAcpiSiliconHob(EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, EFI_HOB_GUID_TYPE *GuidHob)
EFI_STATUS FindTableByHandle(IN UINTN Handle, IN LIST_ENTRY *TableList, OUT EFI_ACPI_TABLE_LIST **Table)
EFI_STATUS AddTableToList(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, IN VOID *Table, IN BOOLEAN Checksum, IN EFI_ACPI_TABLE_VERSION Version, IN BOOLEAN IsFromHob, OUT UINTN *Handle)
EFI_STATUS RemoveTableFromList(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, IN EFI_ACPI_TABLE_VERSION Version, IN UINTN Handle)
EFI_STATUS ReallocateAcpiTableBuffer(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance)
EFI_STATUS EFIAPI InstallAcpiTable(IN EFI_ACPI_TABLE_PROTOCOL *This, IN VOID *AcpiTableBuffer, IN UINTN AcpiTableBufferSize, OUT UINTN *TableKey)
EFI_STATUS EFIAPI UninstallAcpiTable(IN EFI_ACPI_TABLE_PROTOCOL *This, IN UINTN TableKey)
EFI_STATUS DeleteTable(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, IN EFI_ACPI_TABLE_VERSION Version, IN OUT EFI_ACPI_TABLE_LIST *Table)
EFI_STATUS RemoveTableFromRsdt(IN OUT EFI_ACPI_TABLE_LIST *Table, IN OUT UINTN *NumberOfTableEntries, IN OUT EFI_ACPI_DESCRIPTION_HEADER *Rsdt OPTIONAL, IN OUT EFI_ACPI_DESCRIPTION_HEADER *Xsdt OPTIONAL)
EFI_STATUS EFIAPI PublishTables(IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance, IN EFI_ACPI_TABLE_VERSION Version)
EFI_STATUS AcpiTableAcpiTableConstructor(EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance)
EFI_STATUS InstallAcpiTableFromHob(EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance)
EFI_STATUS AcpiPlatformChecksum(IN VOID *Buffer, IN UINTN Size, IN UINTN ChecksumOffset)
STATIC VOID FreeTableMemory(EFI_ACPI_TABLE_LIST *TableEntry)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_MEMORY_TYPE
@ EfiACPIMemoryNVS
@ EfiACPIReclaimMemory
EFI_ALLOCATE_TYPE
Definition: UefiSpec.h:29
@ AllocateMaxAddress
Definition: UefiSpec.h:38
@ AllocateAnyPages
Definition: UefiSpec.h:33
#define UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD(TYPE, Field)