| /** @file | |
| ACPI Platform Driver | |
| Copyright (c) 2013-2016 Intel Corporation. | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include <Protocol/AcpiTable.h> | |
| #include <IndustryStandard/Pci22.h> | |
| #include "AcpiPlatform.h" | |
| // | |
| // Global Variable | |
| // | |
| EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; | |
| EFI_ACPI_SDT_PROTOCOL *mAcpiSdt; | |
| EFI_ACPI_HANDLE mDsdtHandle = NULL; | |
| EFI_STATUS | |
| LocateSupportProtocol ( | |
| IN EFI_GUID *Protocol, | |
| OUT VOID **Instance, | |
| IN UINT32 Type | |
| ) | |
| /*++ | |
| Routine Description: | |
| Locate the first instance of a protocol. If the protocol requested is an | |
| FV protocol, then it will return the first FV that contains the ACPI table | |
| storage file. | |
| Arguments: | |
| Protocol The protocol to find. | |
| Instance Return pointer to the first instance of the protocol | |
| Returns: | |
| EFI_SUCCESS The function completed successfully. | |
| EFI_NOT_FOUND The protocol could not be located. | |
| EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. | |
| --*/ | |
| { | |
| EFI_STATUS Status; | |
| EFI_HANDLE *HandleBuffer; | |
| UINTN NumberOfHandles; | |
| EFI_FV_FILETYPE FileType; | |
| UINT32 FvStatus; | |
| EFI_FV_FILE_ATTRIBUTES Attributes; | |
| UINTN Size; | |
| UINTN i; | |
| FvStatus = 0; | |
| // | |
| // Locate protocol. | |
| // | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| Protocol, | |
| NULL, | |
| &NumberOfHandles, | |
| &HandleBuffer | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| // | |
| // Defined errors at this time are not found and out of resources. | |
| // | |
| return Status; | |
| } | |
| // | |
| // Looking for FV with ACPI storage file | |
| // | |
| for (i = 0; i < NumberOfHandles; i++) { | |
| // | |
| // Get the protocol on this handle | |
| // This should not fail because of LocateHandleBuffer | |
| // | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[i], | |
| Protocol, | |
| Instance | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| if (!Type) { | |
| // | |
| // Not looking for the FV protocol, so find the first instance of the | |
| // protocol. There should not be any errors because our handle buffer | |
| // should always contain at least one or LocateHandleBuffer would have | |
| // returned not found. | |
| // | |
| break; | |
| } | |
| // | |
| // See if it has the ACPI storage file | |
| // | |
| Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL*) (*Instance))->ReadFile (*Instance, | |
| (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), | |
| NULL, | |
| &Size, | |
| &FileType, | |
| &Attributes, | |
| &FvStatus | |
| ); | |
| // | |
| // If we found it, then we are done | |
| // | |
| if (Status == EFI_SUCCESS) { | |
| break; | |
| } | |
| } | |
| // | |
| // Our exit status is determined by the success of the previous operations | |
| // If the protocol was found, Instance already points to it. | |
| // | |
| // | |
| // Free any allocated buffers | |
| // | |
| gBS->FreePool (HandleBuffer); | |
| return Status; | |
| } | |
| VOID | |
| DsdtTableUpdate ( | |
| IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, | |
| IN OUT EFI_ACPI_TABLE_VERSION *Version | |
| ) | |
| /*++ | |
| Routine Description: | |
| Update the DSDT table | |
| Arguments: | |
| Table - The table to be set | |
| Version - Version to publish | |
| Returns: | |
| None | |
| --*/ | |
| { | |
| UINT8 *CurrPtr; | |
| UINT8 *DsdtPointer; | |
| UINT32 *Signature; | |
| UINT8 *Operation; | |
| UINT32 *Address; | |
| UINT16 *Size; | |
| // | |
| // Loop through the ASL looking for values that we must fix up. | |
| // | |
| CurrPtr = (UINT8 *) TableHeader; | |
| for (DsdtPointer = CurrPtr; | |
| DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); | |
| DsdtPointer++ | |
| ) | |
| { | |
| Signature = (UINT32 *) DsdtPointer; | |
| switch (*Signature) { | |
| // | |
| // MNVS operation region | |
| // | |
| case (SIGNATURE_32 ('M', 'N', 'V', 'S')): | |
| // | |
| // Conditional match. For Region Objects, the Operator will always be the | |
| // byte immediately before the specific name. Therefore, subtract 1 to check | |
| // the Operator. | |
| // | |
| Operation = DsdtPointer - 1; | |
| if (*Operation == AML_OPREGION_OP) { | |
| Address = (UINT32 *) (DsdtPointer + 6); | |
| *Address = (UINT32) (UINTN) mGlobalNvsArea.Area; | |
| Size = (UINT16 *) (DsdtPointer + 11); | |
| *Size = sizeof (EFI_GLOBAL_NVS_AREA); | |
| } | |
| break; | |
| // | |
| // Update processor PBLK register I/O base address | |
| // | |
| case (SIGNATURE_32 ('P', 'R', 'I', 'O')): | |
| // | |
| // Conditional match. Update the following ASL code: | |
| // Processor (CPU0, 0x01, 0x4F495250, 0x06) {} | |
| // The 3rd parameter will be updated to the actual PBLK I/O base address. | |
| // the Operator. | |
| // | |
| Operation = DsdtPointer - 8; | |
| if ((*Operation == AML_EXT_OP) && (*(Operation + 1) == AML_EXT_PROCESSOR_OP)) { | |
| *(UINT32 *)DsdtPointer = PcdGet16(PcdPmbaIoBaseAddress); | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| VOID | |
| ApicTableUpdate ( | |
| IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, | |
| IN OUT EFI_ACPI_TABLE_VERSION *Version | |
| ) | |
| /*++ | |
| Routine Description: | |
| Update the processors information in the APIC table | |
| Arguments: | |
| Table - The table to be set | |
| Version - Version to publish | |
| Returns: | |
| None | |
| --*/ | |
| { | |
| EFI_STATUS Status; | |
| EFI_MP_SERVICES_PROTOCOL *MpService; | |
| UINT8 *CurrPtr; | |
| UINT8 *EndPtr; | |
| UINT8 CurrIoApic; | |
| UINT8 CurrProcessor; | |
| UINTN NumberOfCPUs; | |
| UINTN NumberOfEnabledCPUs; | |
| EFI_PROCESSOR_INFORMATION MpContext; | |
| ACPI_APIC_STRUCTURE_PTR *ApicPtr; | |
| CurrIoApic = 0; | |
| CurrProcessor = 0; | |
| // | |
| // Find the MP Protocol. This is an MP platform, so MP protocol must be | |
| // there. | |
| // | |
| Status = gBS->LocateProtocol ( | |
| &gEfiMpServiceProtocolGuid, | |
| NULL, | |
| (VOID**)&MpService | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| // | |
| // Failed to get MP information, doesn't publish the invalid table | |
| // | |
| *Version = EFI_ACPI_TABLE_VERSION_NONE; | |
| return; | |
| } | |
| // | |
| // Determine the number of processors | |
| // | |
| MpService->GetNumberOfProcessors ( | |
| MpService, | |
| &NumberOfCPUs, | |
| &NumberOfEnabledCPUs | |
| ); | |
| CurrPtr = (UINT8*) &(TableHeader[1]); | |
| CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag | |
| EndPtr = (UINT8*) TableHeader; | |
| EndPtr = EndPtr + TableHeader->Length; | |
| while (CurrPtr < EndPtr) { | |
| ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr; | |
| switch (ApicPtr->AcpiApicCommon.Type) { | |
| case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC: | |
| ApicPtr->AcpiLocalApic.Flags = 0; | |
| ApicPtr->AcpiLocalApic.ApicId = 0; | |
| Status = MpService->GetProcessorInfo ( | |
| MpService, | |
| CurrProcessor, | |
| &MpContext | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) { | |
| ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED; | |
| } | |
| ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId; | |
| } | |
| CurrProcessor++; | |
| break; | |
| case EFI_ACPI_1_0_IO_APIC: | |
| // | |
| // IO APIC entries can be patched here | |
| // | |
| if (CurrIoApic == 0) { | |
| // | |
| // Update SOC internel IOAPIC base | |
| // | |
| ApicPtr->AcpiIoApic.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId); | |
| ApicPtr->AcpiIoApic.IoApicAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress); | |
| ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0; | |
| } else { | |
| // | |
| // Porting is required to update other IOAPIC entries if available | |
| // | |
| ASSERT (0); | |
| } | |
| CurrIoApic++; | |
| break; | |
| default: | |
| break; | |
| }; | |
| CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length; | |
| } | |
| } | |
| VOID | |
| AcpiUpdateTable ( | |
| IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, | |
| IN OUT EFI_ACPI_TABLE_VERSION *Version | |
| ) | |
| /*++ | |
| Routine Description: | |
| Set the correct table revision upon the setup value | |
| Arguments: | |
| Table - The table to be set | |
| Version - Version to publish | |
| Returns: | |
| None | |
| --*/ | |
| { | |
| EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader1; | |
| EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader2; | |
| EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtHeader3; | |
| EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *AllocationStructurePtr; | |
| if (TableHeader != NULL && Version != NULL) { | |
| *Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; | |
| // | |
| // Here we use all 3.0 signature because all version use same signature if they supported | |
| // | |
| switch (TableHeader->Signature) { | |
| // | |
| // "APIC" Multiple APIC Description Table | |
| // | |
| case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: | |
| ApicTableUpdate (TableHeader, Version); | |
| break; | |
| // | |
| // "DSDT" Differentiated System Description Table | |
| // | |
| case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: | |
| DsdtTableUpdate (TableHeader, Version); | |
| break; | |
| // | |
| // "FACP" Fixed ACPI Description Table (FADT) | |
| // | |
| case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: | |
| *Version = EFI_ACPI_TABLE_VERSION_NONE; | |
| if (TableHeader->Revision == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { | |
| *Version = EFI_ACPI_TABLE_VERSION_1_0B; | |
| FadtHeader1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader; | |
| FadtHeader1->SmiCmd = PcdGet16(PcdSmmActivationPort); | |
| FadtHeader1->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress); | |
| FadtHeader1->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C; | |
| FadtHeader1->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T; | |
| FadtHeader1->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress); | |
| } else if (TableHeader->Revision == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { | |
| *Version = EFI_ACPI_TABLE_VERSION_2_0; | |
| FadtHeader2 = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader; | |
| FadtHeader2->SmiCmd = PcdGet16(PcdSmmActivationPort); | |
| FadtHeader2->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress); | |
| FadtHeader2->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C; | |
| FadtHeader2->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T; | |
| FadtHeader2->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress); | |
| FadtHeader2->XPm1aEvtBlk.Address = FadtHeader2->Pm1aEvtBlk; | |
| FadtHeader2->XPm1aCntBlk.Address = FadtHeader2->Pm1aCntBlk; | |
| FadtHeader2->XPmTmrBlk.Address = FadtHeader2->PmTmrBlk; | |
| FadtHeader2->XGpe0Blk.Address = FadtHeader2->Gpe0Blk; | |
| } else if (TableHeader->Revision == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { | |
| *Version = EFI_ACPI_TABLE_VERSION_3_0; | |
| FadtHeader3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) TableHeader; | |
| FadtHeader3->SmiCmd = PcdGet16(PcdSmmActivationPort); | |
| FadtHeader3->Pm1aEvtBlk = PcdGet16(PcdPm1blkIoBaseAddress); | |
| FadtHeader3->Pm1aCntBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C; | |
| FadtHeader3->PmTmrBlk = PcdGet16(PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1T; | |
| FadtHeader3->Gpe0Blk = PcdGet16(PcdGpe0blkIoBaseAddress); | |
| FadtHeader3->XPm1aEvtBlk.Address = FadtHeader3->Pm1aEvtBlk; | |
| FadtHeader3->XPm1aCntBlk.Address = FadtHeader3->Pm1aCntBlk; | |
| FadtHeader3->XPmTmrBlk.Address = FadtHeader3->PmTmrBlk; | |
| FadtHeader3->XGpe0Blk.Address = FadtHeader3->Gpe0Blk; | |
| } | |
| break; | |
| // | |
| // "FACS" Firmware ACPI Control Structure | |
| // | |
| case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE: | |
| break; | |
| // | |
| // "SSDT" Secondary System Description Table | |
| // | |
| case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "HPET" IA-PC High Precision Event Timer Table | |
| // | |
| case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE: | |
| // | |
| // If HPET is disabled in setup, don't publish the table. | |
| // | |
| if (mGlobalNvsArea.Area->HpetEnable == 0) { | |
| *Version = EFI_ACPI_TABLE_VERSION_NONE; | |
| } | |
| ((EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) TableHeader)->BaseAddressLower32Bit.Address | |
| = PcdGet64 (PcdHpetBaseAddress); | |
| break; | |
| // | |
| // "SPCR" Serial Port Concole Redirection Table | |
| // | |
| case EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table | |
| // | |
| case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE: | |
| AllocationStructurePtr = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *) | |
| ((UINT8 *)TableHeader + sizeof(EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER)); | |
| AllocationStructurePtr->BaseAddress = PcdGet64(PcdPciExpressBaseAddress); | |
| break; | |
| // Lakeport platform doesn't support the following table | |
| /* | |
| // | |
| // "ECDT" Embedded Controller Boot Resources Table | |
| // | |
| case EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "PSDT" Persistent System Description Table | |
| // | |
| case EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "SBST" Smart Battery Specification Table | |
| // | |
| case EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "SLIT" System Locality Information Table | |
| // | |
| case EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "SRAT" Static Resource Affinity Table | |
| // | |
| case EFI_ACPI_3_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "XSDT" Extended System Description Table | |
| // | |
| case EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "BOOT" MS Simple Boot Spec | |
| // | |
| case EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "CPEP" Corrected Platform Error Polling Table | |
| // | |
| case EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "DBGP" MS Debug Port Spec | |
| // | |
| case EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "ETDT" Event Timer Description Table | |
| // | |
| case EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "SPMI" Server Platform Management Interface Table | |
| // | |
| case EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE: | |
| break; | |
| // | |
| // "TCPA" Trusted Computing Platform Alliance Capabilities Table | |
| // | |
| case EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE: | |
| break; | |
| */ | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| // | |
| // Description: | |
| // Entrypoint of Acpi Platform driver | |
| // In: | |
| // ImageHandle | |
| // SystemTable | |
| // Out: | |
| // EFI_SUCCESS | |
| // EFI_LOAD_ERROR | |
| // EFI_OUT_OF_RESOURCES | |
| // | |
| EFI_STATUS | |
| AcpiPlatformEntryPoint ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_ACPI_TABLE_PROTOCOL *AcpiTable; | |
| EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; | |
| INTN Instance; | |
| EFI_ACPI_COMMON_HEADER *CurrentTable; | |
| UINTN TableHandle; | |
| UINT32 FvStatus; | |
| UINTN Size; | |
| EFI_ACPI_TABLE_VERSION Version; | |
| EFI_HANDLE Handle; | |
| UINTN Index; | |
| PCI_DEVICE_INFO *PciDeviceInfo; | |
| EFI_ACPI_HANDLE PciRootHandle; | |
| BOOLEAN UpdatePRT; | |
| BOOLEAN UpdatePRW; | |
| PCI_DEVICE_SETTING *mConfigData; | |
| DEBUG((DEBUG_INFO, "ACPI Platform start...\n")); | |
| Instance = 0; | |
| TableHandle = 0; | |
| CurrentTable = NULL; | |
| mConfigData = NULL; | |
| // | |
| // Initialize the EFI Driver Library | |
| // | |
| ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512); | |
| Status = gBS->AllocatePool ( | |
| EfiACPIMemoryNVS, | |
| sizeof (EFI_GLOBAL_NVS_AREA), | |
| (VOID**)&mGlobalNvsArea.Area | |
| ); | |
| Handle = NULL; | |
| Status = gBS->InstallProtocolInterface ( | |
| &Handle, | |
| &gEfiGlobalNvsAreaProtocolGuid, | |
| EFI_NATIVE_INTERFACE, | |
| &mGlobalNvsArea | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| if (!EFI_ERROR (Status)) { | |
| SetMem ( | |
| mGlobalNvsArea.Area, | |
| sizeof (EFI_GLOBAL_NVS_AREA), | |
| 0 | |
| ); | |
| } | |
| // | |
| // Initialize the data. Eventually, this will be controlled by setup options. | |
| // | |
| mGlobalNvsArea.Area->HpetEnable = PcdGetBool (PcdHpetEnable); | |
| mGlobalNvsArea.Area->Pm1blkIoBaseAddress = PcdGet16(PcdPm1blkIoBaseAddress); | |
| mGlobalNvsArea.Area->PmbaIoBaseAddress = PcdGet16(PcdPmbaIoBaseAddress); | |
| mGlobalNvsArea.Area->Gpe0blkIoBaseAddress = PcdGet16(PcdGpe0blkIoBaseAddress); | |
| mGlobalNvsArea.Area->GbaIoBaseAddress = PcdGet16(PcdGbaIoBaseAddress); | |
| mGlobalNvsArea.Area->SmbaIoBaseAddress = PcdGet16(PcdSmbaIoBaseAddress); | |
| mGlobalNvsArea.Area->WdtbaIoBaseAddress = PcdGet16(PcdWdtbaIoBaseAddress); | |
| mGlobalNvsArea.Area->HpetBaseAddress = (UINT32)PcdGet64(PcdHpetBaseAddress); | |
| mGlobalNvsArea.Area->HpetSize = (UINT32)PcdGet64(PcdHpetSize); | |
| mGlobalNvsArea.Area->PciExpressBaseAddress= (UINT32)PcdGet64(PcdPciExpressBaseAddress); | |
| mGlobalNvsArea.Area->PciExpressSize = (UINT32)PcdGet64(PcdPciExpressSize); | |
| mGlobalNvsArea.Area->RcbaMmioBaseAddress = (UINT32)PcdGet64(PcdRcbaMmioBaseAddress); | |
| mGlobalNvsArea.Area->RcbaMmioSize = (UINT32)PcdGet64(PcdRcbaMmioSize); | |
| mGlobalNvsArea.Area->IoApicBaseAddress = (UINT32)PcdGet64(PcdIoApicBaseAddress); | |
| mGlobalNvsArea.Area->IoApicSize = (UINT32)PcdGet64(PcdIoApicSize); | |
| mGlobalNvsArea.Area->TpmPresent = (UINT32)(FALSE); | |
| mGlobalNvsArea.Area->DBG2Present = (UINT32)(FALSE); | |
| mGlobalNvsArea.Area->PlatformType = (UINT32)PcdGet16 (PcdPlatformType); | |
| // | |
| // Configure platform IO expander I2C Slave Address. | |
| // | |
| if (mGlobalNvsArea.Area->PlatformType == Galileo) { | |
| if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) { | |
| mGlobalNvsArea.Area->AlternateSla = FALSE; | |
| } else { | |
| mGlobalNvsArea.Area->AlternateSla = TRUE; | |
| } | |
| } | |
| // | |
| // Find the AcpiTable protocol | |
| // | |
| Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); | |
| if (EFI_ERROR (Status)) { | |
| return EFI_ABORTED; | |
| } | |
| // | |
| // Initialize MADT table | |
| // | |
| Status = MadtTableInitialize (&CurrentTable, &Size); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Perform any table specific updates. | |
| // | |
| AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); | |
| // | |
| // Update the check sum | |
| // It needs to be zeroed before the checksum calculation | |
| // | |
| ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0; | |
| ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = | |
| CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length); | |
| // | |
| // Add the table | |
| // | |
| TableHandle = 0; | |
| Status = AcpiTable->InstallAcpiTable ( | |
| AcpiTable, | |
| CurrentTable, | |
| CurrentTable->Length, | |
| &TableHandle | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| CurrentTable = NULL; | |
| // | |
| // Init Pci Device PRT PRW information structure from PCD | |
| // | |
| mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING)); | |
| ASSERT (mConfigData != NULL); | |
| InitPciDeviceInfoStructure (mConfigData); | |
| // | |
| // Get the Acpi SDT protocol for manipulation on acpi table | |
| // | |
| Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Locate the firmware volume protocol | |
| // | |
| Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1); | |
| if (EFI_ERROR (Status)) { | |
| return EFI_ABORTED; | |
| } | |
| // | |
| // Read tables from the storage file. | |
| // | |
| while (Status == EFI_SUCCESS) { | |
| Status = FwVol->ReadSection ( | |
| FwVol, | |
| (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile), | |
| EFI_SECTION_RAW, | |
| Instance, | |
| (VOID**)&CurrentTable, | |
| &Size, | |
| &FvStatus | |
| ); | |
| if (!EFI_ERROR(Status)) { | |
| // | |
| // Perform any table specific updates. | |
| // | |
| AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version); | |
| // | |
| // Update the check sum | |
| // It needs to be zeroed before the checksum calculation | |
| // | |
| ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0; | |
| ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = | |
| CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length); | |
| // | |
| // Add the table | |
| // | |
| TableHandle = 0; | |
| Status = AcpiTable->InstallAcpiTable ( | |
| AcpiTable, | |
| CurrentTable, | |
| ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length, | |
| &TableHandle | |
| ); | |
| if (EFI_ERROR(Status)) { | |
| return EFI_ABORTED; | |
| } | |
| // | |
| // If this table is the DSDT table, then update the _PRT and _PRW based on | |
| // the settings from pcds | |
| // | |
| if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { | |
| // | |
| // Create the root handle for DSDT table | |
| // | |
| Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle); | |
| ASSERT_EFI_ERROR (Status); | |
| PciRootHandle = NULL; | |
| PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle); | |
| ASSERT (PciRootHandle != NULL); | |
| PciDeviceInfo = NULL; | |
| for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) { | |
| PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]); | |
| // | |
| // Check whether this is a valid item | |
| // | |
| if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) { | |
| //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress)); | |
| UpdatePRT = FALSE; | |
| UpdatePRW = FALSE; | |
| SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW); | |
| // | |
| // Check whether there is any valid pci routing item | |
| // | |
| if (UpdatePRT) { | |
| // | |
| // Update the pci routing information | |
| // | |
| //DEBUG ((EFI_D_ERROR, "Update _PRT\n")); | |
| SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo); | |
| } | |
| // | |
| // Check whether there is any valid pci routing item | |
| // | |
| if (UpdatePRW) { | |
| // | |
| // Update the pci wakeup information | |
| // | |
| //DEBUG ((EFI_D_ERROR, "Update _PRW\n")); | |
| SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo); | |
| } | |
| } | |
| } | |
| Status = mAcpiSdt->Close (PciRootHandle); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Mark the root handle as modified , let SDT protocol recaculate the checksum | |
| // | |
| ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE; | |
| Status = mAcpiSdt->Close (mDsdtHandle); | |
| ASSERT_EFI_ERROR (Status); | |
| } | |
| // | |
| // Increment the instance | |
| // | |
| Instance++; | |
| CurrentTable = NULL; | |
| } | |
| } | |
| gBS->FreePool (mConfigData); | |
| return EFI_SUCCESS; | |
| } |