From 5f7e96419eba9dae61a6fc1efe4dbad2de9b862a Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 13:36:44 +0800 Subject: BroxtonPlatformPkg: Add AcpiPlatformDxe Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../Common/Acpi/AcpiPlatformDxe/AcpiPlatform.c | 2466 ++++++++++++++++++++ .../Common/Acpi/AcpiPlatformDxe/AcpiPlatform.h | 304 +++ .../Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf | 91 + .../Acpi/AcpiPlatformDxe/AcpiPlatformHooks.c | 490 ++++ .../Acpi/AcpiPlatformDxe/AcpiPlatformHooks.h | 124 + .../Acpi/AcpiPlatformDxe/AcpiPlatformHooksLib.h | 89 + .../Common/Acpi/AcpiPlatformDxe/Osfr.h | 53 + 7 files changed, 3617 insertions(+) create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.c create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.h create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.c create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.h create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooksLib.h create mode 100644 Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/Osfr.h diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.c b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.c new file mode 100644 index 0000000000..854bd48a25 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.c @@ -0,0 +1,2466 @@ +/** @file + ACPI Platform Driver. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "PlatformBaseAddresses.h" + +#if (ENBDT_PF_ENABLE == 0) +#include +#endif +#include "AcpiPlatform.h" +#include "AcpiPlatformHooks.h" +#include "AcpiPlatformHooksLib.h" +#include "Osfr.h" + +#ifdef PRAM_SUPPORT +#include +extern EFI_GUID gPramAddrDataGuid; +extern EFI_GUID gEfiPramConfGuid; +#endif +extern EFI_GUID gPlatformSsdtImageGuid; + +CHAR16 EfiPlatformCpuInfoVariable[] = L"PlatformCpuInfo"; +CHAR16 gACPIOSFRModelStringVariableName[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME; +CHAR16 gACPIOSFRRefDataBlockVariableName[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME; +CHAR16 gACPIOSFRMfgStringVariableName[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME; + +EFI_CPU_IO2_PROTOCOL *mCpuIo; + +BOOLEAN mFirstNotify; +EFI_PLATFORM_INFO_HOB *mPlatformInfo; +SYSTEM_CONFIGURATION mSystemConfiguration; +UINT8 mSLP20DataPresenceCheckDone = FALSE; +UINT8 mSLP20DataPresentAndValid = FALSE; +UINT64 mSLP20OemIdValue; +UINT64 mSLP20OemTableIdValue; +UINT8 *mSLP20PublicKeyBuffer = NULL, *mSLP20MarkerBuffer = NULL; +UINTN mMaximumNumberOfCpus; +UINTN mNumberOfEnabledCpus; +EFI_MP_SERVICES_PROTOCOL *mMpService; +// +// APCI Watchdog Action Table (WDAT) +// +UINT8 EntryNumber; + +EFI_ACPI_WATCHDOG_ACTION_TABLE mWatchDogActionTableAcpiTemplate = { + { + { + EFI_ACPI_5_0_WATCHDOG_ACTION_TABLE_SIGNATURE, + 0x00, // Length, will be updated + EFI_ACPI_WATCHDOG_ACTION_1_0_TABLE_REVISION, + // + // Compiler initializes the remaining bytes to 0 + // These fields should be filled in in production + // + }, + sizeof (EFI_ACPI_WATCHDOG_ACTION_1_0_TABLE) - sizeof (EFI_ACPI_DESCRIPTION_HEADER), + 0x00FF, // PCI Segment + 0xFF, // PCI Bus Number + 0xFF, // PCI Device Number + 0xFF, // PCI Function Number + 0x00, 0x00, 0x00, // Reserved_45[3] + 0x00000258, // TimerPeriod, 600 milliseconds + 0x000003FF, // MaxCount + 0x00000002, // MinCount + 0x00, // WatchdogFlags, will be updated + 0x00, 0x00, 0x00, // Reserved_61[3] + 0x00, // NumberWatchdogInstructionEntries, will be updated + }, +}; + +EFI_STATUS +PublishWatchDogActionTable ( + VOID + ); + +UINT8 +ReadCmosBank1Byte ( + IN EFI_CPU_IO2_PROTOCOL *CpuIo, + IN UINT8 Index + ); + +VOID +WriteCmosBank1Byte ( + IN EFI_CPU_IO2_PROTOCOL *CpuIo, + IN UINT8 Index, + IN UINT8 Data + ); + +EFI_STATUS +UpdateDbgpTable ( + IN EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport + ); + +EFI_STATUS +UpdateDbg2Table ( + IN EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport + ); + +/** + 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. + + @param[in] Protocol The protocol to find. + @param[out] Instance Return pointer to the first instance of the protocol. + @param[in] Type The type of protocol to locate. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The protocol could not be located. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. + +**/ +EFI_STATUS +LocateSupportProtocol ( + IN EFI_GUID *Protocol, + OUT VOID **Instance, + IN UINT32 Type + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + + 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 (Index = 0; Index < NumberOfHandles; Index++) { + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + 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, + &gEfiAcpiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (!EFI_ERROR (Status)) { + 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; +} + + +/** + Installing all the newly created SSDTs. + +**/ +EFI_STATUS +InstallAcpiTableForPlatformSsdt ( + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol, + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport + ) +{ + UINTN TableHandle; + UINTN Instance; + UINTN Size; + UINT32 FvStatus; + EFI_ACPI_COMMON_HEADER *CurrentTable; + EFI_STATUS Status; + BOOLEAN FoundSsdt; + EFI_ACPI_TABLE_VERSION TableVersion; + BOOLEAN InstallTable; + + // + // Read SSDT tables from the storage file. + // + Status = EFI_SUCCESS; + Instance = 0; + FoundSsdt = FALSE; + TableVersion = EFI_ACPI_TABLE_VERSION_2_0; + InstallTable = FALSE; + + while (!EFI_ERROR (Status)) { + CurrentTable = NULL; + + Status = FwVol->ReadSection ( + FwVol, + &gPlatformSsdtImageGuid, + EFI_SECTION_RAW, + Instance, + &CurrentTable, + (UINTN *) &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + // + // Add the table + // + TableHandle = 0; + InstallTable = TRUE; + DEBUG ((DEBUG_INFO, "Found SSDT %x index = %d \n", CurrentTable, Instance)); + +#if (ENBDT_PF_ENABLE == 1) + if (((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->OemTableId == SIGNATURE_64 ('I', 'r', 'm', 't', 'T', 'a', 'b', 'l')) { + if (mSystemConfiguration.IrmtConfiguration == 1) { + DEBUG((DEBUG_INFO, "IRMT: Publishing IrmtTabl\n")); + } else { + DEBUG((DEBUG_INFO, "IRMT: Found IrmtTabl but disabled, will not publish\n")); + InstallTable = FALSE; + } + } +#endif + + if (InstallTable) { + // + // Install the table + // + Status = AcpiSupport->SetAcpiTable ( + AcpiSupport, + CurrentTable, + TRUE, + TableVersion, + &TableHandle + ); + ASSERT_EFI_ERROR (Status); + } + + FoundSsdt = TRUE; + Instance ++; + } + } + + if (FoundSsdt) { + Status = EFI_SUCCESS; + } + + return Status; +} + + +/** + This function will update any runtime platform specific information. + This currently includes: + Setting OEM table values, ID, table ID, creator ID and creator revision. + Enabling the proper processor entries in the APIC tables. + + @param[in] Table The table to update. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +PlatformUpdateTables ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + UINT8 *CurrPtr; + UINT8 *EndPtr; + ACPI_APIC_STRUCTURE_PTR *ApicPtr; + UINT8 CurrProcessor; + EFI_STATUS Status; + UINTN BufferSize; + ACPI_APIC_STRUCTURE_PTR *ProcessorLocalApicEntry; + UINTN BspIndex; + EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTbl; + UINT64 OemIdValue; + EFI_CPU_IO2_PROTOCOL *CpuIo; + UINT8 Data; + EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFACP; + EFI_ACPI_SLIC_TABLE *SlicTable; + UINT8 *SLP20PKSignBuffer = NULL; + UINT32 SLP20Magic; + EFI_GUID SLP20MagicGuid = {0x41282EF2L, 0x9B5A, 0x4EB7, 0x95, 0xD8, 0xD9, 0xCD, 0x7B, 0xDC, 0xE3, 0x67}; + EFI_DPSD_RSA1024_AND_SHA256_SIGNATURE_VERIFICATION_PROTOCOL *DpsdRSA1024AndSHA256SignatureVerification; + EFI_ACPI_OSFR_TABLE *pOsfrTable; + EFI_ACPI_OSFR_OCUR_OBJECT *pOcurObject; + EFI_ACPI_OSFR_OCUR_OBJECT OcurObject = {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0}; + CHAR16 *OcurMfgStringBuffer = NULL, *OcurModelStringBuffer = NULL; + UINT8 *OcurRefDataBlockBuffer = NULL; + UINTN OcurMfgStringBufferSize, OcurModelStringBufferSize, OcurRefDataBlockBufferSize; + UINT8 IoApicId; +#if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED + EFI_ACPI_ASPT_TABLE *pSpttTable; +#endif + UINT16 NumberOfHpets; + UINT16 HpetCapIdValue; + UINT32 HpetBlockID; + UINTN LocalApicCounter; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; +#ifdef PRAM_SUPPORT + UINT32 VariableAttributes; + SYSTEM_CONFIGURATION SetupVarBuffer; + UINTN VariableSize; + EFI_HOB_GUID_TYPE *GuidHob = NULL; + EFI_PHYSICAL_ADDRESS PramBaseAddress = 0; + EFI_PHYSICAL_ADDRESS PramBaseAddressVar = 0; + UINT32 PramSizeVar = 0; + UINT32 PramSize = 0; + EFI_STATUS Status1; + UINT8 PramConfigVariable; +#endif + + CurrPtr = NULL; + EndPtr = NULL; + ApicPtr = NULL; + LocalApicCounter = 0; + CurrProcessor = 0; + ProcessorLocalApicEntry = NULL; + + // + // Check for presence of SLP 2.0 data in proper variables + // + if (mSLP20DataPresenceCheckDone == FALSE) { + mSLP20DataPresenceCheckDone = TRUE; + + // + // Prep handshaking variable for programming SLP 2.0 data + // + BufferSize = sizeof (UINT32); + Status = gRT->GetVariable (L"SLP20Magic", &SLP20MagicGuid, NULL, &BufferSize, &SLP20Magic); + + if (EFI_ERROR (Status)) { + // + // SLP 2.0 magic variable not present - set it to current value + // + SLP20Magic = SLP20_MAGIC_NUMBER; + Status = gRT->SetVariable (L"SLP20Magic", &SLP20MagicGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_NON_VOLATILE, BufferSize, &SLP20Magic); + } + + BufferSize = sizeof (EFI_ACPI_SLIC_OEM_PUBLIC_KEY); + mSLP20PublicKeyBuffer = AllocatePool (BufferSize); + if (mSLP20PublicKeyBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable (L"SLP20OEMPublicKey", &gSLP20OEMPublicKeyVariableGuid, NULL, &BufferSize, mSLP20PublicKeyBuffer); + + if (!EFI_ERROR (Status)) { + BufferSize = sizeof (EFI_ACPI_SLIC_SLP_MARKER); + mSLP20MarkerBuffer = AllocatePool (BufferSize); + if (mSLP20MarkerBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable (L"SLP20Marker", &gSLP20MarkerVariableGuid, NULL, &BufferSize, mSLP20MarkerBuffer); + + if (!EFI_ERROR (Status)) { + BufferSize = sizeof (EFI_ACPI_SLIC_SIGNED_OEM_PUBLIC_KEY); + SLP20PKSignBuffer = AllocatePool (BufferSize); + if (SLP20PKSignBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable (L"SLP20EncryptedOEMPublicKey", &gSLP20EncryptedOEMPublicKeyVariableGuid, NULL, &BufferSize, SLP20PKSignBuffer); + + if (!EFI_ERROR (Status)) { + // + // All SLP 2.0 data is here. Let's see if the signature has already been verified + // + if ((*(UINT32 *) SLP20PKSignBuffer != SLP20_VERIFIED_INDICATOR)) { + Status = gBS->LocateProtocol (&gEfiDpsdRSA1024AndSHA256SignatureVerificationProtocolGuid, NULL, (VOID **) &DpsdRSA1024AndSHA256SignatureVerification); + + if (!EFI_ERROR (Status)) { + Status = DpsdRSA1024AndSHA256SignatureVerification->VerifySignature (mSLP20PublicKeyBuffer, sizeof (EFI_ACPI_SLIC_OEM_PUBLIC_KEY), SLP20PKSignBuffer); + + if (!EFI_ERROR (Status)) { + // + // Signature has been verified + // + mSLP20DataPresentAndValid = TRUE; + + CopyMem (&mSLP20OemIdValue, ((EFI_ACPI_SLIC_SLP_MARKER *) mSLP20MarkerBuffer)->sOEMID, 6); + mSLP20OemTableIdValue = ((EFI_ACPI_SLIC_SLP_MARKER *) mSLP20MarkerBuffer)->sOEMTABLEID; + + BufferSize = sizeof (UINT32); + SLP20Magic = SLP20_VERIFIED_INDICATOR; + + // + // Update variable to indicate that signature verification has already succeeded + // + gRT->SetVariable (L"SLP20EncryptedOEMPublicKey#!rtUY9o", &gSLP20EncryptedOEMPublicKeyVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_NON_VOLATILE, BufferSize, &SLP20Magic); + } + } + } + // + // Signature has been previously verified + // + else + { + mSLP20DataPresentAndValid = TRUE; + + CopyMem (&mSLP20OemIdValue, ((EFI_ACPI_SLIC_SLP_MARKER *) mSLP20MarkerBuffer)->sOEMID, 6); + mSLP20OemTableIdValue = ((EFI_ACPI_SLIC_SLP_MARKER *) mSLP20MarkerBuffer)->sOEMTABLEID; + + BufferSize = sizeof (UINT32); + SLP20Magic = SLP20_VERIFIED_INDICATOR; + + // + // Update variable to indicate that signature verification has already succeeded + // + gRT->SetVariable (L"SLP20EncryptedOEMPublicKey#!rtUY9o", &gSLP20EncryptedOEMPublicKeyVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS + | EFI_VARIABLE_NON_VOLATILE, BufferSize, &SLP20Magic); + } + } + } + } + + // + // Free all allocated memory + // + if (SLP20PKSignBuffer != NULL) { + gBS->FreePool (SLP20PKSignBuffer); + } + } + + if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) { + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + // + // Update the OEMID + // + OemIdValue = mPlatformInfo->AcpiOemId; + + // + // Override ACPI OEMID from valid SLP 2.0 data + // + if (mSLP20DataPresentAndValid) { + OemIdValue = mSLP20OemIdValue; + } + + *(UINT32 *) (TableHeader->OemId) = (UINT32) OemIdValue; + *(UINT16 *) (TableHeader->OemId + 4) = *(UINT16*) (((UINT8 *) &OemIdValue) + 4); + + if ((Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) { + // + // Update the OEM Table ID + // + TableHeader->OemTableId = mPlatformInfo->AcpiOemTableId; + } + // + // Override ACPI OEMTABLEID from valid SLP 2.0 data + // + if (mSLP20DataPresentAndValid && Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { + TableHeader->OemTableId = mSLP20OemTableIdValue; + } + + // + // Update the OEM Table ID + // + TableHeader->OemRevision = EFI_ACPI_OEM_REVISION; + + // + // Update the creator ID + // + TableHeader->CreatorId = EFI_ACPI_CREATOR_ID; + + // + // Update the creator revision + // + TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION; + } + // + // Complete this function + // + // + // Assign a invalid initial value for update + // + // + // Update the processors in the APIC table + // + switch (Table->Signature) { + + case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: + + Status = mMpService->WhoAmI ( + mMpService, + &BspIndex + ); + + CurrPtr = (UINT8 *) &((EFI_ACPI_DESCRIPTION_HEADER *) Table)[1]; + CurrPtr = CurrPtr + 8; + + // + // Size of Local APIC Address & Flag + // + EndPtr = (UINT8 *) Table; + EndPtr = EndPtr + Table->Length; + + while (CurrPtr < EndPtr) { + ApicPtr = (ACPI_APIC_STRUCTURE_PTR *) CurrPtr; + + switch (ApicPtr->AcpiApicCommon.Type) { + case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC: + // + // ESS override + // Fix for Ordering of MADT to be maintained as it is in MADT table. + // + // Update processor enabled or disabled and keep the local APIC + // order in MADT intact + // + // Sanity check to make sure proc-id is not arbitrary + // + DEBUG ((DEBUG_INFO, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", ApicPtr->AcpiLocalApic.AcpiProcessorId, mMaximumNumberOfCpus)); + + BufferSize = 0; + ApicPtr->AcpiLocalApic.Flags = 0; + + for (CurrProcessor = 0; CurrProcessor < mMaximumNumberOfCpus; CurrProcessor++) { + Status = mMpService->GetProcessorInfo ( + mMpService, + CurrProcessor, + &ProcessorInfoBuffer + ); + + if (Status == EFI_SUCCESS && ProcessorInfoBuffer.ProcessorId == ApicPtr->AcpiLocalApic.ApicId) { + // + // Check to see whether or not a processor (or thread) is enabled + // + if (BspIndex == CurrProcessor || ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0)) { + ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED; + AppendCpuMapTableEntry (&(ApicPtr->AcpiLocalApic)); + } + break; + } + } + + // + // If no APIC-ID match, the CPU may not be populated + // + break; + + case EFI_ACPI_3_0_IO_APIC: + // + // IO APIC entries can be patched here + // + DEBUG ((DEBUG_INFO, " Original ApicPtr->AcpiIoApic.IoApicId = %x\n", \ + ApicPtr->AcpiIoApic.IoApicId)); + + // + // Get IO APIC ID + // + MmioWrite8 ((UINTN) R_IO_APIC_INDEX, R_IO_APIC_ID); + IoApicId = MmioRead32 ((UINTN) R_IO_APIC_WINDOW) >> 24; + ApicPtr->AcpiIoApic.IoApicId = IoApicId; + + DEBUG ((DEBUG_INFO, " Updated ApicPtr->AcpiIoApic.IoApicId = %x\n", \ + ApicPtr->AcpiIoApic.IoApicId)); + + break; + } + + CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length; + } + break; + + case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: + pFACP = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table; + pFACP->ResetValue = mSystemConfiguration.ResetSelect; + pFACP->Flags |= BIT10; + DEBUG ((DEBUG_INFO, "FACP ResetValue = %x\n", pFACP->ResetValue)); + + // + // if Native ASPM is disabled, set FACP table to skip Native ASPM + // + if ((mSystemConfiguration.PciExpNative == 0) || (mSystemConfiguration.NativeAspmEnable == 0x0)) { + pFACP->IaPcBootArch |= 0x10; + } + if (mSystemConfiguration.LowPowerS0Idle) { + DEBUG((DEBUG_INFO,"LowPowerS0Idle enabled.\n")); + pFACP->Flags |= BIT21; + } + + break; + + case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + // + // Patch the memory resource + // + PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *) Table); + break; + + case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + // + // Gv3 support + // + // TBD: Need re-design based on the Broxton platform. + // + break; + + case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE: + // + // Adjust HPET Table to correct the Base Address + // + // Enable HPET always as Hpet.asi always indicates that Hpet is enabled. + // + MmioOr8 (R_HPET + R_HPET_GCFG, B_HPET_GCFG_EN); + + // + // Update CMOS to reflect HPET enable/disable for ACPI usage + // + Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) &CpuIo); + ASSERT_EFI_ERROR (Status); + + Data = ReadCmosBank1Byte (CpuIo, EFI_CMOS_ACPI_TABLE_FLAG_ADDRESS); + Data &= ~B_CMOS_HPET_ENABLED; + + Data |= B_CMOS_HPET_ENABLED; + + WriteCmosBank1Byte (CpuIo, EFI_CMOS_ACPI_TABLE_FLAG_ADDRESS, Data); + + HpetTbl = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table; + HpetTbl->BaseAddressLower32Bit.Address = HPET_BASE_ADDRESS; + HpetTbl->EventTimerBlockId = *((UINT32*) (UINTN) HPET_BASE_ADDRESS); + + HpetCapIdValue = *(UINT16 *) (UINTN) (HPET_BASE_ADDRESS); + NumberOfHpets = HpetCapIdValue & B_HPET_GCID_NT; // Bits [8:12] contains the number of Hpets + HpetBlockID = EFI_ACPI_EVENT_TIMER_BLOCK_ID; + + if ((NumberOfHpets) && (NumberOfHpets & B_HPET_GCID_NT)) { + HpetBlockID |= (NumberOfHpets); + } + HpetTbl->EventTimerBlockId = HpetBlockID; + break; + + case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE: + // + // Update MCFG base and end bus number + // + ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].BaseAddress + = mPlatformInfo->PciData.PciExpressBase; + + ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].EndBusNumber + = (UINT8) RShiftU64 (mPlatformInfo->PciData.PciExpressSize, 20) - 1; + break; + + case EFI_ACPI_SLIC_TABLE_SIGNATURE: + if (!mSLP20DataPresentAndValid) { + return EFI_UNSUPPORTED; + } + + SlicTable = (EFI_ACPI_SLIC_TABLE *) Table; + + CopyMem (&(SlicTable->OemPublicKey), mSLP20PublicKeyBuffer, sizeof (EFI_ACPI_SLIC_OEM_PUBLIC_KEY)); + CopyMem (&(SlicTable->SlpMarker), mSLP20MarkerBuffer, sizeof (EFI_ACPI_SLIC_SLP_MARKER)); + + gBS->FreePool (mSLP20PublicKeyBuffer); + gBS->FreePool (mSLP20MarkerBuffer); + break; + + case EFI_ACPI_OSFR_TABLE_SIGNATURE: + // + // Get size of OSFR variable + // + OcurMfgStringBufferSize = 0; + Status = gRT->GetVariable (gACPIOSFRMfgStringVariableName, &gACPIOSFRMfgStringVariableGuid, NULL, &OcurMfgStringBufferSize, NULL); + + if (Status != EFI_BUFFER_TOO_SMALL) { + // + // Variable must not be present on the system + // + return EFI_UNSUPPORTED; + } + // + // Allocate memory for variable data + // + OcurMfgStringBuffer = AllocatePool (OcurMfgStringBufferSize); + if (OcurMfgStringBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable (gACPIOSFRMfgStringVariableName, &gACPIOSFRMfgStringVariableGuid, NULL, &OcurMfgStringBufferSize, OcurMfgStringBuffer); + + if (!EFI_ERROR (Status)) { + OcurModelStringBufferSize = 0; + Status = gRT->GetVariable (gACPIOSFRModelStringVariableName, &gACPIOSFRModelStringVariableGuid, NULL, &OcurModelStringBufferSize, NULL); + + if (Status != EFI_BUFFER_TOO_SMALL) { + // + // Variable must not be present on the system + // + return EFI_UNSUPPORTED; + } + + // + // Allocate memory for variable data + // + OcurModelStringBuffer = AllocatePool (OcurModelStringBufferSize); + if (OcurModelStringBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = gRT->GetVariable (gACPIOSFRModelStringVariableName, &gACPIOSFRModelStringVariableGuid, NULL, &OcurModelStringBufferSize, OcurModelStringBuffer); + + if (!EFI_ERROR (Status)) { + OcurRefDataBlockBufferSize = 0; + Status = gRT->GetVariable (gACPIOSFRRefDataBlockVariableName, &gACPIOSFRRefDataBlockVariableGuid, NULL, &OcurRefDataBlockBufferSize, NULL); + + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Allocate memory for variable data + // + OcurRefDataBlockBuffer = AllocatePool (OcurRefDataBlockBufferSize); + if (OcurRefDataBlockBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = gRT->GetVariable (gACPIOSFRRefDataBlockVariableName, &gACPIOSFRRefDataBlockVariableGuid, NULL, &OcurRefDataBlockBufferSize, OcurRefDataBlockBuffer); + } + + pOsfrTable = (EFI_ACPI_OSFR_TABLE *) Table; + + // + // Currently only one object is defined: OCUR_OSFR_TABLE + // + pOsfrTable->ObjectCount = 1; + + // + // Initialize table length to fixed portion of the ACPI OSFR table + // + pOsfrTable->Header.Length = sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION); + *(UINT32 *) ((UINTN) pOsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION)) = \ + (UINT32) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + sizeof (UINT32)); + + pOcurObject = (EFI_ACPI_OSFR_OCUR_OBJECT *) ((UINTN) pOsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + \ + sizeof (UINT32)); + + CopyMem (pOcurObject, &OcurObject, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)); + pOcurObject->ManufacturerNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) pOsfrTable + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)); + pOcurObject->ModelNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) pOsfrTable + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize); + + if (OcurRefDataBlockBufferSize > 0) { + pOcurObject->MicrosoftReferenceOffset = (UINT32)((UINTN) pOcurObject - (UINTN) pOsfrTable + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + OcurModelStringBufferSize); + } + + CopyMem ((UINTN *) ((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)), OcurMfgStringBuffer, OcurMfgStringBufferSize); + CopyMem ((UINTN *) ((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize), \ + OcurModelStringBuffer, OcurModelStringBufferSize); + + if (OcurRefDataBlockBufferSize > 0) { + CopyMem ((UINTN *) ((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + OcurModelStringBufferSize), \ + OcurRefDataBlockBuffer, OcurRefDataBlockBufferSize); + } + + pOsfrTable->Header.Length += (UINT32)(OcurMfgStringBufferSize + OcurModelStringBufferSize + OcurRefDataBlockBufferSize); + pOsfrTable->Header.Length += sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + sizeof (UINT32); + } + } + + gBS->FreePool (OcurMfgStringBuffer); + gBS->FreePool (OcurModelStringBuffer); + gBS->FreePool (OcurRefDataBlockBuffer); + break; +#ifdef PRAM_SUPPORT + case EFI_ACPI_PRAM_BASE_ADDRESS_TABLE_SIGNATURE: + VariableSize = sizeof (UINTN); + Status = gRT->GetVariable ( + L"PRAM_Conf", + &gEfiPramConfGuid, + NULL, + &VariableSize, + &PramConfigVariable + ); + if (Status == EFI_SUCCESS && PramConfigVariable != mSystemConfiguration.Pram) { + DEBUG ((DEBUG_INFO, "PramConfigVariable = 0x%x\n", PramConfigVariable)); + + VariableSize = sizeof (SETUP_DATA); + Status = gRT->GetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + &VariableAttributes, + &VariableSize, + &SetupVarBuffer + ); + ASSERT_EFI_ERROR (Status); + + SetupVarBuffer.Pram = PramConfigVariable; + Status = gRT->SetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + VariableAttributes, + VariableSize, + &SetupVarBuffer + ); + ASSERT_EFI_ERROR (Status); + + // + // WA for variable cannot be accessed before memory init + // + DEBUG ((DEBUG_INFO, "EfiResetWarm for Pram \n")); + gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); + CpuDeadLoop (); + } else { + PramConfigVariable = mSystemConfiguration.Pram; + } + + if (PramConfigVariable != 0x30) { + switch (PramConfigVariable) { + case 0x31: // 4MB + PramSize = 0x400000; + break; + case 0x32: // 16MB + PramSize = 0x1000000; + break; + case 0x33: // 64MB + PramSize = 0x4000000; + break; + } + + GuidHob = GetFirstGuidHob (&gPramAddrDataGuid); + if (GuidHob == NULL) { + ASSERT_EFI_ERROR (Status); + return EFI_NOT_FOUND; + } + PramBaseAddress = *(EFI_PHYSICAL_ADDRESS *) GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, "PramBaseAddress = 0x%lx\n", PramBaseAddress)); + + VariableSize = sizeof (EFI_PHYSICAL_ADDRESS); + Status = gRT->GetVariable ( + L"PramBaseAddress", + &gPramAddrDataGuid, + NULL, + &VariableSize, + &PramBaseAddressVar + ); + VariableSize = sizeof (UINT32); + Status1 = gRT->GetVariable ( + L"PramSize", + &gPramAddrDataGuid, + NULL, + &VariableSize, + &PramSizeVar + ); + if (EFI_ERROR(Status) || EFI_ERROR(Status1) || (PramBaseAddressVar!=PramBaseAddress) || (PramSizeVar!=PramSize)) { + Status = gRT->SetVariable ( + L"PramBaseAddress", + &gPramAddrDataGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (EFI_PHYSICAL_ADDRESS), + &PramBaseAddress + ); + Status = gRT->SetVariable ( + L"PramSize", + &gPramAddrDataGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (UINT32), + &PramSize + ); + ((EFI_ACPI_PRAM_BASE_ADDRESS_TABLE *) Table)->PramSize = PramSize; + ((EFI_ACPI_PRAM_BASE_ADDRESS_TABLE *) Table)->PramBaseAddress = PramBaseAddress; + } else { + ((EFI_ACPI_PRAM_BASE_ADDRESS_TABLE *) Table)->PramSize = PramSize; + ((EFI_ACPI_PRAM_BASE_ADDRESS_TABLE *) Table)->PramBaseAddress = PramBaseAddress; + } + } + break; +#endif + + default: + break; + } + // + // + // Update the hardware signature in the FACS structure + // + // + // Locate the SPCR table and update based on current settings. + // The user may change CR settings via setup or other methods. + // The SPCR table must match. + // + return EFI_SUCCESS; +} + + +/** + Ready To Boot Function. + + @param[in] Event A pointer to the Event that triggered. + @param[in] Context A pointer to private data registered function. + +**/ +STATIC +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; + EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save; + EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; + EFI_ACPI_TABLE_VERSION TableVersion; + SYSTEM_CONFIGURATION SetupVarBuffer; + EFI_PLATFORM_CPU_INFO *PlatformCpuInfoPtr = NULL; + EFI_PLATFORM_CPU_INFO PlatformCpuInfo; + EFI_PEI_HOB_POINTERS GuidHob; + UINTN VariableSize; + UINT32 VariableAttributes; + UINTN PciMmBase = 0; + UINT32 BaseAddress = 0; + + if (mFirstNotify) { + return; + } + + Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0); + ASSERT_EFI_ERROR (Status); + + TableVersion = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0; + + mFirstNotify = TRUE; + + // + // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used" + // + PlatformCpuInfo.CpuVersion.FullCpuId = 0; + + // + // Get Platform CPU Info HOB + // + PlatformCpuInfoPtr = NULL; + + ZeroMem (&PlatformCpuInfo, sizeof (EFI_PLATFORM_CPU_INFO)); + VariableSize = sizeof (EFI_PLATFORM_CPU_INFO); + + Status = gRT->GetVariable( + EfiPlatformCpuInfoVariable, + &gEfiBxtVariableGuid, + NULL, + &VariableSize, + PlatformCpuInfoPtr + ); + + if (EFI_ERROR (Status)) { + GuidHob.Raw = GetHobList (); + + if (GuidHob.Raw != NULL) { + if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformCpuInfoGuid, GuidHob.Raw)) != NULL) { + PlatformCpuInfoPtr = GET_GUID_HOB_DATA (GuidHob.Guid); + } + } + } + + if ((PlatformCpuInfoPtr != NULL)) { + CopyMem (&PlatformCpuInfo, PlatformCpuInfoPtr, sizeof (EFI_PLATFORM_CPU_INFO)); + } + + // + // Update the ACPI parameter blocks + // + VariableSize = sizeof (SETUP_DATA); + + Status = gRT->GetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + &VariableAttributes, + &VariableSize, + &SetupVarBuffer + ); + + ASSERT_EFI_ERROR (Status); + + // + // Update the DBG2 Table + // + if (GetBxtSeries() == BxtP) { + Status = UpdateDbgpTable (AcpiSupport); + } + + // + // Update the DBG2 Table + // + Status = UpdateDbg2Table (AcpiSupport); + + if (Status == EFI_DEVICE_ERROR) { + DEBUG ((EFI_D_INFO, "UART2 Device Not Found Or OsDbgEnable is Disabled - DBG2 UART2 Base Address Not Updated\n")); + } else if (Status == EFI_NOT_FOUND) { + DEBUG ((EFI_D_ERROR, "DBG2 ACPI Table Not Found - Table Not Updated\n")); + } + + // + // Update the DMAR Table + // + UpdateDmarOnReadyToBoot (SetupVarBuffer.VTdEnable); + + // + // Publish ACPI 1.0 or 2.0 Tables + // + Status = AcpiSupport->PublishTables ( + AcpiSupport, + TableVersion + ); + ASSERT_EFI_ERROR (Status); + + // + // S3 script save + // + Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save); + if (!EFI_ERROR (Status)) { + AcpiS3Save->S3Save (AcpiS3Save, NULL); + } + + Status = gBS->LocateProtocol ( + &gEfiGlobalNvsAreaProtocolGuid, + NULL, + (VOID **) &GlobalNvsArea + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Error loading GlobalNvsAreaProtocol - P2SB and eMMC Base Addresses Not Updated\n")); + return; + } + + // + // Update P2SB Base Address in Global NVS + // + PciMmBase = MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_P2SB, + PCI_FUNCTION_NUMBER_P2SB, + 0 + ); + + BaseAddress = MmioRead32 (PciMmBase + R_P2SB_BASE) & 0xFF000000; + + GlobalNvsArea->Area->P2SBBaseAddress = BaseAddress; + + // + // Update eMMC Base Address in Global NVS + // + PciMmBase = MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SCC_EMMC, + PCI_FUNCTION_NUMBER_SCC_FUNC0, + 0 + ); + + BaseAddress = MmioRead32 (PciMmBase + R_SCC_BAR) & B_SCC_BAR_BA; + + GlobalNvsArea->Area->eMMCAddr = BaseAddress; + + // + // Install WatchDog Action Table + // + DEBUG ((DEBUG_INFO,"Publish WDAT...\n")); + Status = PublishWatchDogActionTable (); + ASSERT_EFI_ERROR (Status); +} + + +/** + Ready to Boot Event to uninstall RTD3 SSDT ACPI Table + + @param[in] Event + @param[in] Context + + @retval EFI_SUCCESS Operation completed successfully. + @retval other Some error occurred when executing this function. + +**/ +VOID +EFIAPI +OnReadyToBootUninstallRtd3SSDTAcpiTable( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINTN Count = 0; + UINTN Handle; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_TABLE_VERSION Version; + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport = NULL; + + // + // Locate ACPI Support protocol + // + Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, (VOID **) &AcpiSupport); + ASSERT_EFI_ERROR (Status); + + if (!EFI_ERROR (Status)) { + do { + Version = 0; + Status = AcpiSupport->GetAcpiTable (AcpiSupport, Count, (VOID **) &Table, &Version, &Handle); + if (EFI_ERROR (Status)) { + break; + } + // + // Check if this is a DPTF SSDT table. If so, uninstall the table + // + if (Table->Signature == EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE && + Table->OemTableId == SIGNATURE_64('R','V','P','R','t','d','3',0x0)) { + DEBUG ((DEBUG_INFO, "RTD3 SSDT Table found.Uninstalling it\n")); + Status = AcpiSupport->SetAcpiTable (AcpiSupport, NULL, TRUE, Version, &Handle); + ASSERT_EFI_ERROR (Status); + Status = AcpiSupport->PublishTables( + AcpiSupport, + EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 + ); + ASSERT_EFI_ERROR (Status); + break; + } + Count ++; + } while (1); + } + + gBS->CloseEvent(Event); +} + + +/** + Convert string containing GUID in the canonical form: + "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp" + where aa - pp are unicode hexadecimal digits + to the buffer format to be used in ACPI, byte ordering: + [Byte 0] gg, hh, ee, ff, aa, bb, cc, dd [Byte 7] + [Byte 8] pp, oo, nn, mm, ll, kk, jj, ii [Byte 16] + + @param[in] GuidString GUID String null terminated (aligned on a 16-bit boundary) + @param[out] AcpiGuidPart1 First half of buffer (bytes 0 - 7) + @param[out] AcpiGuidPart2 Second half of buffer (bytes 8 - 16) + + @retval EFI_SUCCESS String converted successfully. + @retval EFI_UNSUPPORTED Wrong input string format. + +**/ +EFI_STATUS +GuidStringToAcpiBuffer ( + IN CHAR16 *GuidString, + OUT UINT64 *AcpiGuidPart1, + OUT UINT64 *AcpiGuidPart2 + ) +{ + UINT32 GuidTempPart32 = 0; + UINT16 GuidTempPart16 = 0; + UINT8 GuidPartIndex; + + DEBUG ((DEBUG_INFO,"GuidStringToAcpiBuffer() - GUID = %s\n", GuidString)); + + for (GuidPartIndex = 0; GuidPartIndex < 4; GuidPartIndex++) { + switch (GuidPartIndex){ + case 0: + GuidTempPart32 = SwapBytes32 ((UINT32) StrHexToUint64 (GuidString)); + *AcpiGuidPart1 = ((UINT64) GuidTempPart32 << 0x20); + break; + case 1: + GuidTempPart16 = SwapBytes16 ((UINT16) StrHexToUint64 (GuidString)); + *AcpiGuidPart1 += ((UINT64) GuidTempPart16 << 0x10); + break; + case 2: + GuidTempPart16 = SwapBytes16 ((UINT16) StrHexToUint64 (GuidString)); + *AcpiGuidPart1 += ((UINT64) GuidTempPart16); + break; + case 3: + GuidTempPart16 = (UINT16) StrHexToUint64 (GuidString); + break; + default: + return EFI_UNSUPPORTED; + } + + while ((*GuidString != L'-') && (*GuidString != L'\0')) { + GuidString++; + } + + if (*GuidString == L'-') { + GuidString++; + } else { + return EFI_UNSUPPORTED; + } + } + + *AcpiGuidPart2 = ((UINT64) GuidTempPart16 << 0x30) + StrHexToUint64 (GuidString); + + // + // Switch endianess because it will be swapped again in ACPI Buffer object + // + *AcpiGuidPart1 = SwapBytes64 (*AcpiGuidPart1); + *AcpiGuidPart2 = SwapBytes64 (*AcpiGuidPart2); + + return EFI_SUCCESS; +} + + +/** + Entry point for Acpi platform driver. + + @param[in] ImageHandle A handle for the image that is initializing this driver. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS Driver initialized successfully. + @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. + +**/ +EFI_STATUS +EFIAPI +AcpiPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_STATUS AcpiStatus; + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + INTN Instance; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINTN TableHandle; + UINT32 FvStatus; + UINT32 Size; + EFI_EVENT Event; + EFI_ACPI_TABLE_VERSION TableVersion; + UINTN VarSize; + EFI_HANDLE Handle; + EFI_PEI_HOB_POINTERS GuidHob; + UINTN McD2BaseAddress; + UINT64 AcpiGuidPart1; + UINT64 AcpiGuidPart2; + CHAR16 LocalGuidString[GUID_CHARS_NUMBER]; + UINTN Data32; + UINT32 VariableAttributes; + + mFirstNotify = FALSE; + TableVersion = EFI_ACPI_TABLE_VERSION_2_0; + Instance = 0; + CurrentTable = NULL; + TableHandle = 0; + McD2BaseAddress = MmPciBase (0, 2, 0); + + // + // Update HOB variable for PCI resource information + // Get the HOB list. If it is not present, then ASSERT. + // + GuidHob.Raw = GetHobList (); + if (GuidHob.Raw != NULL) { + if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) { + mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid); + } + } + + VarSize = sizeof (SYSTEM_CONFIGURATION); + + Status = gRT->GetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + NULL, + &VarSize, + &mSystemConfiguration + ); + + // + // Find the AcpiSupport protocol + // + Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0); + ASSERT_EFI_ERROR (Status); + + // + // Locate the firmware volume protocol + // + Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID **) &FwVol, 1); + ASSERT_EFI_ERROR (Status); + + // + // Locate the MP services protocol + // + // + // Find the MP Protocol. This is an MP platform, so MP protocol must be + // there. + // + Status = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **) &mMpService + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = EFI_SUCCESS; + Instance = 0; + + // + // Allocate and initialize the NVS area for SMM and ASL communication. + // + Status = gBS->AllocatePool (EfiACPIMemoryNVS, sizeof (EFI_GLOBAL_NVS_AREA), (VOID **) &mGlobalNvsArea.Area); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + gBS->SetMem (mGlobalNvsArea.Area, sizeof (EFI_GLOBAL_NVS_AREA), 0); + + + // + // Determine the number of processors + // + mMpService->GetNumberOfProcessors ( + mMpService, + &mMaximumNumberOfCpus, + &mNumberOfEnabledCpus + ); + + ASSERT (mMaximumNumberOfCpus <= MAX_CPU_NUM && mNumberOfEnabledCpus >= 1); + // + // Dual Core Override + // + if ((mMaximumNumberOfCpus == DUAL_CORE_CONFIG) && (mSystemConfiguration.Core1 == 1) && (mSystemConfiguration.Core3 == 1)) { + DEBUG ((DEBUG_INFO, "Dual Core Config - Update Setup Variable\n")); + + VarSize = sizeof (SYSTEM_CONFIGURATION); + Status = gRT->GetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + &VariableAttributes, + &VarSize, + &mSystemConfiguration + ); + ASSERT_EFI_ERROR (Status); + + mSystemConfiguration.NumOfProcessors = (UINT8) mMaximumNumberOfCpus; + Status = gRT->SetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + VariableAttributes, + VarSize, + &mSystemConfiguration + ); + ASSERT_EFI_ERROR (Status); + } + + // + // Update Global NVS area for ASL and SMM init code to use + // + if (GetBxtSeries() == BxtP) { + mGlobalNvsArea.Area->NumberOfBatteries = 1; + mGlobalNvsArea.Area->BatteryCapacity0 = 100; + mGlobalNvsArea.Area->Mmio32Base = (MmioRead32 ((UINTN) PcdGet64 (PcdPciExpressBaseAddress) + 0xBC) & 0xFFF00000);; + mGlobalNvsArea.Area->Mmio32Length = ACPI_MMIO_BASE_ADDRESS - mGlobalNvsArea.Area->Mmio32Base; + // + // Initialize IGD state by checking if IGD Device 2 Function 0 is enabled in the chipset + // + if (MmioRead16 (McD2BaseAddress) != 0xFFFF) { + mGlobalNvsArea.Area->IgdState = 1; + } else { + mGlobalNvsArea.Area->IgdState = 0; + } + + // + // RTD3 Settings + // + mGlobalNvsArea.Area->Rtd3Support = mSystemConfiguration.Rtd3Support; + mGlobalNvsArea.Area->RTD3Config0 = mSystemConfiguration.RTD3ZPODD; + mGlobalNvsArea.Area->EnableModernStandby = mSystemConfiguration.ConsolidatedPR; + mGlobalNvsArea.Area->SelectBtDevice = mSystemConfiguration.SelectBtDevice; + mGlobalNvsArea.Area->ScHdAudioIoBufferOwnership = mSystemConfiguration.ScHdAudioIoBufferOwnership; + mGlobalNvsArea.Area->XdciEnable = mSystemConfiguration.ScUsbOtg; + mGlobalNvsArea.Area->PciDelayOptimizationEcr = mSystemConfiguration.PciDelayOptimizationEcr; + + // + // LPSS I2C0 Speed + // + if (mSystemConfiguration.I2C0Speed == 1) { + mGlobalNvsArea.Area->I2C0Speed = 100000; + } else if (mSystemConfiguration.I2C0Speed == 2) { + mGlobalNvsArea.Area->I2C0Speed = 400000; + } else if (mSystemConfiguration.I2C0Speed == 3) { + mGlobalNvsArea.Area->I2C0Speed = 1000000; + } else if (mSystemConfiguration.I2C0Speed == 4) { + mGlobalNvsArea.Area->I2C0Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C0Speed = 0; + } + // + // LPSS I2C1 Speed + // + if (mSystemConfiguration.I2C1Speed == 1) { + mGlobalNvsArea.Area->I2C1Speed = 100000; + } else if (mSystemConfiguration.I2C1Speed == 2) { + mGlobalNvsArea.Area->I2C1Speed = 400000; + } else if (mSystemConfiguration.I2C1Speed == 3) { + mGlobalNvsArea.Area->I2C1Speed = 1000000; + } else if (mSystemConfiguration.I2C1Speed == 4) { + mGlobalNvsArea.Area->I2C1Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C1Speed = 0; + } + // + // LPSS I2C2 Speed + // + if (mSystemConfiguration.I2C2Speed == 1) { + mGlobalNvsArea.Area->I2C2Speed = 100000; + } else if (mSystemConfiguration.I2C2Speed == 2) { + mGlobalNvsArea.Area->I2C2Speed = 400000; + } else if (mSystemConfiguration.I2C2Speed == 3) { + mGlobalNvsArea.Area->I2C2Speed = 1000000; + } else if (mSystemConfiguration.I2C2Speed == 4) { + mGlobalNvsArea.Area->I2C2Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C2Speed = 0; + } + // + // LPSS I2C3 Speed + // + if (mSystemConfiguration.I2C3Speed == 1) { + mGlobalNvsArea.Area->I2C3Speed = 100000; + } else if (mSystemConfiguration.I2C3Speed == 2) { + mGlobalNvsArea.Area->I2C3Speed = 400000; + } else if (mSystemConfiguration.I2C3Speed == 3) { + mGlobalNvsArea.Area->I2C3Speed = 1000000; + } else if (mSystemConfiguration.I2C3Speed == 4) { + mGlobalNvsArea.Area->I2C3Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C3Speed = 0; + } + // + // LPSS I2C4 Speed + // + if (mSystemConfiguration.I2C4Speed == 1) { + mGlobalNvsArea.Area->I2C4Speed = 100000; + } else if (mSystemConfiguration.I2C4Speed == 2) { + mGlobalNvsArea.Area->I2C4Speed = 400000; + } else if (mSystemConfiguration.I2C4Speed == 3) { + mGlobalNvsArea.Area->I2C4Speed = 1000000; + } else if (mSystemConfiguration.I2C4Speed == 4) { + mGlobalNvsArea.Area->I2C4Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C4Speed = 0; + } + // + // LPSS I2C5 Speed + // + if (mSystemConfiguration.I2C5Speed == 1) { + mGlobalNvsArea.Area->I2C5Speed = 100000; + } else if (mSystemConfiguration.I2C5Speed == 2) { + mGlobalNvsArea.Area->I2C5Speed = 400000; + } else if (mSystemConfiguration.I2C5Speed == 3) { + mGlobalNvsArea.Area->I2C5Speed = 1000000; + } else if (mSystemConfiguration.I2C5Speed == 4) { + mGlobalNvsArea.Area->I2C5Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C5Speed = 0; + } + // + // LPSS I2C6 Speed + // + if (mSystemConfiguration.I2C6Speed == 1){ + mGlobalNvsArea.Area->I2C6Speed = 100000; + } else if (mSystemConfiguration.I2C6Speed == 2) { + mGlobalNvsArea.Area->I2C6Speed = 400000; + } else if (mSystemConfiguration.I2C6Speed == 3) { + mGlobalNvsArea.Area->I2C6Speed = 1000000; + } else if (mSystemConfiguration.I2C6Speed == 4) { + mGlobalNvsArea.Area->I2C6Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C6Speed = 0; + } + // + // LPSS I2C7 Speed + // + if (mSystemConfiguration.I2C7Speed == 1) { + mGlobalNvsArea.Area->I2C7Speed = 100000; + } else if (mSystemConfiguration.I2C7Speed == 2) { + mGlobalNvsArea.Area->I2C7Speed = 400000; + } else if (mSystemConfiguration.I2C7Speed == 3) { + mGlobalNvsArea.Area->I2C7Speed = 1000000; + } else if (mSystemConfiguration.I2C7Speed == 4) { + mGlobalNvsArea.Area->I2C7Speed = 3400000; + } else { + mGlobalNvsArea.Area->I2C7Speed = 0; + } + + // + // LPSS devices + // + mGlobalNvsArea.Area->I2s343A = mSystemConfiguration.I2s343A; + mGlobalNvsArea.Area->I2s34C1 = mSystemConfiguration.I2s34C1; + mGlobalNvsArea.Area->I2cNfc = mSystemConfiguration.I2cNfc; + mGlobalNvsArea.Area->I2cPss = mSystemConfiguration.I2cPss; + mGlobalNvsArea.Area->UartBt = mSystemConfiguration.UartBt; + mGlobalNvsArea.Area->UartGps = mSystemConfiguration.UartGps; + mGlobalNvsArea.Area->Spi1SensorDevice = mSystemConfiguration.Spi1SensorDevice; + mGlobalNvsArea.Area->I2cTouchPanel = mSystemConfiguration.I2cTouchPanel; + mGlobalNvsArea.Area->I2cTouchPad = mSystemConfiguration.I2cTouchPad; + + // + // EPI + // + mGlobalNvsArea.Area->EPIEnable = mSystemConfiguration.EPIEnable; + + if (mSystemConfiguration.TypeCEnable == 2) { + // + // AUTO + // + mGlobalNvsArea.Area->TypeCEnable = 0; // Disable TypeC for All other RVP. + } else { + mGlobalNvsArea.Area->TypeCEnable = mSystemConfiguration.TypeCEnable; + } + DEBUG ((DEBUG_INFO, "TypeCEnable = %d\n", mGlobalNvsArea.Area->TypeCEnable)); + } else { + mGlobalNvsArea.Area->VirtualKeyboard = mSystemConfiguration.VirtualKbEnable; + DEBUG ((DEBUG_INFO, "VirtualKeyboard = %d\n", mGlobalNvsArea.Area->VirtualKeyboard)); + + mGlobalNvsArea.Area->WifiSel = mSystemConfiguration.WifiSel; + DEBUG ((DEBUG_INFO, "GlobalNvsArea.Area->WifiSel: [%02x], WiFi selection: 0: SDIO Lightning Peak, 1: SDIO Broadcom; 2: PCIe Lightning Peak\n", mGlobalNvsArea.Area->WifiSel)); + + mGlobalNvsArea.Area->NfcSelect = mSystemConfiguration.NfcSelect; + DEBUG ((DEBUG_INFO, "GlobalNvsArea.Area->NfcSelect: [%02x], NFC deivce select: 0: disabled; 1: NFC (IPT)/secure NFC; 2: NFC;\n", mGlobalNvsArea.Area->NfcSelect)); + + mGlobalNvsArea.Area->AudioSel = mSystemConfiguration.AudioSel; + mGlobalNvsArea.Area->PanelSel = mSystemConfiguration.PanelSel; + } + +#if (ENBDT_PF_ENABLE == 0) + // + // Input PMIC stepping to Global NVS area. + // + mGlobalNvsArea.Area->PmicStepping = PmicStepping (); + DEBUG ((DEBUG_INFO, "PmicStepping = 0x%x\n", mGlobalNvsArea.Area->PmicStepping)); +#endif + + if (mSystemConfiguration.IpuEn == 0) { + // + // If IPU is disabled, both camera can't be used. + // + mGlobalNvsArea.Area->WorldCameraSel = 0; + mGlobalNvsArea.Area->UserCameraSel = 0; + } else { + mGlobalNvsArea.Area->WorldCameraSel = mSystemConfiguration.WorldCameraSel; + mGlobalNvsArea.Area->UserCameraSel = mSystemConfiguration.UserCameraSel; + } + mGlobalNvsArea.Area->CameraRotationAngle = mSystemConfiguration.CameraRotationAngle; + mGlobalNvsArea.Area->Reservedo = 3; + mGlobalNvsArea.Area->ApicEnable = 1; + mGlobalNvsArea.Area->PowerState = 0; + + mGlobalNvsArea.Area->IgdPanelType = mSystemConfiguration.IgdFlatPanel; + mGlobalNvsArea.Area->IgdPanelScaling = mSystemConfiguration.PanelScaling; + mGlobalNvsArea.Area->IgdSciSmiMode = 0; + mGlobalNvsArea.Area->IgdTvFormat = 0; + mGlobalNvsArea.Area->IgdTvMinor = 0; + mGlobalNvsArea.Area->IgdSscConfig = 1; + mGlobalNvsArea.Area->IgdBiaConfig = mSystemConfiguration.IgdLcdIBia; + mGlobalNvsArea.Area->IgdBlcConfig = mSystemConfiguration.IgdLcdIGmchBlc; + mGlobalNvsArea.Area->IgdDvmtMemSize = mSystemConfiguration.IgdDvmt50TotalAlloc; + mGlobalNvsArea.Area->IgdHpllVco = 0; //Todo: Need to lookup broxton spec // SKL: MmioRead8 (mMchBarBase + 0xC0F) & 0x07; + + mGlobalNvsArea.Area->AlsEnable = mSystemConfiguration.AlsEnable; + mGlobalNvsArea.Area->BacklightControlSupport = 2; + mGlobalNvsArea.Area->BrightnessPercentage = 100; + mGlobalNvsArea.Area->LidState = 1; + + mGlobalNvsArea.Area->DeviceId1 = 0x80000100; + mGlobalNvsArea.Area->DeviceId2 = 0x80000400; + mGlobalNvsArea.Area->DeviceId3 = 0x80000200; + mGlobalNvsArea.Area->DeviceId4 = 0x04; + mGlobalNvsArea.Area->DeviceId5 = 0x05; + mGlobalNvsArea.Area->NumberOfValidDeviceId = 4; + mGlobalNvsArea.Area->CurrentDeviceList = 0x0F; + + // + //Broxton-P(ApolloLake only) + // + if (GetBxtSeries() == BxtP) { + // + // Legacy thermal zone Active trip point + // + mGlobalNvsArea.Area->ActiveTripPoint = mSystemConfiguration.ActiveTripPoint; + + // + // Broxton-P(ApolloLake only) + // + mGlobalNvsArea.Area->DptfProcActiveTemperature = mSystemConfiguration.DptfProcActiveTemperature; + mGlobalNvsArea.Area->DptfFanDevice = mSystemConfiguration.DptfFanDevice; + + // + // DPTF Policies + // + mGlobalNvsArea.Area->EnableActivePolicy = mSystemConfiguration.EnableActivePolicy; + mGlobalNvsArea.Area->TrtRevision = mSystemConfiguration.TrtRevision; + + // + // DPTF Participants + // + mGlobalNvsArea.Area->EnableSen1Participant = mSystemConfiguration.EnableSen1Participant; + mGlobalNvsArea.Area->ActiveThermalTripPointSen1 = mSystemConfiguration.ActiveThermalTripPointSen1; + mGlobalNvsArea.Area->PassiveThermalTripPointSen1 = mSystemConfiguration.PassiveThermalTripPointSen1; + mGlobalNvsArea.Area->CriticalThermalTripPointSen1 = mSystemConfiguration.CriticalThermalTripPointSen1; + mGlobalNvsArea.Area->CriticalThermalTripPointSen1S3 = mSystemConfiguration.CriticalThermalTripPointSen1S3; + mGlobalNvsArea.Area->HotThermalTripPointSen1 = mSystemConfiguration.HotThermalTripPointSen1; + mGlobalNvsArea.Area->SensorSamplingPeriodSen1 = mSystemConfiguration.SensorSamplingPeriodSen1; + + mGlobalNvsArea.Area->EnableGen1Participant = mSystemConfiguration.EnableGen1Participant; + mGlobalNvsArea.Area->ActiveThermalTripPointGen1 = mSystemConfiguration.ActiveThermalTripPointGen1; + mGlobalNvsArea.Area->PassiveThermalTripPointGen1 = mSystemConfiguration.PassiveThermalTripPointGen1; + mGlobalNvsArea.Area->CriticalThermalTripPointGen1 = mSystemConfiguration.CriticalThermalTripPointGen1; + mGlobalNvsArea.Area->CriticalThermalTripPointGen1S3 = mSystemConfiguration.CriticalThermalTripPointGen1S3; + mGlobalNvsArea.Area->HotThermalTripPointGen1 = mSystemConfiguration.HotThermalTripPointGen1; + mGlobalNvsArea.Area->ThermistorSamplingPeriodGen1 = mSystemConfiguration.ThermistorSamplingPeriodGen1; + + mGlobalNvsArea.Area->EnableGen2Participant = mSystemConfiguration.EnableGen2Participant; + mGlobalNvsArea.Area->ActiveThermalTripPointGen2 = mSystemConfiguration.ActiveThermalTripPointGen2; + mGlobalNvsArea.Area->PassiveThermalTripPointGen2 = mSystemConfiguration.PassiveThermalTripPointGen2; + mGlobalNvsArea.Area->CriticalThermalTripPointGen2 = mSystemConfiguration.CriticalThermalTripPointGen2; + mGlobalNvsArea.Area->CriticalThermalTripPointGen2S3 = mSystemConfiguration.CriticalThermalTripPointGen2S3; + mGlobalNvsArea.Area->HotThermalTripPointGen2 = mSystemConfiguration.HotThermalTripPointGen2; + mGlobalNvsArea.Area->ThermistorSamplingPeriodGen2 = mSystemConfiguration.ThermistorSamplingPeriodGen2; + + mGlobalNvsArea.Area->EnableGen3Participant = mSystemConfiguration.EnableGen3Participant; + mGlobalNvsArea.Area->ActiveThermalTripPointGen3 = mSystemConfiguration.ActiveThermalTripPointGen3; + mGlobalNvsArea.Area->PassiveThermalTripPointGen3 = mSystemConfiguration.PassiveThermalTripPointGen3; + mGlobalNvsArea.Area->CriticalThermalTripPointGen3 = mSystemConfiguration.CriticalThermalTripPointGen3; + mGlobalNvsArea.Area->CriticalThermalTripPointGen3S3 = mSystemConfiguration.CriticalThermalTripPointGen3S3; + mGlobalNvsArea.Area->HotThermalTripPointGen3 = mSystemConfiguration.HotThermalTripPointGen3; + mGlobalNvsArea.Area->ThermistorSamplingPeriodGen3 = mSystemConfiguration.ThermistorSamplingPeriodGen3; + + mGlobalNvsArea.Area->EnableGen4Participant = mSystemConfiguration.EnableGen4Participant; + mGlobalNvsArea.Area->ActiveThermalTripPointGen4 = mSystemConfiguration.ActiveThermalTripPointGen4; + mGlobalNvsArea.Area->PassiveThermalTripPointGen4 = mSystemConfiguration.PassiveThermalTripPointGen4; + mGlobalNvsArea.Area->CriticalThermalTripPointGen4 = mSystemConfiguration.CriticalThermalTripPointGen4; + mGlobalNvsArea.Area->CriticalThermalTripPointGen4S3 = mSystemConfiguration.CriticalThermalTripPointGen4S3; + mGlobalNvsArea.Area->HotThermalTripPointGen4 = mSystemConfiguration.HotThermalTripPointGen4; + mGlobalNvsArea.Area->ThermistorSamplingPeriodGen4 = mSystemConfiguration.ThermistorSamplingPeriodGen4; + + mGlobalNvsArea.Area->ActiveThermalTripPointVS1 = mSystemConfiguration.ActiveThermalTripPointVS1; + mGlobalNvsArea.Area->CriticalThermalTripPointVS1 = mSystemConfiguration.CriticalThermalTripPointVS1; + mGlobalNvsArea.Area->CriticalThermalTripPointVS1S3 = mSystemConfiguration.CriticalThermalTripPointVS1S3; + mGlobalNvsArea.Area->HotThermalTripPointVS1 = mSystemConfiguration.HotThermalTripPointVS1; + + mGlobalNvsArea.Area->ActiveThermalTripPointVS2 = mSystemConfiguration.ActiveThermalTripPointVS2; + mGlobalNvsArea.Area->CriticalThermalTripPointVS2 = mSystemConfiguration.CriticalThermalTripPointVS2; + mGlobalNvsArea.Area->CriticalThermalTripPointVS2S3 = mSystemConfiguration.CriticalThermalTripPointVS2S3; + mGlobalNvsArea.Area->HotThermalTripPointVS2 = mSystemConfiguration.HotThermalTripPointVS2; + + mGlobalNvsArea.Area->ActiveThermalTripPointVS3 = mSystemConfiguration.ActiveThermalTripPointVS3; + mGlobalNvsArea.Area->CriticalThermalTripPointVS3 = mSystemConfiguration.CriticalThermalTripPointVS3; + mGlobalNvsArea.Area->CriticalThermalTripPointVS3S3 = mSystemConfiguration.CriticalThermalTripPointVS3S3; + mGlobalNvsArea.Area->HotThermalTripPointVS3 = mSystemConfiguration.HotThermalTripPointVS3; + + } else { + // + // Broxton-M only + // + mGlobalNvsArea.Area->EnableSen0Participant = mSystemConfiguration.EnableSen0Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointSen0 = mSystemConfiguration.PassiveThermalTripPointSen0; + mGlobalNvsArea.Area->CriticalThermalTripPointSen0 = mSystemConfiguration.CriticalThermalTripPointSen0; + mGlobalNvsArea.Area->CriticalThermalTripPointSen0S3 = mSystemConfiguration.CriticalThermalTripPointSen0S3; + mGlobalNvsArea.Area->HotThermalTripPointSen0 = mSystemConfiguration.HotThermalTripPointSen0; + + mGlobalNvsArea.Area->EnableSen1Participant = mSystemConfiguration.EnableSen1Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointSen1 = mSystemConfiguration.PassiveThermalTripPointSen1; + mGlobalNvsArea.Area->CriticalThermalTripPointSen1 = mSystemConfiguration.CriticalThermalTripPointSen1; + mGlobalNvsArea.Area->CriticalThermalTripPointSen1S3 = mSystemConfiguration.CriticalThermalTripPointSen1S3; + mGlobalNvsArea.Area->HotThermalTripPointSen1 = mSystemConfiguration.HotThermalTripPointSen1; + + mGlobalNvsArea.Area->EnableSen2Participant = mSystemConfiguration.EnableSen2Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointSen2 = mSystemConfiguration.PassiveThermalTripPointSen2; + mGlobalNvsArea.Area->CriticalThermalTripPointSen2 = mSystemConfiguration.CriticalThermalTripPointSen2; + mGlobalNvsArea.Area->CriticalThermalTripPointSen2S3 = mSystemConfiguration.CriticalThermalTripPointSen2S3; + mGlobalNvsArea.Area->HotThermalTripPointSen2 = mSystemConfiguration.HotThermalTripPointSen2; + + mGlobalNvsArea.Area->EnableSen3Participant = mSystemConfiguration.EnableSen3Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointSen3 = mSystemConfiguration.PassiveThermalTripPointSen3; + mGlobalNvsArea.Area->CriticalThermalTripPointSen3 = mSystemConfiguration.CriticalThermalTripPointSen3; + mGlobalNvsArea.Area->CriticalThermalTripPointSen3S3 = mSystemConfiguration.CriticalThermalTripPointSen3S3; + mGlobalNvsArea.Area->HotThermalTripPointSen3 = mSystemConfiguration.HotThermalTripPointSen3; + + mGlobalNvsArea.Area->DptfGenericCriticalTemperature0 = mSystemConfiguration.GenericCriticalTemp0; + mGlobalNvsArea.Area->DptfGenericPassiveTemperature0 = mSystemConfiguration.GenericPassiveTemp0; + mGlobalNvsArea.Area->DptfGenericCriticalTemperature1 = mSystemConfiguration.GenericCriticalTemp1; + mGlobalNvsArea.Area->DptfGenericPassiveTemperature1 = mSystemConfiguration.GenericPassiveTemp1; + mGlobalNvsArea.Area->DptfGenericCriticalTemperature3 = mSystemConfiguration.GenericCriticalTemp3; + mGlobalNvsArea.Area->DptfGenericPassiveTemperature3 = mSystemConfiguration.GenericPassiveTemp3; + mGlobalNvsArea.Area->DptfGenericCriticalTemperature4 = mSystemConfiguration.GenericCriticalTemp4; + mGlobalNvsArea.Area->DptfGenericPassiveTemperature4 = mSystemConfiguration.GenericPassiveTemp4; + + mGlobalNvsArea.Area->DptfWwanDevice = mSystemConfiguration.DptfWwanDevice; + mGlobalNvsArea.Area->PassiveThermalTripPointWWAN = mSystemConfiguration.PassiveThermalTripPointWWAN; + mGlobalNvsArea.Area->CriticalThermalTripPointWWANS3 = mSystemConfiguration.CriticalThermalTripPointWWANS3; + mGlobalNvsArea.Area->HotThermalTripPointWWAN = mSystemConfiguration.HotThermalTripPointWWAN; + mGlobalNvsArea.Area->CriticalThermalTripPointWWAN = mSystemConfiguration.CriticalThermalTripPointWWAN; + + } + + // + // Common code for Broxton-M and Broxton-P(ApolloLake) + // + mGlobalNvsArea.Area->EnableDCFG = mSystemConfiguration.EnableDCFG; + + // + // DPTF OEM Design Variables + // + mGlobalNvsArea.Area->OemDesignVariable0 = mSystemConfiguration.OemDesignVariable0; + mGlobalNvsArea.Area->OemDesignVariable1 = mSystemConfiguration.OemDesignVariable1; + mGlobalNvsArea.Area->OemDesignVariable2 = mSystemConfiguration.OemDesignVariable2; + mGlobalNvsArea.Area->OemDesignVariable3 = mSystemConfiguration.OemDesignVariable3; + mGlobalNvsArea.Area->OemDesignVariable4 = mSystemConfiguration.OemDesignVariable4; + mGlobalNvsArea.Area->OemDesignVariable5 = mSystemConfiguration.OemDesignVariable5; + + mGlobalNvsArea.Area->CriticalThermalTripPoint = mSystemConfiguration.CriticalThermalTripPoint; + mGlobalNvsArea.Area->PassiveThermalTripPoint = mSystemConfiguration.PassiveThermalTripPoint; + mGlobalNvsArea.Area->PassiveTc1Value = mSystemConfiguration.PassiveTc1Value; + mGlobalNvsArea.Area->PassiveTc2Value = mSystemConfiguration.PassiveTc2Value; + mGlobalNvsArea.Area->PassiveTspValue = mSystemConfiguration.PassiveTspValue; + mGlobalNvsArea.Area->DptfEnable = mSystemConfiguration.EnableDptf; + mGlobalNvsArea.Area->DptfProcessor = mSystemConfiguration.DptfProcessor; + mGlobalNvsArea.Area->DptfProcCriticalTemperature = mSystemConfiguration.DptfProcCriticalTemperature; + mGlobalNvsArea.Area->DptfProcPassiveTemperature = mSystemConfiguration.DptfProcPassiveTemperature; + mGlobalNvsArea.Area->DptfProcCriticalTemperatureS3 = mSystemConfiguration.DptfProcCriticalTemperatureS3; + mGlobalNvsArea.Area->DptfProcHotThermalTripPoint = mSystemConfiguration.DptfProcHotThermalTripPoint; + mGlobalNvsArea.Area->ThermalSamplingPeriodTCPU = mSystemConfiguration.ThermalSamplingPeriodTCPU; + mGlobalNvsArea.Area->EnablePowerParticipant = mSystemConfiguration.EnablePowerParticipant; + mGlobalNvsArea.Area->PowerParticipantPollingRate = mSystemConfiguration.PowerParticipantPollingRate; + mGlobalNvsArea.Area->DptfChargerDevice = mSystemConfiguration.DptfChargerDevice; + + mGlobalNvsArea.Area->DptfDisplayDevice = mSystemConfiguration.DptfDisplayDevice; + mGlobalNvsArea.Area->DisplayHighLimit = mSystemConfiguration.DisplayHighLimit; + mGlobalNvsArea.Area->DisplayLowLimit = mSystemConfiguration.DisplayLowLimit; + + mGlobalNvsArea.Area->EnableVS1Participant = mSystemConfiguration.EnableVS1Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointVS1 = mSystemConfiguration.PassiveThermalTripPointVS1; + + mGlobalNvsArea.Area->EnableVS2Participant = mSystemConfiguration.EnableVS2Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointVS2 = mSystemConfiguration.PassiveThermalTripPointVS2; + + mGlobalNvsArea.Area->EnableVS3Participant = mSystemConfiguration.EnableVS3Participant; + mGlobalNvsArea.Area->PassiveThermalTripPointVS3 = mSystemConfiguration.PassiveThermalTripPointVS3; + + // + // DPTF Policies + // + mGlobalNvsArea.Area->EnablePassivePolicy = mSystemConfiguration.EnablePassivePolicy; + mGlobalNvsArea.Area->EnableAPPolicy = mSystemConfiguration.EnableAPPolicy; + mGlobalNvsArea.Area->EnableCriticalPolicy = mSystemConfiguration.EnableCriticalPolicy; + mGlobalNvsArea.Area->EnablePowerBossPolicy = mSystemConfiguration.EnablePowerBossPolicy; + mGlobalNvsArea.Area->EnableVSPolicy = mSystemConfiguration.EnableVSPolicy; + + // + // Dump DPTF Settings + // + DEBUG((DEBUG_INFO, "Dumping DPTF settings in Global NVS init...\n")); + DEBUG((DEBUG_INFO, "DPTFEnabled = %d\n", mGlobalNvsArea.Area->DptfEnable)); + DEBUG((DEBUG_INFO, "DptfProcessor = %d\n", mGlobalNvsArea.Area->DptfProcessor)); + + if (GetBxtSeries() == Bxt1) { + mGlobalNvsArea.Area->WiGigEnable = mSystemConfiguration.WiGigEnable; + mGlobalNvsArea.Area->WiGigSPLCPwrLimit = mSystemConfiguration.WiGigSPLCPwrLimit; + mGlobalNvsArea.Area->WiGigSPLCTimeWindow = mSystemConfiguration.WiGigSPLCTimeWindow; + mGlobalNvsArea.Area->RfemSPLCPwrLimit = mSystemConfiguration.RfemSPLCPwrLimit; + mGlobalNvsArea.Area->RfemSPLCTimeWindow = mSystemConfiguration.RfemSPLCTimeWindow; + + mGlobalNvsArea.Area->PsmEnable = mSystemConfiguration.PsmEnable; + mGlobalNvsArea.Area->PsmSPLC0DomainType = mSystemConfiguration.PsmSPLC0DomainType; + mGlobalNvsArea.Area->PsmSPLC0PwrLimit = mSystemConfiguration.PsmSPLC0PwrLimit; + mGlobalNvsArea.Area->PsmSPLC0TimeWindow = mSystemConfiguration.PsmSPLC0TimeWindow; + mGlobalNvsArea.Area->PsmSPLC1DomainType = mSystemConfiguration.PsmSPLC1DomainType; + mGlobalNvsArea.Area->PsmSPLC1PwrLimit = mSystemConfiguration.PsmSPLC1PwrLimit; + mGlobalNvsArea.Area->PsmSPLC1TimeWindow = mSystemConfiguration.PsmSPLC1TimeWindow; + + mGlobalNvsArea.Area->PsmDPLC0DomainType = mSystemConfiguration.PsmDPLC0DomainType; + mGlobalNvsArea.Area->PsmDPLC0DomainPerference = mSystemConfiguration.PsmDPLC0DomainPerference; + mGlobalNvsArea.Area->PsmDPLC0PowerLimitIndex = mSystemConfiguration.PsmDPLC0PowerLimitIndex; + mGlobalNvsArea.Area->PsmDPLC0PwrLimit = mSystemConfiguration.PsmDPLC0PwrLimit; + mGlobalNvsArea.Area->PsmDPLC0TimeWindow = mSystemConfiguration.PsmDPLC0TimeWindow; + + mGlobalNvsArea.Area->PsmDPLC1DomainType = mSystemConfiguration.PsmDPLC1DomainType; + mGlobalNvsArea.Area->PsmDPLC1DomainPerference = mSystemConfiguration.PsmDPLC1DomainPerference; + mGlobalNvsArea.Area->PsmDPLC1PowerLimitIndex = mSystemConfiguration.PsmDPLC1PowerLimitIndex; + mGlobalNvsArea.Area->PsmDPLC1PwrLimit = mSystemConfiguration.PsmDPLC1PwrLimit; + mGlobalNvsArea.Area->PsmDPLC1TimeWindow = mSystemConfiguration.PsmDPLC1TimeWindow; + } + + // + // Dump Settings. + // + DEBUG((DEBUG_INFO, "OFFSET_OF BacklightControlSupport = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,BacklightControlSupport))); + DEBUG((DEBUG_INFO, "OFFSET_OF WorldCameraSel = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,WorldCameraSel))); + DEBUG((DEBUG_INFO, "OFFSET_OF I2C61Len = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,I2C61Len))); + DEBUG((DEBUG_INFO, "OFFSET_OF PepList = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,PepList))); + DEBUG((DEBUG_INFO, "OFFSET_OF PlatformFlavor = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,PlatformFlavor))); + DEBUG((DEBUG_INFO, "OFFSET_OF WorldCameraSel = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,WorldCameraSel))); + DEBUG((DEBUG_INFO, "OFFSET_OF I2C61Len = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,I2C61Len))); + DEBUG((DEBUG_INFO, "OFFSET_OF PepList = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,PepList))); + DEBUG((DEBUG_INFO, "OFFSET_OF SPI1Addr = %d\n", OFFSET_OF(EFI_GLOBAL_NVS_AREA,SPI1Addr))); + + // + // PCIe Native Mode + // + mGlobalNvsArea.Area->NativePCIESupport = mSystemConfiguration.PciExpNative; + // + // Low Power S0 Idle - Enabled/Disabled + // + mGlobalNvsArea.Area->LowPowerS0Idle = mSystemConfiguration.LowPowerS0Idle; + // + // Kernel Debugger Enable/Disable + // + mGlobalNvsArea.Area->OsDbgEnable = mSystemConfiguration.OsDbgEnable; + + // + // + // Platform Flavor + // + mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor; + // + // Update the Platform id + // + mGlobalNvsArea.Area->BoardId = mPlatformInfo->BoardId; + // + // Update the Platform id + // + mGlobalNvsArea.Area->BoardRev = mPlatformInfo->BoardRev; + + mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.ScUsb30Mode; + // + // PMIC is enabled by default. When it is disabled, we will not expose it in DSDT. + // + mGlobalNvsArea.Area->PmicEnable = mSystemConfiguration.PmicEnable; + mGlobalNvsArea.Area->BatteryChargingSolution = mSystemConfiguration.BatteryChargingSolution; + // + // If I-unit is fused off set the IPU ACPI mode to disabled. + // + Data32 = MmioRead32 (MmPciBase (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN) + R_SA_MC_CAPID0_B); + if (Data32 & BIT31) { + DEBUG ((DEBUG_INFO, "IPU Fused off\n")); + mGlobalNvsArea.Area->IpuAcpiMode = 2; //No IGFX + } else if (mSystemConfiguration.IpuEn == 0) { + DEBUG ((DEBUG_INFO, "IPU function disabled\n")); + mGlobalNvsArea.Area->IpuAcpiMode = 0; //IGFX disabled + } else { + mGlobalNvsArea.Area->IpuAcpiMode = mSystemConfiguration.IpuAcpiMode; + } + + mGlobalNvsArea.Area->ModemSel = mSystemConfiguration.ModemSel; + mGlobalNvsArea.Area->GpsModeSel = mSystemConfiguration.GpsModeSel; + + + mGlobalNvsArea.Area->BxtStepping = BxtStepping (); + DEBUG((DEBUG_INFO, "GlobalNvsArea.Area->BxtStepping: 0x%x;\n", mGlobalNvsArea.Area->BxtStepping)); + + if (mSystemConfiguration.ScHdAudioPostProcessingMod[29]) { + DEBUG ((DEBUG_INFO,"HDA: AudioDSP Pre/Post-Processing custom module 'Alpha' enabled (BIT29)\n")); + CopyMem (LocalGuidString, mSystemConfiguration.ScHdAudioPostProcessingModCustomGuid1, GUID_CHARS_NUMBER * sizeof (CHAR16)); + GuidStringToAcpiBuffer (LocalGuidString, &AcpiGuidPart1, &AcpiGuidPart2); + mGlobalNvsArea.Area->HdaDspPpModCustomGuid1Low = AcpiGuidPart1; + mGlobalNvsArea.Area->HdaDspPpModCustomGuid1High = AcpiGuidPart2; + DEBUG ((DEBUG_INFO,"HdaDspPpModCustomGuid1Low = 0x%016Lx\nHdaDspPpModCustomGuid2High = 0x%016Lx\n", + mGlobalNvsArea.Area->HdaDspPpModCustomGuid1Low, mGlobalNvsArea.Area->HdaDspPpModCustomGuid1High)); + } + + if (mSystemConfiguration.ScHdAudioPostProcessingMod[30]) { + DEBUG ((DEBUG_INFO,"HDA: AudioDSP Pre/Post-Processing custom module 'Beta' enabled (BIT30)\n")); + CopyMem (LocalGuidString, mSystemConfiguration.ScHdAudioPostProcessingModCustomGuid2, GUID_CHARS_NUMBER * sizeof (CHAR16)); + GuidStringToAcpiBuffer (LocalGuidString, &AcpiGuidPart1, &AcpiGuidPart2); + mGlobalNvsArea.Area->HdaDspPpModCustomGuid2Low = AcpiGuidPart1; + mGlobalNvsArea.Area->HdaDspPpModCustomGuid2High = AcpiGuidPart2; + DEBUG ((DEBUG_INFO,"HdaDspPpModCustomGuid2Low = 0x%016Lx\nHdaDspPpModCustomGuid2High = 0x%016Lx\n", + mGlobalNvsArea.Area->HdaDspPpModCustomGuid2Low, mGlobalNvsArea.Area->HdaDspPpModCustomGuid2High)); + } + + if (mSystemConfiguration.ScHdAudioPostProcessingMod[31]) { + DEBUG ((DEBUG_INFO,"HDA: AudioDSP Pre/Post-Processing custom module 'Gamma' enabled (BIT31)\n")); + CopyMem (LocalGuidString, mSystemConfiguration.ScHdAudioPostProcessingModCustomGuid3, GUID_CHARS_NUMBER * sizeof (CHAR16)); + GuidStringToAcpiBuffer (LocalGuidString, &AcpiGuidPart1, &AcpiGuidPart2); + mGlobalNvsArea.Area->HdaDspPpModCustomGuid3Low = AcpiGuidPart1; + mGlobalNvsArea.Area->HdaDspPpModCustomGuid3High = AcpiGuidPart2; + DEBUG ((DEBUG_INFO,"HdaDspPpModCustomGuid3Low = 0x%016Lx\nHdaDspPpModCustomGuid3High = 0x%016Lx\n", + mGlobalNvsArea.Area->HdaDspPpModCustomGuid3Low, mGlobalNvsArea.Area->HdaDspPpModCustomGuid3High)); + } + +#if (ENBDT_PF_ENABLE == 1) + // + // Install ACPI interface for Intel Ready Mode Technology (IRMT) + // + if (mSystemConfiguration.IrmtConfiguration == 1) { + // + // Initialize the Irmt configuration in ACPI GNVS + // + mGlobalNvsArea.Area->IrmtCfg = BIT0; // Irmt Enabled + } + + // + // Uninstall RTD3 table if it is disabled + // + if (mSystemConfiguration.Rtd3Support == 0) { + // + // Register for OnReadyToBoot event + // + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBootUninstallRtd3SSDTAcpiTable, + NULL, + &Event + ); + } +#endif + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiGlobalNvsAreaProtocolGuid, + &mGlobalNvsArea, + NULL + ); + + // + // Read tables from the storage file. + // + while (!EFI_ERROR (Status)) { + CurrentTable = NULL; + + Status = FwVol->ReadSection ( + FwVol, + &gEfiAcpiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + (VOID **) &CurrentTable, + (UINTN *) &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + // + // Allow platform specific code to reject the table or update it + // + AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable); + + if (!EFI_ERROR (AcpiStatus)) { + // + // Perform any table specific updates. + // + AcpiStatus = PlatformUpdateTables (CurrentTable); + + if (!EFI_ERROR (AcpiStatus)) { + // + // Add the table + // + TableHandle = 0; + AcpiStatus = AcpiSupport->SetAcpiTable ( + AcpiSupport, + CurrentTable, + TRUE, + TableVersion, + &TableHandle + ); + ASSERT_EFI_ERROR (AcpiStatus); + } else { + DEBUG ((EFI_D_ERROR, "Skip %x\n", CurrentTable)); + } + } + // + // Increment the instance + // + Instance ++; + } + } + + Status = InstallAcpiTableForPlatformSsdt (FwVol, AcpiSupport); + if (Status != EFI_SUCCESS){ + DEBUG ((EFI_D_ERROR, "UBMS SSDT - Not found \n" )); + } + + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &Event + ); + // + // Finished + // + return EFI_SUCCESS; +} + + +/** + This function updates the UART 2 device base address in the DBG ACPI table. + + @param[in] AcpiSupport Instance of the ACPI Support protocol. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The requested table does not exist. + +**/ +EFI_STATUS +UpdateDbg2Table ( + IN EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport + ) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_DEBUG_PORT_2_TABLE *Dbg2Table; + EFI_ACPI_TABLE_VERSION Version; + SYSTEM_CONFIGURATION SetupVarBuffer; + UINTN VariableSize; + UINTN Handle; + UINT8 Index = 0; + UINTN Uart2BaseAddressRegister = 0; + + // + // Find the DBG2 ACPI table + // + do { + Status = AcpiSupport->GetAcpiTable(AcpiSupport, Index, (VOID **) &Table, &Version, &Handle); + Index++; + } while (Table->Signature != EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_SIGNATURE); + + if (Status == EFI_NOT_FOUND) { + return EFI_NOT_FOUND; + } + + Dbg2Table = (EFI_ACPI_DEBUG_PORT_2_TABLE *) Table; + + // + // Update the UART2 BAR in the DBG2 ACPI table + // + Uart2BaseAddressRegister = MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_LPSS_HSUART, + PCI_FUNCTION_NUMBER_LPSS_HSUART2, + R_LPSS_IO_BAR + ); + + VariableSize = sizeof (SYSTEM_CONFIGURATION); + + Status = gRT->GetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + NULL, + &VariableSize, + &SetupVarBuffer + ); + ASSERT_EFI_ERROR (Status); + if (SetupVarBuffer.OsDbgEnable && (MmioRead32 (Uart2BaseAddressRegister) != 0xFFFFFFFF)) { + Dbg2Table->DbgDeviceInfoCom1.BaseAddressRegister->Address = MmioRead32 (Uart2BaseAddressRegister) & B_LPSS_IO_BAR_BA; + + DEBUG ((DEBUG_INFO, "UART2 Base Address in DBG2 ACPI Table: 0x%x\n", Dbg2Table->DbgDeviceInfoCom1.BaseAddressRegister->Address)); + + if (GetBxtSeries() == Bxt || GetBxtSeries() == Bxt1) { + SideBandAndThenOr32 ( + 0xC6, + 0x0F38, + 0xFFFFFFFF, + BIT0 + ); + } + + Status = AcpiSupport->SetAcpiTable ( + AcpiSupport, + Dbg2Table, + TRUE, + Version, + &Handle + ); + + ASSERT_EFI_ERROR (Status); + } else { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +/** + This function updates the UART 2 device base address in the DBGP ACPI table. + + @param[in] AcpiSupport Instance of the ACPI Support protocol. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The requested table does not exist. + +**/ +EFI_STATUS +UpdateDbgpTable ( + IN EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport +) +{ + EFI_STATUS Status; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_DEBUG_PORT_DESCRIPTION_TABLE *DbgTable; + EFI_ACPI_TABLE_VERSION Version; + SYSTEM_CONFIGURATION SetupVarBuffer; + UINTN VariableSize; + UINTN Handle; + UINT8 Index = 0; + UINTN Uart2BaseAddressRegister = 0; + + // + // Find the DBGP ACPI table + // + do { + Status = AcpiSupport->GetAcpiTable(AcpiSupport, Index, (VOID **) &Table, &Version, &Handle); + Index++; + } while (Table->Signature != EFI_ACPI_5_0_DEBUG_PORT_TABLE_SIGNATURE); + + if (Status == EFI_NOT_FOUND) { + return EFI_NOT_FOUND; + } + + DbgTable = (EFI_ACPI_DEBUG_PORT_DESCRIPTION_TABLE *) Table; + + // + // Update the UART2 BAR in the DBGP ACPI table + // + Uart2BaseAddressRegister = MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_LPSS_HSUART, + PCI_FUNCTION_NUMBER_LPSS_HSUART2, + R_LPSS_IO_BAR + ); + + VariableSize = sizeof (SYSTEM_CONFIGURATION); + Status = gRT->GetVariable ( + L"Setup", + &gEfiSetupVariableGuid, + NULL, + &VariableSize, + &SetupVarBuffer + ); + ASSERT_EFI_ERROR (Status); + if (SetupVarBuffer.OsDbgEnable && (MmioRead32 (Uart2BaseAddressRegister) != 0xFFFFFFFF)) { + DbgTable->BaseAddress.Address = MmioRead32 (Uart2BaseAddressRegister) & B_LPSS_IO_BAR_BA; + + DEBUG ((DEBUG_INFO, "UART2 Base Address in DBGP ACPI Table: 0x%x\n", DbgTable->BaseAddress.Address)); + + if (GetBxtSeries() == Bxt || GetBxtSeries() == Bxt1) { + SideBandAndThenOr32 ( + 0xC6, + 0x0F38, + 0xFFFFFFFF, + BIT0 + ); + } + + Status = AcpiSupport->SetAcpiTable ( + AcpiSupport, + DbgTable, + TRUE, + Version, + &Handle + ); + + ASSERT_EFI_ERROR (Status); + } else { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +/** + Publish WatchDog Action ACPI Table + + @retval EFI_SUCCESS The WatchDog Action ACPI table is published successfully. + @retval Others The WatchDog Action ACPI table is not published. + +**/ +EFI_STATUS +PublishWatchDogActionTable ( + VOID + ) +{ + EFI_STATUS Status; + UINT16 AcpiBase; + UINT32 Value; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + UINTN TableKey; + + // + // Enable reset on TCO time out + // + MmioAnd8 (PMC_BASE_ADDRESS + R_PMC_PM_CFG, (UINT8) ~B_PMC_PM_CFG_NO_REBOOT); + + // + // Read ACPI Base Address + // + AcpiBase = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Construct WatchDog Action Table + // + + // + // Set Watchdog Flags + // + mWatchDogActionTableAcpiTemplate.Table.WatchdogFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_STOPPED_IN_SLEEP_STATE; + + Value = IoRead32 (AcpiBase + R_SMI_EN) & B_SMI_EN_TCO; + if (Value) { + // + // TCO is enabled + // + mWatchDogActionTableAcpiTemplate.Table.WatchdogFlags |= EFI_ACPI_WDAT_1_0_WATCHDOG_ENABLED; + } + + EntryNumber = 0; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_RESET + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_RESET; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_WRITE_VALUE | EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_PRESERVE_REGISTER; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x0A; // 10 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_RLD; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x04; // It can be Any value + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x3FF; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_COUNTDOWN_PERIOD + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_COUNTDOWN_PERIOD; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_WRITE_COUNTDOWN | EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_PRESERVE_REGISTER; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x0A; // 10 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x10; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_TMR; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x3FF; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x3FF; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_QUERY_RUNNING_STATE + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_QUERY_RUNNING_STATE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_READ_VALUE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x01; // 1 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x0B; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_CNT; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x01; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_RUNNING_STATE + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_RUNNING_STATE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_WRITE_VALUE | EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_PRESERVE_REGISTER; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x01; // 1 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x0B; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_CNT; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x01; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_QUERY_STOPPED_STATE + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_QUERY_STOPPED_STATE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_READ_VALUE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x01; // 1 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x0B; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_CNT; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x01; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x01; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_STOPPED_STATE + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_STOPPED_STATE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_WRITE_VALUE | EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_PRESERVE_REGISTER; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x01; // 1 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x0B; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_CNT; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x01; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x01; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_QUERY_WATCHDOG_STATUS + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_QUERY_WATCHDOG_STATUS; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_READ_VALUE; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x01; // 1 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x11; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_STS; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x01; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x01; + EntryNumber ++; + // + // Watchdog action EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_WATCHDOG_STATUS + // + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].WatchdogAction = EFI_ACPI_WDAT_1_0_WATCHDOG_ACTION_SET_WATCHDOG_STATUS; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].InstructionFlags = EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_WRITE_VALUE | EFI_ACPI_WDAT_1_0_WATCHDOG_INSTRUCTION_PRESERVE_REGISTER; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[0] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Reserved_2[1] = 0x00; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.AddressSpaceId = 0x01; // 0 System Memory, 1 System IO + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitWidth = 0x01; // 1 bit + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.RegisterBitOffset = 0x11; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Reserved = 0x03; // AccessSize, Dword Access + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].RegisterRegion.Address = AcpiBase + R_TCO_STS; + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Value = 0x01; // Write '1' to clear + mWatchDogActionTableAcpiTemplate.Entry[EntryNumber].Mask = 0x01; + EntryNumber ++; + // + // Set Length and Entry number + // + mWatchDogActionTableAcpiTemplate.Table.Header.Length = sizeof (EFI_ACPI_WATCHDOG_ACTION_1_0_TABLE) + EntryNumber * sizeof (EFI_ACPI_WATCHDOG_ACTION_1_0_WATCHDOG_ACTION_INSTRUCTION_ENTRY); + mWatchDogActionTableAcpiTemplate.Table.NumberWatchdogInstructionEntries = EntryNumber; + + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO,"Installing WDAT...\n")); + // + // Install ACPI table + // + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + &mWatchDogActionTableAcpiTemplate, + mWatchDogActionTableAcpiTemplate.Table.Header.Length, + &TableKey + ); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO,"Install WDAT %r\n", Status)); + + return Status; +} + + +UINT8 +ReadCmosBank1Byte ( + IN EFI_CPU_IO2_PROTOCOL *CpuIo, + IN UINT8 Index + ) +{ + UINT8 Data; + + CpuIo->Io.Write (CpuIo, EfiCpuIoWidthUint8, 0x72, 1, &Index); + CpuIo->Io.Read (CpuIo, EfiCpuIoWidthUint8, 0x73, 1, &Data); + + return Data; +} + + +VOID +WriteCmosBank1Byte ( + IN EFI_CPU_IO2_PROTOCOL *CpuIo, + IN UINT8 Index, + IN UINT8 Data + ) +{ + CpuIo->Io.Write (CpuIo, EfiCpuIoWidthUint8, 0x72, 1, &Index); + CpuIo->Io.Write (CpuIo, EfiCpuIoWidthUint8, 0x73, 1, &Data); +} + diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.h b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.h new file mode 100644 index 0000000000..727cf0b567 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatform.h @@ -0,0 +1,304 @@ +/** @file + This is an implementation of the ACPI platform driver. Requirements for + this driver are defined in the Tiano ACPI External Product Specification, + revision 0.3.6. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef _ACPI_PLATFORM_H_ +#define _ACPI_PLATFORM_H_ + +// +// Statements that include other header files +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CMOSMap.h" + +#include +#include +#include +#include +#include +#include +#include + +// +// Global variables +// +EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + +// +// ACPI table information used to initialize tables. +// +// SLP 2.0 equates +// +#define SLP20_MAGIC_NUMBER 0x00000001 +#define SLP20_VERIFIED_INDICATOR 0x91827364 +#define EFI_ACPI_OEM_REVISION 0x00000003 +#define EFI_ACPI_CREATOR_ID SIGNATURE_32 ('B', 'R', 'X', 'T') +#define EFI_ACPI_CREATOR_REVISION 0x0100000D + +#define WPCN381U_CONFIG_INDEX 0x2E +#define WPCN381U_CONFIG_DATA 0x2F +#define WPCN381U_CHIP_ID 0xF4 +#define WDCP376_CHIP_ID 0xF1 + +#define MOBILE_PLATFORM 1 +#define DESKTOP_PLATFORM 2 + +#define DUAL_CORE_CONFIG 2 + +#define KBC_DATA_PORT 0x60 +#define KBC_CMD_STS_PORT 0x64 + +// +// 8042 Command +// +#define READ_CMD_BYTE 0x20 +#define WRITE_CMD_BYTE 0x60 +#define DISABLE_AUX 0xa7 +#define ENABLE_AUX 0xa8 +#define DISABLE_KB 0xad +#define ENABLE_KB 0xae +#define WRITE_AUX_DEV 0xd4 +#define READ_ID_CMD 0xf2 +#define ENABLE_CMD 0xf4 +#define CMD_KB_STS 0x10 +#define CMD_KB_DIS 0x10 +#define CMD_AUX_STS 0x20 +#define CMD_AUX_DIS 0x20 + +#define PS2_ACK 0xfa +#define PS2_RESEND 0xfe + +#define KBC_INPB 0x02 +#define KBC_OUTB 0x01 +#define KBC_AUXB 0x20 + +#define TIMEOUT 50000 +#define BAT_TIMEOUT 500000 + +// +// +++++++++++++++++++++++++++++++++++++++++++++++++++ +// ESS - GV3 Definitions +// +++++++++++++++++++++++++++++++++++++++++++++++++++ +// +#pragma pack(1) + +typedef struct { + UINT32 PlatformId; + UINT8 IoApicEnable; + UINT8 NMEN; // Node Manager Enable (aka NPTM) + UINT8 TpmEnable :1; + UINT8 CStateEnable :1; + UINT8 OSC2Report :1; + UINT8 C6Enable :1; + UINT8 C7Enable :1; + UINT8 MonitorMwaitEnable :1; + UINT8 PStateEnable :1; + UINT8 Rsvd :1; + UINT8 PSDT :2; // P-State Dependency Type + UINT8 StandbyToS1 :1; + UINT8 KBPresent :1; + UINT8 MousePresent :1; + UINT8 DualIohPresent :1; + UINT8 DummyBits :2; + UINT32 CpuIdInfo; // Used in PciCrs.asl to determine Havendale/Lynnfield Processor + UINT32 Tolm; // Used in PciCrs.asl + UINT16 OsSelect; // O/S Type. This is for ASL only. + UINT32 IgdOpRegionAddress; // IGD OpRegion Starting Address + UINT8 IgdBootType; // IGD Boot Display Device + UINT8 IgdPanelType; // IGD Panel Type CMOs option + UINT8 IgdTvFormat; // IGD TV Format CMOS option + UINT8 IgdTvMinor; // IGD TV Minor Format CMOS option + UINT8 IgdPanelScaling; // IGD Panel Scaling + UINT8 IgdBlcConfig; // IGD BLC Configuration + UINT8 IgdBiaConfig; // IGD BIA Configuration + UINT8 IgdSscConfig; // IGD SSC Configuration + UINT8 IgdDvmtMemSize; // IGD DVMT Memory Size + UINT8 IgdFunc1Enable; // IGD Function 1 Enable + UINT8 IgdHpllVco; // HPLL VCO + UINT8 IgdSciSmiMode; // GMCH SMI/SCI mode (0=SCI) + UINT8 IgdPAVP; // IGD PAVP data +} BIOS_ACPI_PARAM; + +typedef struct _AML_GV3_STATE_PACKAGE { + UINT8 PkgOp; // 0x12 + UINT8 PkgLeadByte; + UINT8 NoData; + UINT8 DWPrefix0; + UINT32 CoreFreq; + UINT8 DWPrefix1; + UINT32 PowerConsumption; + UINT8 DWPrefix2; + UINT32 TransactionLatency; + UINT8 DWPrefix3; + UINT32 BusMasterLatency; + UINT8 DWPrefix4; + UINT32 ControlValue; + UINT8 DWPrefix5; + UINT32 StatusValue; +} AML_GV3_STATE_PACKAGE; + +typedef struct _AML_PSS_PACKAGE { + UINT8 NameOp; // 0x08 + UINT8 Sign[4]; + UINT8 PkgOp; // 0x12 + UINT8 Res1[2]; + UINT8 NoOfGV3Packages; + AML_GV3_STATE_PACKAGE Pstates[16]; +} AML_PSS_PACKAGE; + +typedef struct _SMM_APICID_MAP { + UINT32 ApicID; + UINT16 PhysicalCpuNumber; + UINT16 CpuNumber; + UINT16 Version; +} SMM_APICID_MAP; + +typedef struct _SMM_GV3_FVID { + UINT16 VidValue : 8; + UINT16 FreqRatio : 8; + UINT16 SystemBusFreq : 16; +} SMM_GV3_FVID; + +// +// APCI Watchdog Action Table (WDAT) +// +#define WATCHDOG_ACTION_INSTRUCTION_ENTRY_MAX_NUMBER 0x0E + +typedef struct { + EFI_ACPI_WATCHDOG_ACTION_1_0_TABLE Table; + EFI_ACPI_WATCHDOG_ACTION_1_0_WATCHDOG_ACTION_INSTRUCTION_ENTRY Entry[WATCHDOG_ACTION_INSTRUCTION_ENTRY_MAX_NUMBER]; +} EFI_ACPI_WATCHDOG_ACTION_TABLE; + +#pragma pack() + +#define GV3_SSDT_OEM_TABLE_IDBASE 0x4000 + +// +// Private Driver Data +// +// +// Define Union of IO APIC & Local APIC structure; +// +typedef union { + EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic; + EFI_ACPI_2_0_IO_APIC_STRUCTURE AcpiIoApic; + struct { + UINT8 Type; + UINT8 Length; + } AcpiApicCommon; +} ACPI_APIC_STRUCTURE_PTR; + +// +// Protocol private structure definition +// +/** + Entry point of the ACPI platform driver. + + @param[in] ImageHandle A handle for the image that is initializing this driver. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS Driver initialized successfully. + @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. + +**/ +EFI_STATUS +InstallAcpiPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Get Acpi Table Version. + +**/ +EFI_ACPI_TABLE_VERSION +GetAcpiTableVersion ( + VOID + ); + +/** + The function returns OEM specific information of Acpi Platform. + + @param[out] OemId OemId returned. + @param[out] OemTableId OemTableId returned. + @param[out] OemRevision OemRevision returned. + + @retval EFI_STATUS Status of function execution. + +**/ +EFI_STATUS +AcpiPlatformGetOemFields ( + OUT UINT8 *OemId, + OUT UINT64 *OemTableId, + OUT UINT32 *OemRevision + ); + +/** + The function returns Acpi Setting. + + @retval Acpi table version encoded as a UINT32. + +**/ +EFI_ACPI_TABLE_VERSION +AcpiPlatformGetAcpiSetting ( + VOID + ); + +/** + Entry point for Acpi platform driver. + + @param[in] ImageHandle A handle for the image that is initializing this driver. + @param[in] SystemTable A pointer to the EFI system table. + + @retval EFI_SUCCESS Driver initialized successfully. + @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. + +**/ +EFI_STATUS +EFIAPI +AcpiPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +IrmtDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf new file mode 100644 index 0000000000..cf862fc88d --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -0,0 +1,91 @@ +## @file +# ACPI Platform Driver. +# +# Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+# +# 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. +# +## + +[defines] + INF_VERSION = 0x00010005 + BASE_NAME = AcpiPlatform + FILE_GUID = 1DFFE9F3-7B5F-4B44-8EBD-39A739EBA903 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = AcpiPlatformEntryPoint + +[sources.common] + AcpiPlatformHooks.c + AcpiPlatform.c + +[Packages] + BroxtonPlatformPkg/PlatformPkg.dec + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + MdeModulePkg/MdeModulePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + HobLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + BaseMemoryLib + DebugLib + HobLib + IoLib + SideBandLib + DxeVtdLib + SteppingLib + SeCLib + +[Guids] + gACPIOSFRMfgStringVariableGuid + gEfiAcpiTableStorageGuid + gSLP20EncryptedOEMPublicKeyVariableGuid + gEfiPlatformInfoGuid + gEfiSetupVariableGuid + gSLP20MarkerVariableGuid + gSLP20OEMPublicKeyVariableGuid + gACPIOSFRRefDataBlockVariableGuid + gACPIOSFRModelStringVariableGuid + gEfiPlatformCpuInfoGuid + gPramAddrDataGuid + gEfiNorthPeakGuid + gEfiBxtVariableGuid + gEfiPramConfGuid + gPlatformSsdtImageGuid + +[Protocols] + gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEnhancedSpeedstepProtocolGuid + gEfiPlatformCpuProtocolGuid + gEfiAcpiSupportProtocolGuid + gEfiAcpiS3SaveProtocolGuid + gEfiCpuIo2ProtocolGuid + gEfiFirmwareVolume2ProtocolGuid + gEfiMpServiceProtocolGuid + gEfiGlobalNvsAreaProtocolGuid + gEfiDpsdRSA1024AndSHA256SignatureVerificationProtocolGuid + gEfiTcgProtocolGuid + gEfiFirmwareVolume2ProtocolGuid + gEfiSeCOperationProtocolGuid + +[Pcd] + gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress + gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + +[Depex] + gEfiAcpiSupportProtocolGuid AND + gEfiMpServiceProtocolGuid AND + gEfiCpuIo2ProtocolGuid AND + gEfiVariableWriteArchProtocolGuid AND + gEfiVariableArchProtocolGuid diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.c b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.c new file mode 100644 index 0000000000..7ad46fe1af --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.c @@ -0,0 +1,490 @@ +/** @file + ACPI Platform Driver Hooks. + + Copyright (c) 1996 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +// +// Statements that include other files +// +#include "AcpiPlatform.h" +#include "AcpiPlatformHooks.h" +#include "Platform.h" +#include + +// +// Prototypes of the various hook functions. +// +#include "AcpiPlatformHooksLib.h" + +extern EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + +extern SYSTEM_CONFIGURATION mSystemConfiguration; + +ENHANCED_SPEEDSTEP_PROTOCOL *mEistProtocol = NULL; + + +// +// Global for the CPU I/O Protocol that is consumed by this driver +// +EFI_CPU_IO2_PROTOCOL *mCpuIo; + +EFI_CPU_ID_MAP mCpuApicIdAcpiIdMapTable[MAX_CPU_NUM]; + +EFI_STATUS +AppendCpuMapTableEntry ( + IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE *AcpiLocalApic + ) +{ + BOOLEAN Added; + UINTN Index; + + for (Index = 0; Index < MAX_CPU_NUM; Index ++) { + if ((mCpuApicIdAcpiIdMapTable[Index].ApicId == AcpiLocalApic->ApicId) && mCpuApicIdAcpiIdMapTable[Index].Flags) { + return EFI_SUCCESS; + } + } + + Added = FALSE; + for (Index = 0; Index < MAX_CPU_NUM; Index ++) { + if (!mCpuApicIdAcpiIdMapTable[Index].Flags) { + mCpuApicIdAcpiIdMapTable[Index].Flags = 1; + mCpuApicIdAcpiIdMapTable[Index].ApicId = AcpiLocalApic->ApicId; + mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId = AcpiLocalApic->AcpiProcessorId; + Added = TRUE; + break; + } + } + + ASSERT (Added); + return EFI_SUCCESS; +} + + +UINT32 +ProcessorId2ApicId ( + UINT32 AcpiProcessorId + ) +{ + UINTN Index; + + ASSERT (AcpiProcessorId < MAX_CPU_NUM); + for (Index = 0; Index < MAX_CPU_NUM; Index ++) { + if (mCpuApicIdAcpiIdMapTable[Index].Flags && (mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId == AcpiProcessorId)) { + return mCpuApicIdAcpiIdMapTable[Index].ApicId; + } + } + + return (UINT32) -1; +} + + +UINT8 +GetProcNumberInPackage ( + IN UINT8 Package + ) +{ + UINTN Index; + UINT8 Number; + + Number = 0; + for (Index = 0; Index < MAX_CPU_NUM; Index ++) { + if (mCpuApicIdAcpiIdMapTable[Index].Flags && (((mCpuApicIdAcpiIdMapTable[Index].ApicId >> 0x04) & 0x01) == Package)) { + Number++; + } + } + + return Number; +} + + +EFI_STATUS +LocateCpuEistProtocol ( + IN UINT32 CpuIndex, + OUT ENHANCED_SPEEDSTEP_PROTOCOL **EistProtocol + ) +{ + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + ENHANCED_SPEEDSTEP_PROTOCOL *EistProt; + UINTN Index; + UINT32 ApicId; + EFI_STATUS Status; + + HandleCount = 0; + gBS->LocateHandleBuffer ( + ByProtocol, + &gEnhancedSpeedstepProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + + Index = 0; + EistProt = NULL; + Status = EFI_NOT_FOUND; + while (Index < HandleCount) { + gBS->HandleProtocol ( + HandleBuffer[Index], + &gEnhancedSpeedstepProtocolGuid, + (VOID **) &EistProt + ); + // + // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based. + // + ApicId = ProcessorId2ApicId (CpuIndex+1); + if (ApicId == (UINT32) -1) { + break; + } + + if (EistProt->ProcApicId == ApicId) { + Status = EFI_SUCCESS; + break; + } + + Index++; + } + + if (HandleBuffer != NULL) { + gBS->FreePool (HandleBuffer); + } + + if (!EFI_ERROR (Status)) { + *EistProtocol = EistProt; + } else { + *EistProtocol = NULL; + } + + return Status; +} + + +EFI_STATUS +PlatformHookInit ( + VOID + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol ( + &gEnhancedSpeedstepProtocolGuid, + NULL, + (VOID **) &mEistProtocol + ); + + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +/** + Called for every ACPI table found in the BIOS flash. + Returns whether a table is active or not. Inactive tables + are not published in the ACPI table list. This hook can be + used to implement optional SSDT tables or enabling/disabling + specific functionality (e.g. SPCR table) based on a setup + switch or platform preference. In case of optional SSDT tables, + the platform flash will include all the SSDT tables but will + return EFI_SUCCESS only for those tables that need to be + published. + + @param[in] Table Pointer to the active table + + @retval EFI_SUCCESS The table is active. + @retval EFI_UNSUPPORTED The table is not active. + +**/ +EFI_STATUS +AcpiPlatformHooksIsActiveTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ) +{ + EFI_ACPI_DESCRIPTION_HEADER *TableHeader; + + TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table; + + if (TableHeader->Signature == EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE) { + + } + + return EFI_SUCCESS; +} + + +/** + Update the GV3 SSDT table + + @param[in, out] TableHeader The table to be set + + @retval EFI_SUCCESS Returns Success + +**/ +EFI_STATUS +PatchGv3SsdtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ) +{ + EFI_STATUS Status; + UINT8 *CurrPtr; + UINT8 *SsdtPointer; + UINT32 Signature; + UINT32 CpuFixes; + UINT32 NpssFixes; + UINT32 SpssFixes; + UINT32 CpuIndex; + UINT32 PackageSize; + UINT32 NewPackageSize; + UINT32 AdjustSize; + UINTN EntryIndex; + UINTN TableIndex; + EFI_ACPI_NAME_COMMAND *PssTable; + EFI_PSS_PACKAGE *PssTableItemPtr; + ENHANCED_SPEEDSTEP_PROTOCOL *EistProt; + EIST_INFORMATION *EistInfo; + EFI_ACPI_CPU_PSS_STATE *PssState; + EFI_ACPI_NAMEPACK_DWORD *NamePtr; + + // + // Loop through the ASL looking for values that we must fix up. + // + NpssFixes = 0; + SpssFixes = 0; + CpuFixes = 0; + CpuIndex = 0; + CurrPtr = (UINT8 *) TableHeader; + + EistProt = NULL; + for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) { + Signature = *(UINT32 *) SsdtPointer; + switch (Signature) { + + case SIGNATURE_32 ('_', 'P', 'R', '_'): + // + // _CPUX ('0' to '0xF') + // + CpuIndex = *(SsdtPointer + 7); + if (CpuIndex >= '0' && CpuIndex <= '9') { + CpuIndex -= '0'; + } else { + if (CpuIndex > '9') { + CpuIndex -= '7'; + } + } + + CpuFixes++; + LocateCpuEistProtocol (CpuIndex, &EistProt); + break; + + case SIGNATURE_32 ('D', 'O', 'M', 'N'): + + NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer); + if (NamePtr->StartByte != AML_NAME_OP) { + continue; + } + + if (NamePtr->Size != AML_NAME_DWORD_SIZE) { + continue; + } + + NamePtr->Value = 0; + + if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) { + NamePtr->Value = (mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01; + } + break; + + case SIGNATURE_32 ('N', 'C', 'P', 'U'): + + NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer); + if (NamePtr->StartByte != AML_NAME_OP) { + continue; + } + + if (NamePtr->Size != AML_NAME_DWORD_SIZE) { + continue; + } + + NamePtr->Value = 0; + if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) { + NamePtr->Value = GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01); + } + break; + + case SIGNATURE_32 ('N', 'P', 'S', 'S'): + case SIGNATURE_32 ('S', 'P', 'S', 'S'): + if (EistProt == NULL) { + continue; + } + + PssTable = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer); + if (PssTable->StartByte != AML_NAME_OP) { + continue; + } + + Status = EistProt->GetEistTable (EistProt, &EistInfo, (VOID **) &PssState); + + AdjustSize = PssTable->NumEntries * sizeof (EFI_PSS_PACKAGE); + AdjustSize -= EistInfo->NumStates * sizeof (EFI_PSS_PACKAGE); + PackageSize = (PssTable->Size & 0xF) + ((PssTable->Size & 0xFF00) >> 4); + NewPackageSize = PackageSize - AdjustSize; + PssTable->Size = (UINT16) ((NewPackageSize & 0xF) + ((NewPackageSize & 0x0FF0) << 4)); + + // + // Set most significant two bits of byte zero to 01, meaning two bytes used + // + PssTable->Size |= 0x40; + + // + // Set unused table to Noop Code + // + SetMem( (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE, AdjustSize, AML_NOOP_OP); + PssTable->NumEntries = (UINT8) EistInfo->NumStates; + PssTableItemPtr = (EFI_PSS_PACKAGE *) ((UINT8 *) PssTable + sizeof (EFI_ACPI_NAME_COMMAND)); + + // + // Update the size + // + for (TableIndex = 0; TableIndex < EistInfo->NumStates; TableIndex++) { + EntryIndex = EistInfo->NumStates - TableIndex - 1; + PssTableItemPtr->CoreFreq = PssState[EntryIndex].CoreFrequency * PssState[EntryIndex].Control; + PssTableItemPtr->Power = PssState[EntryIndex].Power * 1000; + if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) { + PssTableItemPtr->BMLatency = PssState[EntryIndex].BusMasterLatency; + PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency; + } else { + // + // This method should be supported by SMM PPM Handler + // + PssTableItemPtr->BMLatency = PssState[EntryIndex].BusMasterLatency * 2; + PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency * 10; + } + + PssTableItemPtr->Control = PssState[EntryIndex].Control; + PssTableItemPtr->Status = PssState[EntryIndex].Status; + PssTableItemPtr++; + } + + if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) { + NpssFixes++; + } else { + SpssFixes++; + } + + SsdtPointer = (UINT8 *) PssTable + PackageSize; + break; + } // switch + } // for + + // + // N fixes together currently + // + ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM); + ASSERT (SpssFixes == NpssFixes); + ASSERT (CpuFixes >= SpssFixes); + + return EFI_SUCCESS; +} + + +/** + Update the DSDT table. + + @param[in, out] TableHeader The table to be set + + @retval EFI_SUCCESS Returns EFI_SUCCESS + +**/ +EFI_STATUS +PatchDsdtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ) +{ + UINT8 *CurrPtr; + UINT8 *DsdtPointer; + UINT32 *Signature; + UINT8 *EndPtr; + UINT8 *Operation; + UINT32 *Address; + UINT16 *Size; + + // + // Fix PCI32 resource "FIX0" -- PSYS system status area + // + CurrPtr = (UINT8 *) & ((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)[0]; + EndPtr = (UINT8 *) TableHeader; + EndPtr = EndPtr + TableHeader->Length; + while (CurrPtr < (EndPtr-2)) { + // + // Removed the _S3 tag to indicate that we do not support S3. The 4th byte is blank space + // since there are only 3 char "_S3". + // + if (mSystemConfiguration.AcpiSuspendState == 0) { + // + // for iasl compiler version 20061109 + // + if ((CurrPtr[0] == '_') && (CurrPtr[1] == 'S') && (CurrPtr[2] == '3') && (CurrPtr[3] == '_')) { + break; + } + // + // for iasl compiler version 20040527 + // + if ((CurrPtr[0] == '\\') && (CurrPtr[1] == '_') && (CurrPtr[2] == 'S') && (CurrPtr[3] == '3')) { + break; + } + } + CurrPtr++; + } + + // + // 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) { + // + // GNVS operation region + // + case (SIGNATURE_32 ('G', '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; + + case SIGNATURE_32 ('B', 'P', 'R', 'W'): + // + // For BXT-M B-stepping Change 'B' in 'BPRW' to '_' + // + if (BxtStepping() >= BxtB0) { + DsdtPointer[0] = '_'; + } + break; + default: + break; + } // switch + } // for + + return EFI_SUCCESS; +} + + diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.h b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.h new file mode 100644 index 0000000000..30889de685 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooks.h @@ -0,0 +1,124 @@ +/** @file + This is an implementation of the ACPI platform driver. Requirements for + this driver are defined in the Tiano ACPI External Product Specification, + revision 0.3.6. + + Copyright (c) 1996 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef _ACPI_PLATFORM_HOOKS_H_ +#define _ACPI_PLATFORM_HOOKS_H_ + +// +// Statements that include other header files +// +#include +#include "Platform.h" +#include + +#define AML_NAME_OP 0x08 +#define AML_METHOD_OP 0x14 +#define AML_OPREGION_OP 0x80 +#define AML_PACKAGE_OP 0x12 // Package operator. +#define AML_NAME_PREFIX_SIZE 0x06 +#define AML_NAME_DWORD_SIZE 0x0C + +#pragma pack(1) + +typedef struct { + UINT8 AcpiProcessorId; + UINT8 ApicId; + UINT16 Flags; +} EFI_CPU_ID_MAP; + +typedef struct { + UINT8 StartByte; + UINT32 NameStr; + UINT8 Size; + UINT32 Value; +} EFI_ACPI_NAMEPACK_DWORD; + +typedef struct { + UINT8 StartByte; + UINT32 NameStr; + UINT8 OpCode; + UINT16 Size; // Hardcode to 16bit width because the table we use is fixed size + UINT8 NumEntries; +} EFI_ACPI_NAME_COMMAND; + +typedef struct { + UINT8 PackageOp; + UINT8 PkgLeadByte; + UINT8 NumEntries; + UINT8 DwordPrefix0; + UINT32 CoreFreq; + UINT8 DwordPrefix1; + UINT32 Power; + UINT8 DwordPrefix2; + UINT32 TransLatency; + UINT8 DwordPrefix3; + UINT32 BMLatency; + UINT8 DwordPrefix4; + UINT32 Control; + UINT8 DwordPrefix5; + UINT32 Status; +} EFI_PSS_PACKAGE; + +typedef struct { + UINT8 PackageOp; + UINT8 PkgLeadByte; + UINT8 NumEntries; + UINT8 BytePrefix0; + UINT8 Entries; + UINT8 BytePrefix1; + UINT8 Revision; + UINT8 BytePrefix2; + UINT8 Domain; + UINT8 BytePrefix3; + UINT8 Coordinate; + UINT8 BytePrefix4; + UINT8 ProcNumber; +} EFI_PSD_PACKAGE; + +#pragma pack() + +#define ACPI_NAME_COMMAND_FROM_NAME_STR(a) BASE_CR (a, EFI_ACPI_NAME_COMMAND, NameStr) +#define ACPI_NAME_COMMAND_FROM_NAMEPACK_STR(a) BASE_CR (a, EFI_ACPI_NAMEPACK_DWORD, NameStr) + +EFI_STATUS +PlatformHookInit ( + VOID + ); + +EFI_STATUS +PatchDsdtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader + ); + + +EFI_STATUS +PatchGv3SsdtTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table + ); + +EFI_STATUS +PatchErstTable ( + IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table + ); + +EFI_STATUS +AppendCpuMapTableEntry ( + IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE *AcpiLocalApic + ); + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooksLib.h b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooksLib.h new file mode 100644 index 0000000000..6fcd938151 --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/AcpiPlatformHooksLib.h @@ -0,0 +1,89 @@ +/** @file + This is an implementation of the ACPI platform driver. Requirements for + this driver are defined in the Tiano ACPI External Product Specification, + revision 0.3.6. + + Copyright (c) 1996 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef _ACPI_PLATFORM_HOOKS_LIB_H_ +#define _ACPI_PLATFORM_HOOKS_LIB_H_ + +// +// Statements that include other header files +// + +#include + + +/** + Returns the ACPI table version that the platform wants. + + @retval EFI_ACPI_TABLE_VERSION_NONE if ACPI is to be disabled + @retval EFI_ACPI_TABLE_VERSION_1_0B if 1.0b + @retval EFI_ACPI_TABLE_VERSION_2_00 if 2.00 + +**/ +EFI_ACPI_TABLE_VERSION +AcpiPlatformHooksGetAcpiTableVersion ( + VOID + ); + +/** + Returns the OEMID, OEM Table ID, OEM Revision. + + @param[out] OemId OEM ID string for ACPI tables, maximum 6 ASCII characters. + This is an OEM-supplied string that identifies the OEM. + @param[out] OemTableId An OEM-supplied string that the OEM uses to identify + the particular data table. This field is particularly useful + when defining a definition block to distinguish definition block + functions. The OEM assigns each dissimilar table a new OEM Table ID. + @param[out] OemRevision An OEM-supplied revision number for ACPI tables. + Larger numbers are assumed to be newer revisions. + +**/ +EFI_STATUS +AcpiPlatformHooksGetOemFields ( + OUT UINT8 *OemId, + OUT UINT64 *OemTableId, + OUT UINT32 *OemRevision + ); + +/** + Called for every ACPI table found in the BIOS flash. + Returns whether a table is active or not. Inactive tables + are not published in the ACPI table list. This hook can be + used to implement optional SSDT tables or enabling/disabling + specific functionality (e.g. SPCR table) based on a setup + switch or platform preference. In case of optional SSDT tables, + the platform flash will include all the SSDT tables but will + return EFI_SUCCESS only for those tables that need to be + published. + This hook can also be used to update the table data. The header + is updated by the common code. For example, if a platform wants + to use an SSDT table to export some platform settings to the + ACPI code, it needs to update the data inside that SSDT based + on platform preferences in this hook. + + @param[in] Table + + @retval EFI_SUCCESS The table is active + @retval EFI_UNSUPPORTED The table is not active + +**/ +EFI_STATUS +AcpiPlatformHooksIsActiveTable ( + IN OUT EFI_ACPI_COMMON_HEADER *Table + ); + +#endif + diff --git a/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/Osfr.h b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/Osfr.h new file mode 100644 index 0000000000..f351cb82ae --- /dev/null +++ b/Platform/BroxtonPlatformPkg/Common/Acpi/AcpiPlatformDxe/Osfr.h @@ -0,0 +1,53 @@ +/** @file + This file describes the contents of the ACPI OSFR Table. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef _OSFR_H +#define _OSFR_H + +// +// Statements that include other files +// +#include +#include + +#pragma pack (1) + +#define EFI_ACPI_OSFR_TABLE_REVISION 0x1 +#define EFI_ACPI_OSFR_TABLE_SIGNATURE SIGNATURE_32('O', 'S', 'F', 'R') //'RFSO' + +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 ObjectCount; + UINT32 TableDWORDs [64]; +} EFI_ACPI_OSFR_TABLE; + +typedef struct { + EFI_ACPI_DESCRIPTION_HEADER Header; + UINT32 ObjectCount; +} EFI_ACPI_OSFR_TABLE_FIXED_PORTION; + +typedef struct { + EFI_GUID ObjectUUID; + UINT32 Reserved1; + UINT32 ManufacturerNameStringOffset; + UINT32 ModelNameStringOffset; + UINT32 Reserved2; + UINT32 MicrosoftReferenceOffset; +} EFI_ACPI_OSFR_OCUR_OBJECT; + +#pragma pack () + +#endif + -- cgit v1.2.3