4 Copyright (c) 2013-2015 Intel Corporation.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Protocol/AcpiTable.h>
17 #include <IndustryStandard/Pci22.h>
18 #include "AcpiPlatform.h"
23 EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea
;
24 EFI_ACPI_SDT_PROTOCOL
*mAcpiSdt
;
26 EFI_ACPI_HANDLE mDsdtHandle
= NULL
;
30 LocateSupportProtocol (
31 IN EFI_GUID
*Protocol
,
39 Locate the first instance of a protocol. If the protocol requested is an
40 FV protocol, then it will return the first FV that contains the ACPI table
45 Protocol The protocol to find.
46 Instance Return pointer to the first instance of the protocol
50 EFI_SUCCESS The function completed successfully.
51 EFI_NOT_FOUND The protocol could not be located.
52 EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
57 EFI_HANDLE
*HandleBuffer
;
58 UINTN NumberOfHandles
;
59 EFI_FV_FILETYPE FileType
;
61 EFI_FV_FILE_ATTRIBUTES Attributes
;
70 Status
= gBS
->LocateHandleBuffer (
77 if (EFI_ERROR (Status
)) {
80 // Defined errors at this time are not found and out of resources.
88 // Looking for FV with ACPI storage file
91 for (i
= 0; i
< NumberOfHandles
; i
++) {
93 // Get the protocol on this handle
94 // This should not fail because of LocateHandleBuffer
96 Status
= gBS
->HandleProtocol (
101 ASSERT_EFI_ERROR (Status
);
105 // Not looking for the FV protocol, so find the first instance of the
106 // protocol. There should not be any errors because our handle buffer
107 // should always contain at least one or LocateHandleBuffer would have
108 // returned not found.
114 // See if it has the ACPI storage file
117 Status
= ((EFI_FIRMWARE_VOLUME2_PROTOCOL
*) (*Instance
))->ReadFile (*Instance
,
118 (EFI_GUID
*)PcdGetPtr (PcdAcpiTableStorageFile
),
127 // If we found it, then we are done
129 if (Status
== EFI_SUCCESS
) {
135 // Our exit status is determined by the success of the previous operations
136 // If the protocol was found, Instance already points to it.
140 // Free any allocated buffers
142 gBS
->FreePool (HandleBuffer
);
150 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
,
151 IN OUT EFI_ACPI_TABLE_VERSION
*Version
157 Update the DSDT table
161 Table - The table to be set
162 Version - Version to publish
178 // Loop through the ASL looking for values that we must fix up.
180 CurrPtr
= (UINT8
*) TableHeader
;
181 for (DsdtPointer
= CurrPtr
;
182 DsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
);
186 Signature
= (UINT32
*) DsdtPointer
;
187 switch (*Signature
) {
189 // MNVS operation region
191 case (SIGNATURE_32 ('M', 'N', 'V', 'S')):
193 // Conditional match. For Region Objects, the Operator will always be the
194 // byte immediately before the specific name. Therefore, subtract 1 to check
197 Operation
= DsdtPointer
- 1;
198 if (*Operation
== AML_OPREGION_OP
) {
199 Address
= (UINT32
*) (DsdtPointer
+ 6);
200 *Address
= (UINT32
) (UINTN
) mGlobalNvsArea
.Area
;
201 Size
= (UINT16
*) (DsdtPointer
+ 11);
202 *Size
= sizeof (EFI_GLOBAL_NVS_AREA
);
207 // Update processor PBLK register I/O base address
209 case (SIGNATURE_32 ('P', 'R', 'I', 'O')):
211 // Conditional match. Update the following ASL code:
212 // Processor (CPU0, 0x01, 0x4F495250, 0x06) {}
213 // The 3rd parameter will be updated to the actual PBLK I/O base address.
216 Operation
= DsdtPointer
- 8;
217 if ((*Operation
== AML_EXT_OP
) && (*(Operation
+ 1) == AML_EXT_PROCESSOR_OP
)) {
218 *(UINT32
*)DsdtPointer
= PcdGet16(PcdPmbaIoBaseAddress
);
230 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
,
231 IN OUT EFI_ACPI_TABLE_VERSION
*Version
237 Update the processors information in the APIC table
241 Table - The table to be set
242 Version - Version to publish
251 EFI_MP_SERVICES_PROTOCOL
*MpService
;
257 UINTN NumberOfEnabledCPUs
;
259 EFI_PROCESSOR_INFORMATION MpContext
;
260 ACPI_APIC_STRUCTURE_PTR
*ApicPtr
;
265 // Find the MP Protocol. This is an MP platform, so MP protocol must be
268 Status
= gBS
->LocateProtocol (
269 &gEfiMpServiceProtocolGuid
,
273 if (EFI_ERROR (Status
)) {
275 // Failed to get MP information, doesn't publish the invalid table
277 *Version
= EFI_ACPI_TABLE_VERSION_NONE
;
282 // Determine the number of processors
284 MpService
->GetNumberOfProcessors (
290 CurrPtr
= (UINT8
*) &(TableHeader
[1]);
291 CurrPtr
= CurrPtr
+ 8; // Size of Local APIC Address & Flag
292 EndPtr
= (UINT8
*) TableHeader
;
293 EndPtr
= EndPtr
+ TableHeader
->Length
;
295 while (CurrPtr
< EndPtr
) {
297 ApicPtr
= (ACPI_APIC_STRUCTURE_PTR
*) CurrPtr
;
298 switch (ApicPtr
->AcpiApicCommon
.Type
) {
300 case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC
:
301 BufferSize
= sizeof (EFI_PROCESSOR_INFORMATION
);
302 ApicPtr
->AcpiLocalApic
.Flags
= 0;
303 ApicPtr
->AcpiLocalApic
.ApicId
= 0;
304 Status
= MpService
->GetProcessorInfo (
310 if (!EFI_ERROR (Status
)) {
311 if (MpContext
.StatusFlag
& PROCESSOR_ENABLED_BIT
) {
312 ApicPtr
->AcpiLocalApic
.Flags
= EFI_ACPI_3_0_LOCAL_APIC_ENABLED
;
314 ApicPtr
->AcpiLocalApic
.ApicId
= (UINT8
)MpContext
.ProcessorId
;
319 case EFI_ACPI_1_0_IO_APIC
:
321 // IO APIC entries can be patched here
323 if (CurrIoApic
== 0) {
325 // Update SOC internel IOAPIC base
327 ApicPtr
->AcpiIoApic
.IoApicId
= PcdGet8 (PcdIoApicSettingIoApicId
);
328 ApicPtr
->AcpiIoApic
.IoApicAddress
= (UINT32
)PcdGet64(PcdIoApicBaseAddress
);
329 ApicPtr
->AcpiIoApic
.GlobalSystemInterruptBase
= 0;
332 // Porting is required to update other IOAPIC entries if available
342 CurrPtr
= CurrPtr
+ ApicPtr
->AcpiApicCommon
.Length
;
348 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
,
349 IN OUT EFI_ACPI_TABLE_VERSION
*Version
355 Set the correct table revision upon the setup value
359 Table - The table to be set
360 Version - Version to publish
369 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*FadtHeader1
;
370 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*FadtHeader2
;
371 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*FadtHeader3
;
372 EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE
*AllocationStructurePtr
;
374 if (TableHeader
!= NULL
&& Version
!= NULL
) {
376 *Version
= EFI_ACPI_TABLE_VERSION_1_0B
| EFI_ACPI_TABLE_VERSION_2_0
| EFI_ACPI_TABLE_VERSION_3_0
;
378 // Here we use all 3.0 signature because all version use same signature if they supported
380 switch (TableHeader
->Signature
) {
382 // "APIC" Multiple APIC Description Table
384 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
:
385 ApicTableUpdate (TableHeader
, Version
);
388 // "DSDT" Differentiated System Description Table
390 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
391 DsdtTableUpdate (TableHeader
, Version
);
395 // "FACP" Fixed ACPI Description Table (FADT)
397 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
398 *Version
= EFI_ACPI_TABLE_VERSION_NONE
;
399 if (TableHeader
->Revision
== EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
400 *Version
= EFI_ACPI_TABLE_VERSION_1_0B
;
401 FadtHeader1
= (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE
*) TableHeader
;
402 FadtHeader1
->SmiCmd
= PcdGet16(PcdSmmActivationPort
);
403 FadtHeader1
->Pm1aEvtBlk
= PcdGet16(PcdPm1blkIoBaseAddress
);
404 FadtHeader1
->Pm1aCntBlk
= PcdGet16(PcdPm1blkIoBaseAddress
) + R_QNC_PM1BLK_PM1C
;
405 FadtHeader1
->PmTmrBlk
= PcdGet16(PcdPm1blkIoBaseAddress
) + R_QNC_PM1BLK_PM1T
;
406 FadtHeader1
->Gpe0Blk
= PcdGet16(PcdGpe0blkIoBaseAddress
);
407 } else if (TableHeader
->Revision
== EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
408 *Version
= EFI_ACPI_TABLE_VERSION_2_0
;
409 FadtHeader2
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*) TableHeader
;
410 FadtHeader2
->SmiCmd
= PcdGet16(PcdSmmActivationPort
);
411 FadtHeader2
->Pm1aEvtBlk
= PcdGet16(PcdPm1blkIoBaseAddress
);
412 FadtHeader2
->Pm1aCntBlk
= PcdGet16(PcdPm1blkIoBaseAddress
) + R_QNC_PM1BLK_PM1C
;
413 FadtHeader2
->PmTmrBlk
= PcdGet16(PcdPm1blkIoBaseAddress
) + R_QNC_PM1BLK_PM1T
;
414 FadtHeader2
->Gpe0Blk
= PcdGet16(PcdGpe0blkIoBaseAddress
);
415 FadtHeader2
->XPm1aEvtBlk
.Address
= FadtHeader2
->Pm1aEvtBlk
;
416 FadtHeader2
->XPm1aCntBlk
.Address
= FadtHeader2
->Pm1aCntBlk
;
417 FadtHeader2
->XPmTmrBlk
.Address
= FadtHeader2
->PmTmrBlk
;
418 FadtHeader2
->XGpe0Blk
.Address
= FadtHeader2
->Gpe0Blk
;
419 } else if (TableHeader
->Revision
== EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
) {
420 *Version
= EFI_ACPI_TABLE_VERSION_3_0
;
421 FadtHeader3
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) TableHeader
;
422 FadtHeader3
->SmiCmd
= PcdGet16(PcdSmmActivationPort
);
423 FadtHeader3
->Pm1aEvtBlk
= PcdGet16(PcdPm1blkIoBaseAddress
);
424 FadtHeader3
->Pm1aCntBlk
= PcdGet16(PcdPm1blkIoBaseAddress
) + R_QNC_PM1BLK_PM1C
;
425 FadtHeader3
->PmTmrBlk
= PcdGet16(PcdPm1blkIoBaseAddress
) + R_QNC_PM1BLK_PM1T
;
426 FadtHeader3
->Gpe0Blk
= PcdGet16(PcdGpe0blkIoBaseAddress
);
427 FadtHeader3
->XPm1aEvtBlk
.Address
= FadtHeader3
->Pm1aEvtBlk
;
428 FadtHeader3
->XPm1aCntBlk
.Address
= FadtHeader3
->Pm1aCntBlk
;
429 FadtHeader3
->XPmTmrBlk
.Address
= FadtHeader3
->PmTmrBlk
;
430 FadtHeader3
->XGpe0Blk
.Address
= FadtHeader3
->Gpe0Blk
;
434 // "FACS" Firmware ACPI Control Structure
436 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
:
439 // "SSDT" Secondary System Description Table
441 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
444 // "HPET" IA-PC High Precision Event Timer Table
446 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE
:
448 // If HPET is disabled in setup, don't publish the table.
450 if (mGlobalNvsArea
.Area
->HpetEnable
== 0) {
451 *Version
= EFI_ACPI_TABLE_VERSION_NONE
;
453 ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*) TableHeader
)->BaseAddressLower32Bit
.Address
454 = PcdGet64 (PcdHpetBaseAddress
);
457 // "SPCR" Serial Port Concole Redirection Table
459 case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE
:
462 // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
464 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE
:
465 AllocationStructurePtr
= (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE
*)
466 ((UINT8
*)TableHeader
+ sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER
));
467 AllocationStructurePtr
->BaseAddress
= PcdGet64(PcdPciExpressBaseAddress
);
469 // Lakeport platform doesn't support the following table
472 // "ECDT" Embedded Controller Boot Resources Table
474 case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE:
477 // "PSDT" Persistent System Description Table
479 case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
482 // "SBST" Smart Battery Specification Table
484 case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE:
487 // "SLIT" System Locality Information Table
489 case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE:
492 // "SRAT" Static Resource Affinity Table
494 case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE:
497 // "XSDT" Extended System Description Table
499 case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
502 // "BOOT" MS Simple Boot Spec
504 case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE:
507 // "CPEP" Corrected Platform Error Polling Table
509 case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE:
512 // "DBGP" MS Debug Port Spec
514 case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE:
517 // "ETDT" Event Timer Description Table
519 case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE:
522 // "SPMI" Server Platform Management Interface Table
524 case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE:
527 // "TCPA" Trusted Computing Platform Alliance Capabilities Table
529 case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE:
540 // Entrypoint of Acpi Platform driver
547 // EFI_OUT_OF_RESOURCES
551 AcpiPlatformEntryPoint (
552 IN EFI_HANDLE ImageHandle
,
553 IN EFI_SYSTEM_TABLE
*SystemTable
557 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
558 EFI_FIRMWARE_VOLUME2_PROTOCOL
*FwVol
;
560 EFI_ACPI_COMMON_HEADER
*CurrentTable
;
564 EFI_ACPI_TABLE_VERSION Version
;
565 QNC_DEVICE_ENABLES QNCDeviceEnables
;
568 PCI_DEVICE_INFO
*PciDeviceInfo
;
569 EFI_ACPI_HANDLE PciRootHandle
;
572 PCI_DEVICE_SETTING
*mConfigData
;
574 DEBUG((DEBUG_INFO
, "ACPI Platform start...\n"));
580 QNCDeviceEnables
.Uint32
= PcdGet32 (PcdDeviceEnables
);
583 // Initialize the EFI Driver Library
586 ASSERT (sizeof (EFI_GLOBAL_NVS_AREA
) == 512);
588 Status
= gBS
->AllocatePool (
590 sizeof (EFI_GLOBAL_NVS_AREA
),
591 (VOID
**)&mGlobalNvsArea
.Area
595 Status
= gBS
->InstallProtocolInterface (
597 &gEfiGlobalNvsAreaProtocolGuid
,
598 EFI_NATIVE_INTERFACE
,
602 ASSERT_EFI_ERROR (Status
);
603 if (!EFI_ERROR (Status
)) {
606 sizeof (EFI_GLOBAL_NVS_AREA
),
612 // Initialize the data. Eventually, this will be controlled by setup options.
614 mGlobalNvsArea
.Area
->HpetEnable
= PcdGetBool (PcdHpetEnable
);
615 mGlobalNvsArea
.Area
->Pm1blkIoBaseAddress
= PcdGet16(PcdPm1blkIoBaseAddress
);
616 mGlobalNvsArea
.Area
->PmbaIoBaseAddress
= PcdGet16(PcdPmbaIoBaseAddress
);
617 mGlobalNvsArea
.Area
->Gpe0blkIoBaseAddress
= PcdGet16(PcdGpe0blkIoBaseAddress
);
618 mGlobalNvsArea
.Area
->GbaIoBaseAddress
= PcdGet16(PcdGbaIoBaseAddress
);
619 mGlobalNvsArea
.Area
->SmbaIoBaseAddress
= PcdGet16(PcdSmbaIoBaseAddress
);
620 mGlobalNvsArea
.Area
->WdtbaIoBaseAddress
= PcdGet16(PcdWdtbaIoBaseAddress
);
621 mGlobalNvsArea
.Area
->HpetBaseAddress
= (UINT32
)PcdGet64(PcdHpetBaseAddress
);
622 mGlobalNvsArea
.Area
->HpetSize
= (UINT32
)PcdGet64(PcdHpetSize
);
623 mGlobalNvsArea
.Area
->PciExpressBaseAddress
= (UINT32
)PcdGet64(PcdPciExpressBaseAddress
);
624 mGlobalNvsArea
.Area
->PciExpressSize
= (UINT32
)PcdGet64(PcdPciExpressSize
);
625 mGlobalNvsArea
.Area
->RcbaMmioBaseAddress
= (UINT32
)PcdGet64(PcdRcbaMmioBaseAddress
);
626 mGlobalNvsArea
.Area
->RcbaMmioSize
= (UINT32
)PcdGet64(PcdRcbaMmioSize
);
627 mGlobalNvsArea
.Area
->IoApicBaseAddress
= (UINT32
)PcdGet64(PcdIoApicBaseAddress
);
628 mGlobalNvsArea
.Area
->IoApicSize
= (UINT32
)PcdGet64(PcdIoApicSize
);
629 mGlobalNvsArea
.Area
->TpmPresent
= (UINT32
)(FALSE
);
630 mGlobalNvsArea
.Area
->DBG2Present
= (UINT32
)(FALSE
);
631 mGlobalNvsArea
.Area
->PlatformType
= (UINT32
)PcdGet16 (PcdPlatformType
);
634 // Configure platform IO expander I2C Slave Address.
636 if (mGlobalNvsArea
.Area
->PlatformType
== Galileo
) {
637 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL
, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO
)) {
638 mGlobalNvsArea
.Area
->AlternateSla
= FALSE
;
640 mGlobalNvsArea
.Area
->AlternateSla
= TRUE
;
645 // Find the AcpiTable protocol
647 Status
= gBS
->LocateProtocol (&gEfiAcpiTableProtocolGuid
, NULL
, (VOID
**)&AcpiTable
);
648 if (EFI_ERROR (Status
)) {
653 // Initialize MADT table
655 Status
= MadtTableInitialize (&CurrentTable
, &Size
);
656 ASSERT_EFI_ERROR (Status
);
658 // Perform any table specific updates.
660 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTable
, &Version
);
663 // Update the check sum
664 // It needs to be zeroed before the checksum calculation
666 ((EFI_ACPI_SDT_HEADER
*)CurrentTable
)->Checksum
= 0;
667 ((EFI_ACPI_SDT_HEADER
*)CurrentTable
)->Checksum
=
668 CalculateCheckSum8 ((VOID
*)CurrentTable
, CurrentTable
->Length
);
674 Status
= AcpiTable
->InstallAcpiTable (
677 CurrentTable
->Length
,
680 ASSERT_EFI_ERROR (Status
);
684 // Init Pci Device PRT PRW information structure from PCD
686 mConfigData
= (PCI_DEVICE_SETTING
*)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING
));
687 ASSERT_EFI_ERROR (mConfigData
);
688 InitPciDeviceInfoStructure (mConfigData
);
690 // Get the Acpi SDT protocol for manipulation on acpi table
692 Status
= gBS
->LocateProtocol (&gEfiAcpiSdtProtocolGuid
, NULL
, (VOID
**)&mAcpiSdt
);
693 ASSERT_EFI_ERROR (Status
);
695 // Locate the firmware volume protocol
697 Status
= LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid
, (VOID
**)&FwVol
, 1);
698 if (EFI_ERROR (Status
)) {
702 // Read tables from the storage file.
705 while (Status
== EFI_SUCCESS
) {
707 Status
= FwVol
->ReadSection (
709 (EFI_GUID
*)PcdGetPtr (PcdAcpiTableStorageFile
),
712 (VOID
**)&CurrentTable
,
717 if (!EFI_ERROR(Status
)) {
719 // Perform any table specific updates.
721 AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTable
, &Version
);
724 // Update the check sum
725 // It needs to be zeroed before the checksum calculation
727 ((EFI_ACPI_SDT_HEADER
*)CurrentTable
)->Checksum
= 0;
728 ((EFI_ACPI_SDT_HEADER
*)CurrentTable
)->Checksum
=
729 CalculateCheckSum8 ((VOID
*)CurrentTable
, CurrentTable
->Length
);
735 Status
= AcpiTable
->InstallAcpiTable (
738 ((EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTable
)->Length
,
741 if (EFI_ERROR(Status
)) {
745 // If this table is the DSDT table, then update the _PRT and _PRW based on
746 // the settings from pcds
748 if (CurrentTable
->Signature
== EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
) {
750 // Create the root handle for DSDT table
752 Status
= mAcpiSdt
->OpenSdt (TableHandle
, &mDsdtHandle
);
753 ASSERT_EFI_ERROR (Status
);
755 PciRootHandle
= NULL
;
756 PciRootHandle
= SdtGetRootBridgeHandle (mAcpiSdt
, mDsdtHandle
);
757 ASSERT (PciRootHandle
!= NULL
);
759 PciDeviceInfo
= NULL
;
760 for (Index
= 0; Index
< mConfigData
->PciDeviceInfoNumber
; Index
++) {
761 PciDeviceInfo
= &(mConfigData
->PciDeviceInfo
[Index
]);
764 // Check whether this is a valid item
766 if ((PciDeviceInfo
->BridgeAddress
!= 0xFFFFFFFF) && (PciDeviceInfo
->DeviceAddress
!= 0xFFFFFFFF)) {
768 //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));
773 SdtCheckPciDeviceInfoChanged (PciDeviceInfo
, &UpdatePRT
, &UpdatePRW
);
775 // Check whether there is any valid pci routing item
779 // Update the pci routing information
781 //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
782 SdtUpdatePciRouting (mAcpiSdt
, PciRootHandle
, PciDeviceInfo
);
785 // Check whether there is any valid pci routing item
789 // Update the pci wakeup information
791 //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
792 SdtUpdatePowerWake (mAcpiSdt
, PciRootHandle
, PciDeviceInfo
);
796 Status
= mAcpiSdt
->Close (PciRootHandle
);
797 ASSERT_EFI_ERROR (Status
);
799 // Mark the root handle as modified , let SDT protocol recaculate the checksum
801 ((EFI_AML_HANDLE
*)mDsdtHandle
)->Modified
= TRUE
;
802 Status
= mAcpiSdt
->Close (mDsdtHandle
);
803 ASSERT_EFI_ERROR (Status
);
806 // Increment the instance
813 gBS
->FreePool (mConfigData
);