summaryrefslogtreecommitdiff
path: root/BraswellPlatformPkg/Common
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-08-03 09:43:39 +0800
committerGuo Mang <mang.guo@intel.com>2016-08-04 10:28:34 +0800
commit923b430effa8a55b6e5a1fcaa4fe385698231ecc (patch)
tree273c454ed7ee008868712764c9c9ed062e13ccc1 /BraswellPlatformPkg/Common
parentd3c42e0e5752c01b7d41a58c218ea7fc1dad23fa (diff)
downloadedk2-platforms-923b430effa8a55b6e5a1fcaa4fe385698231ecc.tar.xz
BraswellPlatformPkg: Move Acpi to Common/Acpi
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com> Reviewed-by: David Wei <david.wei@intel.com>
Diffstat (limited to 'BraswellPlatformPkg/Common')
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.c1131
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.h302
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.inf103
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.h243
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.inf103
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiSmm/Platform.c831
-rw-r--r--BraswellPlatformPkg/Common/Acpi/AcpiSmm/S3Save.c402
7 files changed, 3115 insertions, 0 deletions
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.c b/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.c
new file mode 100644
index 0000000000..68a6aa55ce
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.c
@@ -0,0 +1,1131 @@
+/** @file
+ ACPI Platform Driver.
+
+ Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 <PiDxe.h>
+#include <Protocol/TcgService.h>
+#include <Protocol/FirmwareVolume2.h>
+#include "AcpiPlatform.h"
+#include "Platform.h"
+#include <Guid/PlatformInfo.h>
+#include <Hpet.h>
+#include <Mcfg.h>
+#include <Guid/GlobalVariable.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PlatformInfo.h>
+#include <Protocol/CpuIo.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Guid/AcpiTableStorage.h>
+#include <PchAccess.h>
+#include <Guid/Chv2Variable.h>
+#include "CpuRegs.h"
+#include <Library/KscLib.h>
+
+#define AML_OPREGION_OP 0x80
+
+typedef struct {
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+} EFI_CPUID_REGISTER;
+
+EFI_CPU_IO2_PROTOCOL *mCpuIo;
+
+#pragma optimize("", off)
+
+EFI_PLATFORM_INFO_HOB *mPlatformInfo;
+SYSTEM_CONFIGURATION mSystemConfiguration;
+
+VOID
+SettingI2CTouchAddress (
+ IN VOID
+ );
+
+VOID
+LoadSsdtIsctTable (
+ VOID
+ );
+
+/**
+Routine Description:
+
+ Locate the first instance of a protocol. If the protocol requested is an
+ FV protocol, then it will return the first FV that contains the ACPI table
+ storage file.
+
+ @param[in] Protocol The protocol to find.
+ @param[in] 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;
+}
+
+/**
+ 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;
+
+ 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++;
+ }
+ EndPtr = (UINT8*) TableHeader;
+ EndPtr = EndPtr + TableHeader->Length;
+ //
+ // 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;
+ default:
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+Routine Description:
+
+ 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;
+ EFI_MP_SERVICES_PROTOCOL *MpService;
+ UINTN MaximumNumberOfCPUs;
+ UINTN NumberOfEnabledCPUs;
+ UINTN BufferSize;
+ ACPI_APIC_STRUCTURE_PTR *ProcessorLocalApicEntry;
+ UINTN BspIndex;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *HpetTbl;
+ UINT64 OemIdValue;
+ EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *pFACP;
+ UINT16 NumberOfHpets;
+ UINT16 HpetCapIdValue;
+ UINT32 HpetBlockID;
+ UINTN LocalApicCounter;
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;
+ EFI_ACPI_3_0_IO_APIC_STRUCTURE *IOApicType;
+ EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *APICTableHeader;
+
+ CurrPtr = NULL;
+ EndPtr = NULL;
+ ApicPtr = NULL;
+ LocalApicCounter = 0;
+ CurrProcessor = 0;
+ ProcessorLocalApicEntry = NULL;
+
+ if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+ //
+ // Update the OEMID
+ //
+ OemIdValue = 0;
+ CopyMem (&OemIdValue, PcdGetPtr (PcdAcpiDefaultOemId), 6);
+
+ *(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 = PcdGet64(PcdAcpiDefaultOemTableId);
+ }
+
+ //
+ // 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
+ //
+ //
+ // 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,
+ &MpService
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Determine the number of processors
+ //
+ MpService->GetNumberOfProcessors (
+ MpService,
+ &MaximumNumberOfCPUs,
+ &NumberOfEnabledCPUs
+ );
+
+ ASSERT (MaximumNumberOfCPUs <= MAX_CPU_NUM && NumberOfEnabledCPUs >= 1);
+
+ //
+ // Assign a invalid intial value for update
+ //
+ //
+ // Update the processors in the APIC table
+ //
+ switch (Table->Signature) {
+ case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+
+ Status = MpService->WhoAmI (
+ MpService,
+ &BspIndex
+ );
+
+ //
+ // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled
+ //
+ APICTableHeader = (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
+ APICTableHeader->Flags |= EFI_ACPI_3_0_PCAT_COMPAT;
+
+ 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 ((EFI_D_ERROR, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", ApicPtr->AcpiLocalApic.AcpiProcessorId, MaximumNumberOfCPUs));
+ if (ApicPtr->AcpiLocalApic.AcpiProcessorId > MaximumNumberOfCPUs) {
+ ApicPtr->AcpiLocalApic.AcpiProcessorId = (UINT8)MaximumNumberOfCPUs;
+ }
+
+ BufferSize = 0;
+ ApicPtr->AcpiLocalApic.Flags = 0;
+
+ for (CurrProcessor = 0; CurrProcessor < MaximumNumberOfCPUs; CurrProcessor++) {
+ Status = MpService->GetProcessorInfo (
+ MpService,
+ 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)) {
+ //
+ // Go on and check if Hyper Threading is enabled. If HT not enabled
+ // hide this thread from OS by not setting the flag to 1. This is the
+ // software way to disable Hyper Threading. Basically we just hide it
+ // from the OS.
+ //
+ ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED;
+
+ if (!mSystemConfiguration.ProcessorHtMode) {
+ if (ProcessorInfoBuffer.Location.Thread != 0) {
+ ApicPtr->AcpiLocalApic.Flags = 0;
+ }
+ }
+
+ if (mSystemConfiguration.ActiveProcessorCores) {
+ if (ProcessorInfoBuffer.Location.Core >= mSystemConfiguration.ActiveProcessorCores) {
+ ApicPtr->AcpiLocalApic.Flags = 0;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ //
+ // If no APIC-ID match, the cpu may not be populated
+ //
+ break;
+
+ case EFI_ACPI_3_0_IO_APIC:
+
+ IOApicType = (EFI_ACPI_3_0_IO_APIC_STRUCTURE *)CurrPtr;
+ MmioWrite8 ((UINTN) R_PCH_IO_APIC_INDEX, R_PCH_IO_APIC_ID);
+ IOApicType->IoApicId = (UINT8) (MmioRead32 ((UINTN) R_PCH_IO_APIC_WINDOW) >> 24);
+ //
+ // IO APIC entries can be patched here
+ //
+ break;
+ }
+
+ CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
+ }
+ break;
+
+ case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+ //
+ // if Native ASPM is disabled, set FACP table to skip Native ASPM
+ //
+ if ((mSystemConfiguration.PciExpNative == 0)) {
+ pFACP = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
+ pFACP->IaPcBootArch |= 0x10;
+ }
+ 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:
+
+ 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_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);
+
+ 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_PCH_PCH_HPET_GCID_NT; // Bits [8:12] contains the number of Hpets
+ HpetBlockID = EFI_ACPI_EVENT_TIMER_BLOCK_ID;
+
+ if ((NumberOfHpets) && (NumberOfHpets & B_PCH_PCH_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;
+
+ 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;
+}
+
+/**
+Routine Description:
+
+ 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_TABLE_PROTOCOL *AcpiTable;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ INTN Instance;
+ EFI_ACPI_COMMON_HEADER *CurrentTable;
+ UINTN TableHandle;
+ UINT32 FvStatus;
+ UINT32 Size;
+ EFI_ACPI_TABLE_VERSION TableVersion;
+ EFI_HANDLE Handle;
+ UINT8 PortData;
+ EFI_MP_SERVICES_PROTOCOL *MpService;
+ UINTN MaximumNumberOfCPUs;
+ UINTN NumberOfEnabledCPUs;
+ UINT32 Data32;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_EVENT EfiExitBootServicesEvent;
+
+ Address = 0xffffffff;
+
+ TableVersion = EFI_ACPI_TABLE_VERSION_2_0;
+ Instance = 0;
+ CurrentTable = NULL;
+ TableHandle = 0;
+ Data32 = 0;
+
+ mPlatformInfo = PcdGetPtr (PcdPlatformInfo);
+
+ //
+ // Search for the Memory Configuration GUID HOB. If it is not present, then
+ // there's nothing we can do. It may not exist on the update path.
+ //
+ CopyMem (&mSystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof(SYSTEM_CONFIGURATION));
+
+ //
+ // Locate the AcpiTable protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Locate the firmware volume protocol
+ //
+ Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, &FwVol, 1);
+ ASSERT_EFI_ERROR (Status);
+
+ Instance = 0;
+
+ Status = gBS->LocateProtocol (
+ &gEfiMpServiceProtocolGuid,
+ NULL,
+ &MpService
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Determine the number of processors
+ //
+ MpService->GetNumberOfProcessors (
+ MpService,
+ &MaximumNumberOfCPUs,
+ &NumberOfEnabledCPUs
+ );
+
+ //
+ // Allocate and initialize the NVS area for SMM and ASL communication.
+ //
+ Pages = EFI_SIZE_TO_PAGES ( sizeof (EFI_GLOBAL_NVS_AREA) );
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ Pages,
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
+ mGlobalNvsArea.Area = (EFI_GLOBAL_NVS_AREA*) (UINTN)Address;
+
+ gBS->SetMem (mGlobalNvsArea.Area, sizeof (EFI_GLOBAL_NVS_AREA), 0);
+ DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea.Area));
+
+ //
+ // Update global NVS area for ASL and SMM init code to use
+ //
+ mGlobalNvsArea.Area->ApicEnable = 1;
+ mGlobalNvsArea.Area->NumberOfBatteries = 1;
+ mGlobalNvsArea.Area->BatteryCapacity0 = 100;
+ mGlobalNvsArea.Area->BatteryStatus0 = 84;
+ mGlobalNvsArea.Area->OnboardCom = 1;
+ mGlobalNvsArea.Area->PowerState = 0;
+
+ mGlobalNvsArea.Area->LogicalProcessorCount = (UINT8)NumberOfEnabledCPUs;
+
+ mGlobalNvsArea.Area->PassiveThermalTripPoint = 85;
+ mGlobalNvsArea.Area->PassiveTc1Value = 1;
+ mGlobalNvsArea.Area->PassiveTc2Value = 5;
+ mGlobalNvsArea.Area->PassiveTspValue = 50;
+ mGlobalNvsArea.Area->CriticalThermalTripPoint = 110;
+
+ 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->AlsEnable = mSystemConfiguration.AlsEnable;
+ mGlobalNvsArea.Area->BacklightControlSupport = 2;
+ mGlobalNvsArea.Area->BrightnessPercentage = 100;
+ mGlobalNvsArea.Area->IgdState = 1;
+ 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 ;
+ mGlobalNvsArea.Area->PreviousDeviceList = 0x0F ;
+
+ mGlobalNvsArea.Area->UartSelection = mSystemConfiguration.UartInterface;
+
+ //
+ // DPTF related
+ //
+ mGlobalNvsArea.Area->DptfEnable = mSystemConfiguration.EnableDptf;
+ mGlobalNvsArea.Area->DptfSysThermal0 = mSystemConfiguration.DptfSysThermal0;
+ mGlobalNvsArea.Area->DptfSysThermal1 = mSystemConfiguration.DptfSysThermal1;
+ mGlobalNvsArea.Area->DptfSysThermal2 = mSystemConfiguration.DptfSysThermal2;
+ mGlobalNvsArea.Area->DptfSysThermal3 = mSystemConfiguration.DptfSysThermal3;
+ mGlobalNvsArea.Area->DptfSysThermal4 = mSystemConfiguration.DptfSysThermal4;
+ mGlobalNvsArea.Area->DptfCharger = mSystemConfiguration.DptfChargerDevice;
+ mGlobalNvsArea.Area->DptfDisplayDevice = mSystemConfiguration.DptfDisplayDevice;
+ mGlobalNvsArea.Area->DptfSocDevice = mSystemConfiguration.DptfSocDevice;
+ mGlobalNvsArea.Area->DptfProcessor = mSystemConfiguration.DptfProcessor;
+ mGlobalNvsArea.Area->DptfProcCriticalTemperature = mSystemConfiguration.CriticalThermalTripPoint;
+ mGlobalNvsArea.Area->DptfProcPassiveTemperature = mSystemConfiguration.PassiveThermalTripPoint;
+
+ mGlobalNvsArea.Area->EnablePassivePolicy = mSystemConfiguration.EnablePassivePolicy;
+ mGlobalNvsArea.Area->EnableCriticalPolicy = mSystemConfiguration.EnableCriticalPolicy;
+ mGlobalNvsArea.Area->EnableActivePolicy = mSystemConfiguration.EnableActivePolicy;
+
+ mGlobalNvsArea.Area->DptfGenericActiveTemperature0 = mSystemConfiguration.GenericActiveTemp0;
+ mGlobalNvsArea.Area->DptfGenericCR3Temperature0 = mSystemConfiguration.GenericCR3Temp0;
+ mGlobalNvsArea.Area->DptfGenericHotTemperature0 = mSystemConfiguration.GenericHotTemp0;
+ mGlobalNvsArea.Area->DptfGenericActiveTemperature1 = mSystemConfiguration.GenericActiveTemp1;
+ mGlobalNvsArea.Area->DptfGenericCR3Temperature1 = mSystemConfiguration.GenericCR3Temp1;
+ mGlobalNvsArea.Area->DptfGenericHotTemperature1 = mSystemConfiguration.GenericHotTemp1;
+ mGlobalNvsArea.Area->DptfGenericActiveTemperature2 = mSystemConfiguration.GenericActiveTemp2;
+ mGlobalNvsArea.Area->DptfGenericCR3Temperature2 = mSystemConfiguration.GenericCR3Temp2;
+ mGlobalNvsArea.Area->DptfGenericHotTemperature2 = mSystemConfiguration.GenericHotTemp2;
+
+ mGlobalNvsArea.Area->DptfProcActiveTemperatureSA = mSystemConfiguration.ActiveThermalTripPointSA;
+ mGlobalNvsArea.Area->DptfProcCriticalTemperatureSA = mSystemConfiguration.CriticalThermalTripPointSA;
+ mGlobalNvsArea.Area->DptfProcCR3TemperatureSA = mSystemConfiguration.CR3ThermalTripPointSA;
+ mGlobalNvsArea.Area->DptfProcHotTemperatureSA = mSystemConfiguration.HotThermalTripPointSA;
+ mGlobalNvsArea.Area->DptfProcPassiveTemperatureSA = mSystemConfiguration.PassiveThermalTripPointSA;
+
+ mGlobalNvsArea.Area->DptfGenericCriticalTemperature0 = mSystemConfiguration.GenericCriticalTemp0;
+ mGlobalNvsArea.Area->DptfGenericPassiveTemperature0 = mSystemConfiguration.GenericPassiveTemp0;
+ mGlobalNvsArea.Area->DptfGenericCriticalTemperature1 = mSystemConfiguration.GenericCriticalTemp1;
+ mGlobalNvsArea.Area->DptfGenericPassiveTemperature1 = mSystemConfiguration.GenericPassiveTemp1;
+ mGlobalNvsArea.Area->DptfGenericCriticalTemperature2 = mSystemConfiguration.GenericCriticalTemp2;
+ mGlobalNvsArea.Area->DptfGenericPassiveTemperature2 = mSystemConfiguration.GenericPassiveTemp2;
+ mGlobalNvsArea.Area->DptfGenericCriticalTemperature3 = mSystemConfiguration.GenericCriticalTemp3;
+ mGlobalNvsArea.Area->DptfGenericPassiveTemperature3 = mSystemConfiguration.GenericPassiveTemp3;
+ mGlobalNvsArea.Area->DptfGenericCriticalTemperature4 = mSystemConfiguration.GenericCriticalTemp4;
+ mGlobalNvsArea.Area->DptfGenericPassiveTemperature4 = mSystemConfiguration.GenericPassiveTemp4;
+ mGlobalNvsArea.Area->CLpmSetting = mSystemConfiguration.Clpm;
+ mGlobalNvsArea.Area->DptfSuperDbg = mSystemConfiguration.SuperDebug;
+ mGlobalNvsArea.Area->LPOEnable = mSystemConfiguration.LPOEnable;
+ mGlobalNvsArea.Area->LPOStartPState = mSystemConfiguration.LPOStartPState;
+ mGlobalNvsArea.Area->LPOStepSize = mSystemConfiguration.LPOStepSize;
+ mGlobalNvsArea.Area->LPOPowerControlSetting = mSystemConfiguration.LPOPowerControlSetting;
+ mGlobalNvsArea.Area->LPOPerformanceControlSetting = mSystemConfiguration.LPOPerformanceControlSetting;
+ mGlobalNvsArea.Area->DppmEnabled = mSystemConfiguration.EnableDppm;
+ mGlobalNvsArea.Area->AmbientTripPointChange = mSystemConfiguration.AmbientTripPointChange;
+ mGlobalNvsArea.Area->DptfWwanDevice = mSystemConfiguration.DptfWwanDevice;
+ mGlobalNvsArea.Area->DptfWwanCrt = mSystemConfiguration.DptfWwanCrt;
+ mGlobalNvsArea.Area->DptfWwanPsv = mSystemConfiguration.DptfWwanPsv;
+ mGlobalNvsArea.Area->DisplayHighLimit = mSystemConfiguration.DisplayHighLimit;
+ mGlobalNvsArea.Area->DisplayLowLimit = mSystemConfiguration.DisplayLowLimit;
+
+ //
+ // Ambient temperature related data
+ //
+ mGlobalNvsArea.Area->AmbientConstants[0] = mSystemConfiguration.AmbientConstants[0];
+ mGlobalNvsArea.Area->AmbientConstants[1] = mSystemConfiguration.AmbientConstants[1];
+ mGlobalNvsArea.Area->AmbientConstants[2] = mSystemConfiguration.AmbientConstants[2];
+ mGlobalNvsArea.Area->AmbientConstants[3] = mSystemConfiguration.AmbientConstants[3];
+ mGlobalNvsArea.Area->AmbientConstants[4] = mSystemConfiguration.AmbientConstants[4];
+ mGlobalNvsArea.Area->AmbientConstants[5] = mSystemConfiguration.AmbientConstants[5];
+ mGlobalNvsArea.Area->AmbientConstantSign[0] = mSystemConfiguration.AmbientConstantSign[0];
+ mGlobalNvsArea.Area->AmbientConstantSign[1] = mSystemConfiguration.AmbientConstantSign[1];
+ mGlobalNvsArea.Area->AmbientConstantSign[2] = mSystemConfiguration.AmbientConstantSign[2];
+ mGlobalNvsArea.Area->AmbientConstantSign[3] = mSystemConfiguration.AmbientConstantSign[3];
+ mGlobalNvsArea.Area->AmbientConstantSign[4] = mSystemConfiguration.AmbientConstantSign[4];
+ mGlobalNvsArea.Area->AmbientConstantSign[5] = mSystemConfiguration.AmbientConstantSign[5];
+ mGlobalNvsArea.Area->Str2TspValue = mSystemConfiguration.Str2TspValue;
+
+ DEBUG((EFI_D_INFO, "Dumping DPTF settings in global nvs init...\n"));
+ DEBUG((EFI_D_INFO, "DPTFEnabled = %d\n", mGlobalNvsArea.Area->DptfEnable));
+ DEBUG((EFI_D_INFO, "CpuParticipantCriticalTemperature = %d\n", mGlobalNvsArea.Area->DptfProcCriticalTemperature));
+ DEBUG((EFI_D_INFO, "CpuParticipantPassiveTemperature = %d\n", mGlobalNvsArea.Area->DptfProcPassiveTemperature));
+ DEBUG((EFI_D_INFO, "GenParticipant0CriticalTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericCriticalTemperature0));
+ DEBUG((EFI_D_INFO, "GenParticipant0PassiveTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericPassiveTemperature0));
+ DEBUG((EFI_D_INFO, "GenParticipant1CriticalTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericCriticalTemperature1));
+ DEBUG((EFI_D_INFO, "GenParticipant1PassiveTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericPassiveTemperature1));
+ DEBUG((EFI_D_INFO, "GenParticipant2CriticalTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericCriticalTemperature2));
+ DEBUG((EFI_D_INFO, "GenParticipant2PassiveTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericPassiveTemperature2));
+ DEBUG((EFI_D_INFO, "GenParticipant3CriticalTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericCriticalTemperature3));
+ DEBUG((EFI_D_INFO, "GenParticipant3PassiveTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericPassiveTemperature3));
+ DEBUG((EFI_D_INFO, "GenParticipant4CriticalTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericCriticalTemperature4));
+ DEBUG((EFI_D_INFO, "GenParticipant4PassiveTemperature = %d\n", mGlobalNvsArea.Area->DptfGenericPassiveTemperature4));
+ DEBUG((EFI_D_INFO,"WwanDevice = %d Wwan PSv = %d WwanCrt = %d\n", mGlobalNvsArea.Area->DptfWwanDevice,mGlobalNvsArea.Area->DptfWwanPsv, mGlobalNvsArea.Area->DptfWwanCrt));
+ DEBUG((EFI_D_INFO, "ClpmSetting = %d\n", mGlobalNvsArea.Area->CLpmSetting));
+ DEBUG((EFI_D_INFO, "SuperDebug = %d\n", mGlobalNvsArea.Area->DptfSuperDbg));
+ DEBUG((EFI_D_INFO, "LPOEnable = %d\n", mGlobalNvsArea.Area->LPOEnable));
+ DEBUG((EFI_D_INFO, "LPOStartPState = %d\n", mGlobalNvsArea.Area->LPOStartPState));
+ DEBUG((EFI_D_INFO, "LPOStepSize = %d\n", mGlobalNvsArea.Area->LPOStepSize));
+ DEBUG((EFI_D_INFO, "LPOPowerControlSetting = %d\n", mGlobalNvsArea.Area->LPOPowerControlSetting));
+ DEBUG((EFI_D_INFO, "LPOPerformanceControlSetting = %d\n", mGlobalNvsArea.Area->LPOPerformanceControlSetting));
+ DEBUG((EFI_D_INFO, "bDppmEnabled = %d\n", mGlobalNvsArea.Area->DppmEnabled));
+
+ DEBUG((EFI_D_INFO, "DptfEnable = %d\n", mGlobalNvsArea.Area->DptfEnable));
+ DEBUG((EFI_D_INFO, "DptfSysThermal0 = %d\n", mGlobalNvsArea.Area->DptfSysThermal0));
+ DEBUG((EFI_D_INFO, "DptfSysThermal1 = %d\n", mGlobalNvsArea.Area->DptfSysThermal1));
+ DEBUG((EFI_D_INFO, "DptfSysThermal2 = %d\n", mGlobalNvsArea.Area->DptfSysThermal2));
+ DEBUG((EFI_D_INFO, "DptfSysThermal3 = %d\n", mGlobalNvsArea.Area->DptfSysThermal3));
+ DEBUG((EFI_D_INFO, "DptfCharger = %d\n", mGlobalNvsArea.Area->DptfCharger));
+ DEBUG((EFI_D_INFO, "DptfDisplayDevice = %d\n", mGlobalNvsArea.Area->DptfDisplayDevice));
+ DEBUG((EFI_D_INFO, "DptfSocDevice = %d\n", mGlobalNvsArea.Area->DptfSocDevice));
+ DEBUG((EFI_D_INFO, "DptfProcessor = %d\n", mGlobalNvsArea.Area->DptfProcessor));
+ DEBUG((EFI_D_INFO, "Dptf Ambient Temperature Constants values = %d \t %d \t %d \t %d \t %d \t %d\n", mGlobalNvsArea.Area->AmbientConstants[0], \
+ mGlobalNvsArea.Area->AmbientConstants[1], mGlobalNvsArea.Area->AmbientConstants[2], mGlobalNvsArea.Area->AmbientConstants[3], \
+ mGlobalNvsArea.Area->AmbientConstants[4], mGlobalNvsArea.Area->AmbientConstants[5] ));
+
+ //
+ //
+ // Platform Flavor
+ //
+ mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor;
+
+ //
+ // Update the Platform ID
+ //
+ mGlobalNvsArea.Area->BoardID = mPlatformInfo->BoardId;
+
+ //
+ // Update the Board Revision
+ //
+ mGlobalNvsArea.Area->FabID = (UINT8)(mPlatformInfo->FABID + 1);
+
+ mGlobalNvsArea.Area->ECSupport = mPlatformInfo->ECSupport;
+ mGlobalNvsArea.Area->FanSupport = mPlatformInfo->FanSupport;
+ mGlobalNvsArea.Area->BatterySupport = mPlatformInfo->BatterySupport;
+
+ mGlobalNvsArea.Area->PmicType = mPlatformInfo->PmicId;
+
+ DEBUG((EFI_D_INFO, "GlobalNvs BoardId = %d\n", mGlobalNvsArea.Area->BoardID));
+ DEBUG((EFI_D_INFO, "GlobalNvs PmicType = %d\n", mGlobalNvsArea.Area->PmicType));
+
+ mGlobalNvsArea.Area->OtgMode = mSystemConfiguration.PchUsbOtg;
+ mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.PchUsb30Mode;
+
+ mGlobalNvsArea.Area->PmicEnable = GLOBAL_NVS_DEVICE_DISABLE;
+
+ mGlobalNvsArea.Area->ISPDevSel = mSystemConfiguration.ISPDevSel;
+
+ mGlobalNvsArea.Area->ISPEn = mSystemConfiguration.ISPEn;
+ mGlobalNvsArea.Area->GpioAcpiEnabled = mSystemConfiguration.GpioAcpiEnabled;
+ mGlobalNvsArea.Area->Sdcard1p8vSwitchingDelay = mSystemConfiguration.Sdcard1p8vSwitchingDelay;
+ mGlobalNvsArea.Area->Sdcard3p3vDischargeDelay = mSystemConfiguration.Sdcard3p3vDischargeDelay;
+
+ //
+ // BSW Virtual Button Support
+ //
+ if (mSystemConfiguration.VirtualButtonEnable == 0) {
+ mGlobalNvsArea.Area->VirtualButtonSupport = 0x00;
+ } else if (mSystemConfiguration.VirtualButtonEnable == 1) {
+ mGlobalNvsArea.Area->VirtualButtonSupport = 0x01;
+
+ if (mSystemConfiguration.ConvertibleState == 1) {
+ mGlobalNvsArea.Area->VirtualButtonSupport = mGlobalNvsArea.Area->VirtualButtonSupport | 0x08;
+ }
+
+ if (mSystemConfiguration.DockIndicator == 1) {
+ mGlobalNvsArea.Area->VirtualButtonSupport = mGlobalNvsArea.Area->VirtualButtonSupport | 0x10;
+ }
+ }
+
+ //
+ // LPE Audio Device Selection & NFC connection
+ //
+ mGlobalNvsArea.Area->PchLpeEnabled = mSystemConfiguration.PchLpeEnabled;
+ mGlobalNvsArea.Area->NfcConnection = PcdGet8(PcdNfcConnection); // NFC1 to I2C7
+
+ //
+ // BT Module Selection - BRCM(Default), 1 - STP(Stone Peak)
+ //
+ mGlobalNvsArea.Area->BTModuleSelect = mSystemConfiguration.BTModule;
+
+ //
+ // WIFI Device Selection
+ //
+ mGlobalNvsArea.Area->WIFIModuleSelect = mSystemConfiguration.WIFIModule;
+ mGlobalNvsArea.Area->NativePCIESupport = mSystemConfiguration.PciExpNative;
+
+ //
+ // Modem selection
+ //
+ mGlobalNvsArea.Area->AcpiModemSel = mSystemConfiguration.AcpiModemSel;
+
+ //
+ // Camera selection
+ //
+ mGlobalNvsArea.Area->RvpCameraDevSel = mSystemConfiguration.RvpCameraDevSel;
+ mGlobalNvsArea.Area->EbCameraDevSel = mSystemConfiguration.EbCameraDevSel;
+ SettingI2CTouchAddress();
+ mGlobalNvsArea.Area->S0ix= mSystemConfiguration.S0ix;
+
+ //
+ // Read BMBOUND and store it in GlobalNVS to pass into ASL
+ //
+ mGlobalNvsArea.Area->BmBound = PcdGet32 (PcdMmioBase);
+
+ if (mSystemConfiguration.ScceMMCEnabled != 0) {
+ DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
+ mGlobalNvsArea.Area->emmcVersion = 1;
+ }
+ mGlobalNvsArea.Area->ToggleSelfClkDisabling = mSystemConfiguration.ToggleSelfClkDisabling;
+
+ //
+ // Support EllensBurg
+ //
+ mGlobalNvsArea.Area->Ellensburg = mSystemConfiguration.Ellensburg;
+ DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->Ellensburg = %d\n", mGlobalNvsArea.Area->Ellensburg));
+
+ #if (_PSSD_FIX_==1)
+ mGlobalNvsArea.Area->PssdFix = 1;
+ #else
+ mGlobalNvsArea.Area->PssdFix = 0;
+ #endif
+
+ mGlobalNvsArea.Area->DisableBattery = 0;
+
+ //
+ // SIO related option
+ //
+ Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, &mCpuIo);
+ ASSERT_EFI_ERROR (Status);
+
+ mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_DISABLE;
+
+ mGlobalNvsArea.Area->DockedSioPresent = GLOBAL_NVS_DEVICE_DISABLE;
+
+ if (mGlobalNvsArea.Area->DockedSioPresent != GLOBAL_NVS_DEVICE_ENABLE) {
+ //
+ // Check ID for SIO WPCN381U
+ //
+ Status = mCpuIo->Io.Read (
+ mCpuIo,
+ EfiCpuIoWidthUint8,
+ WPCN381U_CONFIG_INDEX,
+ 1,
+ &PortData
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (PortData != 0xFF) {
+ PortData = 0x20;
+ Status = mCpuIo->Io.Write (
+ mCpuIo,
+ EfiCpuIoWidthUint8,
+ WPCN381U_CONFIG_INDEX,
+ 1,
+ &PortData
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = mCpuIo->Io.Read (
+ mCpuIo,
+ EfiCpuIoWidthUint8,
+ WPCN381U_CONFIG_DATA,
+ 1,
+ &PortData
+ );
+ ASSERT_EFI_ERROR (Status);
+ if ((PortData == WPCN381U_CHIP_ID) || (PortData == WDCP376_CHIP_ID)) {
+ mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_ENABLE;
+ mGlobalNvsArea.Area->OnboardCom = GLOBAL_NVS_DEVICE_ENABLE;
+ mGlobalNvsArea.Area->OnboardComCir = GLOBAL_NVS_DEVICE_DISABLE;
+ }
+ }
+ }
+
+ mGlobalNvsArea.Area->SDIOMode = mSystemConfiguration.LpssSdioMode;
+
+ 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,
+ &CurrentTable,
+ (UINTN *) &Size,
+ &FvStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Perform any table specific updates.
+ //
+ AcpiStatus = PlatformUpdateTables (CurrentTable);
+ if (!EFI_ERROR (AcpiStatus)) {
+ //
+ // Install the table
+ //
+ TableHandle = 0;
+ AcpiStatus = AcpiTable->InstallAcpiTable (AcpiTable, CurrentTable, CurrentTable->Length, &TableHandle);
+ ASSERT_EFI_ERROR (AcpiStatus);
+ }
+ //
+ // Increment the instance
+ //
+ Instance++;
+ }
+ }
+
+ //
+ //Audio Codec Support for EB and RVP
+ //
+ mGlobalNvsArea.Area->AudioCodecSuppport = mSystemConfiguration.AudioCodecSuppport;
+ DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->AudioCodecSuppport = %d\n", mGlobalNvsArea.Area->AudioCodecSuppport));
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ EnableAcpiCallback,
+ NULL,
+ &gEfiEventExitBootServicesGuid,
+ &EfiExitBootServicesEvent
+ );
+
+ //
+ // Finished
+ //
+
+ return EFI_SUCCESS;
+}
+
+VOID
+SettingI2CTouchAddress (
+ IN VOID
+ )
+{
+ if (mSystemConfiguration.I2CTouchAd == 0) { // if setup menu select auto set I2C Touch Address base on board id
+ } else {
+ mGlobalNvsArea.Area->I2CTouchAddress = mSystemConfiguration.I2CTouchAd;
+ }
+ DEBUG((EFI_D_ERROR, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea.Area->I2CTouchAddress));
+}
+
+/**
+ Event Notification during exit boot service to enabel ACPI mode
+
+ @param[in] Event EFI Event Handle
+ @param[in] Context Pointer to Notify Context
+
+ @return
+
+**/
+VOID
+EnableAcpiCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT32 RegData32;
+ UINT16 Pm1Cnt;
+ UINT16 AcpiBase;
+ UINT32 Gpe0aEn;
+ EFI_GLOBAL_NVS_AREA *mGlobalNvsAreaPtr;
+ EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsAreaProtocol;
+ EFI_STATUS Status;
+
+ GlobalNvsAreaProtocol = NULL;
+
+ Status = gBS->LocateProtocol (&gEfiGlobalNvsAreaProtocolGuid, NULL, &GlobalNvsAreaProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to locate GlobalNvsAreaProtocol\n"));
+ return;
+ }
+
+ mGlobalNvsAreaPtr = GlobalNvsAreaProtocol->Area;
+
+ AcpiBase = MmioRead16 (
+ MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE
+ )
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ DEBUG ((EFI_D_INFO, "EnableAcpiCallback: AcpiBase = %x\n", AcpiBase));
+
+ //
+ // Disable PM sources except power button
+ // power button is enabled only for PCAT. Disabled it on Tablet platform
+ //
+ IoWrite16 (AcpiBase + R_PCH_ACPI_PM1_EN, B_PCH_ACPI_PM1_EN_PWRBTN);
+ IoWrite16 (AcpiBase + R_PCH_ACPI_PM1_STS, 0xffff);
+
+ //
+ // Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
+ // Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS RAM is no longer Valid
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
+ IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
+
+ {
+ SendKscCommand (KSC_C_SMI_NOTIFY_DISABLE);
+
+ RegData32 = IoRead32(AcpiBase + R_PCH_ALT_GP_SMI_EN);
+ RegData32 &= ~(BIT7);
+ IoWrite32 ((AcpiBase + R_PCH_ALT_GP_SMI_EN), RegData32);
+
+ //
+ // Disable APM/SMI mode
+ //
+ SendKscCommand (KSC_C_SMI_DISABLE);
+
+ //
+ // Disable ACPI/SCI mode
+ //
+ SendKscCommand (KSC_C_ACPI_ENABLE);
+ }
+
+ //
+ // Enable SCI
+ //
+ Pm1Cnt = IoRead16(AcpiBase + R_PCH_ACPI_PM1_CNT);
+ Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
+ IoWrite16 (AcpiBase + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+
+ IoWrite8 (0x80, 0xA0); //SW_SMI_ACPI_ENABLE
+
+ //
+ // Enable PME_B0_EN in GPE0a_EN
+ // Caution: Enable PME_B0_EN must be placed after enabling SCI.
+ // Otherwise, USB PME could not be handled as SMI event since no handler is there.
+ //
+ if (mGlobalNvsAreaPtr->OSImageId == 1) {
+ Gpe0aEn = IoRead32 (AcpiBase + R_PCH_ACPI_GPE0a_EN);
+ Gpe0aEn |= B_PCH_ACPI_GPE0a_EN_PME_B0;
+ IoWrite32 (AcpiBase + R_PCH_ACPI_GPE0a_EN, Gpe0aEn);
+ }
+}
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.h b/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.h
new file mode 100644
index 0000000000..14a31c30e5
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.h
@@ -0,0 +1,302 @@
+/** @file
+ 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) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 <FrameworkDxe.h>
+#include <PiDxe.h>
+#include <Protocol/CpuPlatformPolicyProtocol.h>
+#include <Base.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/CpuIo2.h>
+#include <IndustryStandard/Acpi30.h>
+#include <IndustryStandard/Acpi20.h>
+#include <Library/HobLib.h>
+#include <Guid/SetupVariable.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <PchRegs.h>
+#include <Library/PchPlatformLib.h>
+#include <Protocol/Spi.h>
+
+//
+// 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 ('C', 'H', 'V', ' ')
+#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 PCAT_RTC_ADDRESS_REGISTER 0x74
+#define PCAT_RTC_DATA_REGISTER 0x75
+#define RTC_ADDRESS_REGISTER_D 0x0D
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#ifndef EFI_SIGNATURE_16
+#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8))
+#endif
+#ifndef EFI_SIGNATURE_32
+#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#endif
+#ifndef EFI_SIGNATURE_64
+#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32))
+#endif
+//
+// +++++++++++++++++++++++++++++++++++++++++++++++++++
+// 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;
+
+#pragma pack()
+
+//
+// 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 EFI_HANDLE: A handle for the image that is initializing this driver.
+ @param[in] SystemTable EFI_SYSTEM_TABLE: 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.
+
+ @param[in] ImageHandle EFI_HANDLE: A handle for the image that is initializing this driver.
+ @param[in] SystemTable EFI_SYSTEM_TABLE: 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_ACPI_TABLE_VERSION
+GetAcpiTableVersion (
+ VOID
+ );
+
+/**
+ The funtion returns Oem specific information of Acpi Platform.
+
+ @param[in] OemId OemId returned.
+ @param[in] OemTableId OemTableId returned.
+ @param[in] 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 table version.
+
+ @param[in]
+
+ @retval EFI_ACPI_TABLE_VERSION 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
+ );
+
+VOID
+SelectNFCDevice (
+ IN VOID
+ );
+
+VOID
+SettingI2CTouchAddress (
+ IN VOID
+ );
+
+/**
+ Event Notification during exit boot service to enabel ACPI mode
+
+ @param[in] Event EFI Event Handle
+ @param[in] Context Pointer to Notify Context
+
+ @return
+
+**/
+VOID
+EnableAcpiCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+#endif
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.inf b/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.inf
new file mode 100644
index 0000000000..ef89d2b55b
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiPlatform/AcpiPlatform.inf
@@ -0,0 +1,103 @@
+## @file
+# ACPI Platform Support Module
+#
+# Provides the ability for the platform to update the ACPI tables based on the
+# platforms configuration at boot.
+#
+# Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 14CD4276-38F3-4F25-B9A3-BDA1288A1A52
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = AcpiPlatformEntryPoint
+
+[Sources]
+ AcpiPlatform.c
+
+[Packages]
+ BraswellPlatformPkg/BraswellPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ HobLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ IoLib
+ PchPlatformLib
+ BaseLib
+ PciLib
+ MemoryAllocationLib
+ DxeKscLib
+
+[Guids]
+ ## CONSUMES ## File
+ gEfiAcpiTableStorageGuid
+
+ ## CONSUMES ## Event
+ gEfiEventExitBootServicesGuid
+
+[Protocols]
+ ## CONSUMES
+ gEfiAcpiTableProtocolGuid
+
+ ## SOMETIMES_CONSUMES
+ gEfiPlatformCpuProtocolGuid
+
+ ## CONSUMES
+ gEfiAcpiS3SaveProtocolGuid
+
+ ## CONSUMES
+ gEfiCpuIo2ProtocolGuid
+
+ ## CONSUMES
+ gEfiFirmwareVolume2ProtocolGuid
+
+ ## CONSUMES
+ gEfiMpServiceProtocolGuid
+
+ ## PRODUCES
+ gEfiGlobalNvsAreaProtocolGuid
+
+[Pcd]
+ ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiEdkIIPlatformTokenSpaceGuid.PcdPlatformInfo
+
+ ## SOMETIMES_CONSUMES
+ gEfiCHVTokenSpaceGuid.PcdIsVlv2
+ gEfiEdkIIPlatformTokenSpaceGuid.PcdNfcConnection
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+
+ ## SOMETIMES_CONSUMES
+ gIntelSiBasicPkgTokenSpaceGuid.PcdMmioBase
+
+ gEfiEdkIIPlatformTokenSpaceGuid.PcdSystemConfiguration
+
+[Depex]
+ gEfiAcpiTableProtocolGuid AND
+ gEfiMpServiceProtocolGuid AND
+ gEfiCpuIo2ProtocolGuid
+
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.h b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.h
new file mode 100644
index 0000000000..256b8d844a
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.h
@@ -0,0 +1,243 @@
+/** @file
+ SMM handler driver implementation.
+
+ Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 _PLATFORM_H
+#define _PLATFORM_H
+
+#include <PiSmm.h>
+#include <Protocol/SmmBase.h>
+#include <Protocol/FirmwareVolume.h>
+#include <Protocol/SmmPowerButtonDispatch2.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmIchnDispatch.h>
+#include <Protocol/SmmAccess.h>
+#include <Protocol/SmmVariable.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadedImage.h>
+#include "Protocol/GlobalNvsArea.h"
+#include <Guid/AcpiVariableCompatibility.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/AcpiVariable.h>
+#include <IndustryStandard/Pci22.h>
+#include "PchAccess.h"
+#include "PlatformBaseAddresses.h"
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PchPlatformLib.h>
+#include <Library/StallSmmLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <ReservedAcpiS3Range.h>
+
+typedef struct {
+ UINT8 Register;
+ UINT8 Function;
+ UINT8 Device;
+ UINT8 Bus;
+ UINT32 ExtendedRegister;
+} SMM_PCI_IO_ADDRESS;
+
+typedef struct {
+ CHAR8 BoardAaNumber[7];
+ UINTN BoardFabNumber;
+} BOARD_AA_NUMBER_DECODE;
+
+//
+// BugBug -- Need to get these two values from acpi.h, but right now, they are
+// declared in platform-specific variants of this file, so no easy
+// way to pick-up the include file and work across platforms.
+// Need these definitions to go into a file like common\acpi.h.
+//
+#define ACPI_ENABLE 0xA0
+#define ACPI_DISABLE 0xA1
+
+#define APM_12_FUNCS 0x50
+#define SMI_SET_SMMVARIABLE_PROTOCOL 0x51 // this is used in Cpu\Pentium\Smm\Base\SmmBase.c
+
+#define SMI_CMD_GET_MSEG_STATUS 0x70
+#define SMI_CMD_UPDATE_MSEG_SIZE 0x71
+#define SMI_CMD_LOAD_STM 0x72
+#define SMI_CMD_UNLOAD_STM 0x73
+#define SMI_CMD_GET_SMRAM_RANGES 0x74
+
+#define PCAT_RTC_ADDRESS_REGISTER 0x74
+#define PCAT_RTC_DATA_REGISTER 0x75
+
+#define RTC_ADDRESS_SECOND 0x00
+#define RTC_ADDRESS_SECOND_ALARM 0x01
+#define RTC_ADDRESS_MINUTE 0x02
+#define RTC_ADDRESS_MINUTE_ALARM 0x03
+#define RTC_ADDRESS_HOUR 0x04
+#define RTC_ADDRESS_HOUR_ALARM 0x05
+
+#define RTC_ADDRESS_REGISTER_A 0x0A
+#define RTC_ADDRESS_REGISTER_B 0x0B
+#define RTC_ADDRESS_REGISTER_C 0x0C
+#define RTC_ADDRESS_REGISTER_D 0x0D
+
+#define B_RTC_ALARM_INT_ENABLE 0x20
+#define B_RTC_ALARM_INT_STATUS 0x20
+
+#define B_RTC_DATE_ALARM_MASK 0x3F
+
+#define PCAT_CMOS_2_ADDRESS_REGISTER 0x72
+#define PCAT_CMOS_2_DATA_REGISTER 0x73
+
+#define EC_C_PORT 0x66
+#define SMC_SMI_DISABLE 0xBC
+#define SMC_ENABLE_ACPI_MODE 0xAA // Enable ACPI mode
+
+#define IO_MISC 156
+
+#define MAXIMUM_NUMBER_OF_PSTATES 12
+#define ICH_SMM_DATA_PORT 0xB3
+
+#define EFI_IA32_PMG_CST_CONFIG 0x000000E2
+#define B_EFI_CST_CONTROL_LOCK BIT15
+#define B_EFI_IO_MWAIT_REDIRECTION_ENABLE BIT10
+#define EFI_IA32_PMG_IO_CAPTURE_ADDR 0x000000E4
+
+extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
+
+//
+// Callback function prototypes
+//
+EFI_STATUS
+EFIAPI
+PowerButtonCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+S5SleepWakeOnLanCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+S5SleepAcLossCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+S4S5CallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+EnableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+DisableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+DummyTco1Callback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+VOID
+PerrSerrCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+VOID
+RiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+VOID
+SetAfterG3On (
+ BOOLEAN Enable
+ );
+
+VOID
+TurnOffVregUsb (
+ );
+
+EFI_STATUS
+PStateSupportCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+PStateTransitionCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+SxSleepEntryCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+ VOID
+ );
+
+#endif
+
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.inf b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.inf
new file mode 100644
index 0000000000..6f9950266d
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/AcpiSmm.inf
@@ -0,0 +1,103 @@
+## @file
+# Component description file for SMM Platform handler module
+#
+# Provides platform specific handlers for different SMI events. The module will
+# register handlers for sleep state transitions as well as other software SMI
+# events.
+#
+# Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = PlatformSmm
+ FILE_GUID = 88802B98-ADFE-4414-A695-FB35CA8D11F2
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializePlatformSmm
+ PI_SPECIFICATION_VERSION = 0x0001000A
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ S3Save.c
+ Platform.c
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+ IoLib
+ BaseLib
+ BaseMemoryLib
+ DevicePathLib
+ HobLib
+ S3BootScriptLib
+ StallSmmLib
+ PchPlatformLib
+ ReportStatusCodeLib
+
+[Guids]
+
+ ## SOMETIMES_CONSUMES ## Variable:L"AcpiGlobalVariable"
+ gEfiAcpiVariableCompatiblityGuid
+
+ ## SOMETIMES_CONSUMES
+ gEfiAcpiVariableGuid
+
+[Protocols]
+ ## CONSUMES
+ gEfiSmmIchnDispatchProtocolGuid
+
+ ## CONSUMES
+ gEfiGlobalNvsAreaProtocolGuid
+
+ ## CONSUMES
+ gEfiSmmSwDispatch2ProtocolGuid
+
+ ## SOMETIMES_CONSUMES
+ gEfiSmmPowerButtonDispatch2ProtocolGuid
+
+ ## CONSUMES
+ gEfiSmmSxDispatch2ProtocolGuid
+
+ ## CONSUMES
+ gEfiSmmVariableProtocolGuid
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+ BraswellPlatformPkg/BraswellPlatformPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[Pcd]
+ ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart ## CONSUMES
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize ## SOMETIMES_CONSUMES
+ gEfiEdkIIPlatformTokenSpaceGuid.PcdSystemConfiguration
+
+[Depex]
+ gEfiSmmBase2ProtocolGuid AND
+ gEfiSmmAccess2ProtocolGuid AND
+ gEfiSmmPowerButtonDispatch2ProtocolGuid AND
+ gEfiSmmSxDispatch2ProtocolGuid AND
+ gEfiSmmIchnDispatchProtocolGuid AND
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiVariableArchProtocolGuid
+
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiSmm/Platform.c b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/Platform.c
new file mode 100644
index 0000000000..bf58f6ca41
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/Platform.c
@@ -0,0 +1,831 @@
+/** @file
+ Generic template for a child of the IchSmm driver.
+
+ Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 "AcpiSmm.h"
+#include <Protocol/CpuIo2.h>
+
+//
+// Local variables
+//
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+} EFI_PCI_BUS_MASTER;
+
+EFI_PCI_BUS_MASTER mPciBm[] = {
+ { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 },
+ { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 },
+ { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 },
+ { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 },
+};
+
+UINT16 mAcpiBaseAddr;
+SYSTEM_CONFIGURATION mSystemConfiguration;
+UINT16 mPM1_SaveState16;
+UINT32 mGPE_SaveState32;
+
+//
+// Variables. Need to initialize this from Setup
+//
+BOOLEAN mWakeOnLanS5Variable;
+BOOLEAN mWakeOnRtcVariable;
+UINT8 mWakeupDay;
+UINT8 mWakeupHour;
+UINT8 mWakeupMinute;
+UINT8 mWakeupSecond;
+
+//
+// Use an enum. 0 is Stay Off, 1 is Last State, 2 is Stay On
+//
+UINT8 mAcLossVariable;
+
+static
+UINT8 mTco1Sources[] = {
+ IchnNmi
+};
+
+UINTN
+DevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+VOID
+S4S5ProgClock();
+
+EFI_STATUS
+InitRuntimeScriptTable (
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+VOID
+EnableS5WakeOnRtc();
+
+UINT8
+HexToBcd (
+ UINT8 HexValue
+ );
+
+UINT8
+BcdToHex(
+ IN UINT8 BcdValue
+ );
+
+VOID
+CpuSmmSxWorkAround (
+ );
+
+
+/*++
+ Set the AC Loss to turn on or off.
+
+ @param[in] Turn on or off.
+
+ @retval None
+
+--*/
+
+VOID
+SetAfterG3On (
+ BOOLEAN Enable
+ )
+{
+ UINT8 PmCon1;
+
+ //
+ // ICH handling portion
+ //
+ PmCon1 = MmioRead8 ( PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 );
+ PmCon1 &= ~B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
+ if (Enable) {
+ PmCon1 |= B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
+ }
+ MmioWrite8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, PmCon1);
+
+}
+
+/**
+ Allocate EfiACPIMemoryNVS below 4G memory address.
+
+ This function allocates EfiACPIMemoryNVS below 4G memory address.
+
+ @param Size Size of memory to allocate.
+
+ @return Allocated address for output.
+
+**/
+VOID*
+AllocateAcpiNvsMemoryBelow4G (
+ IN UINTN Size
+ )
+{
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ VOID* Buffer;
+
+ Pages = EFI_SIZE_TO_PAGES (Size);
+ Address = 0xffffffff;
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ Pages,
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Buffer = (VOID *) (UINTN) Address;
+ ZeroMem (Buffer, Size);
+
+ return Buffer;
+}
+
+EFI_STATUS
+EFIAPI
+AllocateS3AcpiReservedMemory (
+ VOID
+)
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT64 MemoryLength;
+ RESERVED_ACPI_S3_RANGE *AcpiS3Range;
+ EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
+ VOID *GuidHob;
+ VOID *AcpiReservedBase;
+
+ //
+ // Calculate the system memory length by memory hobs
+ //
+ MemoryLength = 0x100000;
+
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ if (Hob.Raw == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) {
+ if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ //
+ // Skip the memory region below 1MB
+ //
+ if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) {
+ MemoryLength += Hob.ResourceDescriptor->ResourceLength;
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ //
+ // Find the location of reserved page in TSEG. This was reserved by the MRC.
+ //
+ GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
+ if (GuidHob != NULL) {
+ SmramDescriptor = (EFI_SMRAM_DESCRIPTOR*) GET_GUID_HOB_DATA (GuidHob);
+
+ //
+ // Now find the location of the data structure that is used to store the address
+ // of the S3 reserved memory.
+ //
+ AcpiS3Range = (RESERVED_ACPI_S3_RANGE*) (UINTN) (SmramDescriptor->PhysicalStart +
+ RESERVED_ACPI_S3_RANGE_OFFSET);
+
+ //
+ // Allocate reserved ACPI memory for S3 resume. Pointer to this region is
+ // stored in SMRAM in the first page of TSEG.
+ //
+ AcpiReservedBase = AllocateAcpiNvsMemoryBelow4G (
+ PcdGet32 (PcdS3AcpiReservedMemorySize)
+ );
+ if (AcpiReservedBase != NULL) {
+ AcpiS3Range->AcpiReservedMemoryBase = (UINT32)(UINTN) AcpiReservedBase;
+ AcpiS3Range->AcpiReservedMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);
+ }
+
+ AcpiS3Range->SystemMemoryLength = (UINT32)MemoryLength;
+
+ DEBUG ((EFI_D_ERROR, "S3 Memory Base: %08X\n", AcpiS3Range->AcpiReservedMemoryBase));
+ DEBUG ((EFI_D_ERROR, "S3 Memory Size: %08X\n", AcpiS3Range->AcpiReservedMemorySize));
+ DEBUG ((EFI_D_ERROR, "S3 SysMemoryLength: %08X\n", AcpiS3Range->SystemMemoryLength));
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+/**
+ Initializes the SMM Handler Driver
+
+ @param[in] ImageHandle
+ @param[in] SystemTable
+
+ @retval None
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePlatformSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PowerButtonContext;
+ EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *PowerButtonDispatch;
+ EFI_SMM_ICHN_DISPATCH_PROTOCOL *IchnDispatch;
+ EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;
+ EFI_SMM_SX_REGISTER_CONTEXT EntryDispatchContext;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+ EFI_BOOT_MODE BootMode;
+
+ Handle = NULL;
+
+ //
+ // Get the ACPI Base Address
+ //
+
+ mAcpiBaseAddr = PchLpcPciCfg16( R_PCH_LPC_ACPI_BASE ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ CopyMem (&mSystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof (SYSTEM_CONFIGURATION));
+ mAcLossVariable = mSystemConfiguration.StateAfterG3;
+ mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5;
+
+ BootMode = GetBootModeHob ();
+
+ //
+ // Get the Power Button protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmPowerButtonDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &PowerButtonDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode != BOOT_ON_FLASH_UPDATE) {
+ //
+ // Register for the power button event
+ //
+ PowerButtonContext.Phase = EfiPowerButtonEntry;
+ Status = PowerButtonDispatch->Register (
+ PowerButtonDispatch,
+ PowerButtonCallback,
+ &PowerButtonContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ //
+ // Get the Sx dispatch protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSxDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &SxDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register entry phase call back function
+ //
+ EntryDispatchContext.Type = SxS3;
+ EntryDispatchContext.Phase = SxEntry;
+
+ Status = SxDispatch->Register (
+ SxDispatch,
+ SxSleepEntryCallBack,
+ &EntryDispatchContext,
+ &Handle
+ );
+
+ EntryDispatchContext.Type = SxS4;
+
+ Status = SxDispatch->Register (
+ SxDispatch,
+ S4S5CallBack,
+ &EntryDispatchContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ EntryDispatchContext.Type = SxS5;
+
+ Status = SxDispatch->Register (
+ SxDispatch,
+ S4S5CallBack,
+ &EntryDispatchContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SxDispatch->Register (
+ SxDispatch,
+ S5SleepAcLossCallBack,
+ &EntryDispatchContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get the Sw dispatch protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSwDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &SwDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register ACPI enable handler
+ //
+ SwContext.SwSmiInputValue = ACPI_ENABLE;
+ Status = SwDispatch->Register (
+ SwDispatch,
+ EnableAcpiCallback,
+ &SwContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register ACPI disable handler
+ //
+ SwContext.SwSmiInputValue = ACPI_DISABLE;
+ Status = SwDispatch->Register (
+ SwDispatch,
+ DisableAcpiCallback,
+ &SwContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get the ICHn protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmIchnDispatchProtocolGuid,
+ NULL,
+ (VOID **) &IchnDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SetAfterG3On (TRUE);
+
+ AllocateS3AcpiReservedMemory ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+ @retval EFI_SUCCESS Operation successfully performed
+
+**/
+EFI_STATUS
+SxSleepEntryCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+
+{
+//
+// EFI_STATUS Status;
+//
+// REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeS3SuspendStart));
+// Status = SaveRuntimeScriptTable ();
+// if (EFI_ERROR (Status)) {
+// return Status;
+// }
+//
+ return EFI_SUCCESS;
+}
+
+/**
+ When a power button event happens, it shuts off the machine.
+
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+ @retval
+
+**/
+EFI_STATUS
+PowerButtonCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+
+ UINT16 data16;
+
+ //
+ // Set what the state to return to after AC Loss. If Last State, then
+ // set it to Off.
+ //
+ SetAfterG3On (TRUE);
+
+ if (mWakeOnRtcVariable) {
+ EnableS5WakeOnRtc();
+ }
+
+ data16 = (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN));
+ data16 &= B_PCH_ACPI_GPE0a_EN_PCI_EXP;
+
+ //
+ // Clear Sleep SMI Status
+ //
+ IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_STS,
+ (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_SMI_STS) | B_PCH_SMI_STS_ON_SLP_EN));
+ //
+ // Clear Sleep Type Enable
+ //
+ IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_EN,
+ (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_SMI_EN) & (~B_PCH_SMI_EN_ON_SLP_EN)));
+
+ //
+ // Clear Power Button Status
+ //
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
+
+ //
+ // Shut it off now!
+ //
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, B_PCH_ACPI_PM1_CNT_SLP_EN | V_PCH_ACPI_PM1_CNT_S5);
+
+ //
+ // Should not return
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+**/
+EFI_STATUS
+EFIAPI
+S5SleepAcLossCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+ @retval Clears the Save State bit in the clock.
+
+**/
+EFI_STATUS
+EFIAPI
+S4S5CallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+VOID
+S4S5ProgClock()
+{
+}
+
+/**
+ SMI handler to enable ACPI mode
+
+ Dispatched on reads from APM port with value 0xA0
+
+ Disables the SW SMI Timer.
+ ACPI events are disabled and ACPI event status is cleared.
+ SCI mode is then enabled.
+
+ Disable SW SMI Timer
+
+ Clear all ACPI event status and disable all ACPI events
+ Disable PM sources except power button
+ Clear status bits
+
+ Disable GPE0 sources
+ Clear status bits
+
+ Disable GPE1 sources
+ Clear status bits
+
+ Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
+
+ Enable SCI
+
+ @param[in] DispatchHandle EFI Handle
+ @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+ @retval Nothing
+
+**/
+EFI_STATUS
+EFIAPI
+EnableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ UINT16 Pm1Cnt;
+
+ //
+ // Enable SCI
+ //
+ Pm1Cnt = IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
+ Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ SMI handler to disable ACPI mode
+
+ Dispatched on reads from APM port with value 0xA1
+
+ ACPI events are disabled and ACPI event status is cleared.
+ SCI mode is then disabled.
+ Clear all ACPI event status and disable all ACPI events
+ Disable PM sources except power button
+ Clear status bits
+ Disable GPE0 sources
+ Clear status bits
+ Disable GPE1 sources
+ Clear status bits
+ Disable SCI
+
+ @param[in] DispatchHandle EFI Handle
+ @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+ @retval Nothing
+
+**/
+EFI_STATUS
+EFIAPI
+DisableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ UINT16 Pm1Cnt;
+
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, mPM1_SaveState16);
+
+ IoWrite32 (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);
+ IoWrite32 (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, mGPE_SaveState32);
+
+ //
+ // Disable SCI
+ //
+ Pm1Cnt = IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
+ Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SCI_EN;
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ When an unknown event happen.
+
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+ @retval None
+
+**/
+EFI_STATUS
+EFIAPI
+DummyTco1Callback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+UINTN
+DevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!IsDevicePathEnd (DevicePath)) {
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+}
+
+/**
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+**/
+EFI_STATUS
+S5SleepWakeOnRtcCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EnableS5WakeOnRtc();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ @retval 1. Check Alarm interrupt is not set.
+ 2. Clear Alarm interrupt.
+ 2. Set RTC wake up date and time.
+ 2. Enable RTC wake up alarm.
+ 3. Enable ICH PM1 EN Bit 10(RTC_EN)
+
+**/
+VOID
+EnableS5WakeOnRtc()
+{
+ UINT8 CmosData;
+ UINTN i;
+
+ if (!mSystemConfiguration.WakeOnRtcS5) {
+ return;
+ }
+ mWakeupDay = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupDate);
+ mWakeupHour = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupTimeHour);
+ mWakeupMinute = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupTimeMinute);
+ mWakeupSecond = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupTimeSecond);
+
+ //
+ // Check RTC alarm interrupt is enabled. If enabled, someone already
+ // grabbed RTC alarm. Just return.
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
+ if (IoRead8 (PCAT_RTC_DATA_REGISTER) & B_RTC_ALARM_INT_ENABLE) {
+ return;
+ }
+
+ //
+ // Set Date
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
+ CmosData = IoRead8 (PCAT_RTC_DATA_REGISTER);
+ CmosData &= ~(B_RTC_DATE_ALARM_MASK);
+ CmosData |= mWakeupDay;
+ for (i = 0; i < 0xffff; i++) {
+ IoWrite8 (PCAT_RTC_DATA_REGISTER, CmosData);
+ SmmStall (1);
+ if(((CmosData = IoRead8 (PCAT_RTC_DATA_REGISTER)) & B_RTC_DATE_ALARM_MASK)
+ == mWakeupDay) {
+ break;
+ }
+ }
+
+ //
+ // Set Second
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECOND_ALARM);
+ for (i = 0; i < 0xffff; i++) {
+ IoWrite8 (PCAT_RTC_DATA_REGISTER, mWakeupSecond);
+ SmmStall (1);
+ if (IoRead8 (PCAT_RTC_DATA_REGISTER) == mWakeupSecond) {
+ break;
+ }
+ }
+
+ //
+ // Set Minute
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTE_ALARM);
+ for (i = 0; i < 0xffff; i++) {
+ IoWrite8 (PCAT_RTC_DATA_REGISTER, mWakeupMinute);
+ SmmStall (1);
+ if (IoRead8 (PCAT_RTC_DATA_REGISTER) == mWakeupMinute) {
+ break;
+ }
+ }
+
+ //
+ // Set Hour
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOUR_ALARM);
+ for (i = 0; i < 0xffff; i++) {
+ IoWrite8 (PCAT_RTC_DATA_REGISTER, mWakeupHour);
+ SmmStall (1);
+ if (IoRead8 (PCAT_RTC_DATA_REGISTER) == mWakeupHour) {
+ break;
+ }
+ }
+
+ //
+ // Wait for UIP to arm RTC alarm
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
+ while (IoRead8 (PCAT_RTC_DATA_REGISTER) & 0x80);
+
+ //
+ // Read RTC register 0C to clear pending RTC interrupts
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
+ IoRead8 (PCAT_RTC_DATA_REGISTER);
+
+ //
+ // Enable RTC Alarm Interrupt
+ //
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
+ IoWrite8 (PCAT_RTC_DATA_REGISTER, IoRead8 (PCAT_RTC_DATA_REGISTER) | B_RTC_ALARM_INT_ENABLE);
+
+ //
+ // Clear ICH RTC Status
+ //
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_RTC);
+
+ //
+ // Enable ICH RTC event
+ //
+ IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_EN,
+ (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_EN) | B_PCH_ACPI_PM1_EN_RTC));
+}
+
+UINT8
+HexToBcd (
+ IN UINT8 HexValue
+ )
+{
+ UINTN HighByte;
+ UINTN LowByte;
+
+ HighByte = (UINTN) HexValue / 10;
+ LowByte = (UINTN) HexValue % 10;
+
+ return ((UINT8) (LowByte + (HighByte << 4)));
+}
+
+UINT8
+BcdToHex (
+ IN UINT8 BcdValue
+ )
+{
+ UINTN HighByte;
+ UINTN LowByte;
+
+ HighByte = (UINTN) ((BcdValue >> 4) * 10);
+ LowByte = (UINTN) (BcdValue & 0x0F);
+
+ return ((UINT8) (LowByte + HighByte));
+}
+
diff --git a/BraswellPlatformPkg/Common/Acpi/AcpiSmm/S3Save.c b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/S3Save.c
new file mode 100644
index 0000000000..690cb12b88
--- /dev/null
+++ b/BraswellPlatformPkg/Common/Acpi/AcpiSmm/S3Save.c
@@ -0,0 +1,402 @@
+/** @file
+ SMM S3 handler driver implementation.
+
+ Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 "AcpiSmm.h"
+
+extern UINT16 mAcpiBaseAddr;
+EFI_PHYSICAL_ADDRESS mRuntimeScriptTableBase;
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+ VOID
+ )
+{
+ SMM_PCI_IO_ADDRESS PciAddress;
+ UINT32 Data32;
+ UINT16 Data16;
+ UINT8 Data8;
+ UINT8 Mask;
+ UINTN Index;
+ UINTN Offset;
+ UINT8 RegTable[] = {
+
+ //Bus , Dev, Func,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+
+ //Bus , Dev, Func, CUnit Device
+ 0x00 , 0x00, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0,
+
+ //Bus , Dev, Func, IGD Device
+ 0x00 , 0x02, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x81, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00,
+
+ //Bus , Dev, Func, IUnit Device
+ 0x00 , 0x03, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, ISH Device
+ 0x00 , 0x0A, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, PUnit Device
+ 0x00 , 0x0B, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, eMMC Device
+ 0x00 , 0x10, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, SDIO Device
+ 0x00 , 0x11, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, SDCard Device
+ 0x00 , 0x12, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //
+ //Bus , Dev, Func, SATA Device
+ 0x00 , 0x13, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0xA3, 0x27, 0x30, 0xF1, 0x1D, 0x00, 0x40,
+
+ //
+ //Bus , Dev, Func, xHCI Device
+ 0x00 , 0x14, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+
+ //Bus , Dev, Func, LPE Device
+ 0x00 , 0x15, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, USB OTG Device
+ 0x00 , 0x16, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 DMA Device
+ 0x00 , 0x18, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C0 Device
+ 0x00 , 0x18, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C1 Device
+ 0x00 , 0x18, 0x02,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C2 Device
+ 0x00 , 0x18, 0x03,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C3 Device
+ 0x00 , 0x18, 0x04,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C4 Device
+ 0x00 , 0x18, 0x05,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C5 Device
+ 0x00 , 0x18, 0x06,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO2 I2C6 Device
+ 0x00 , 0x18, 0x07,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, SEC Device
+ 0x00 , 0x1A, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+
+ //Bus , Dev, Func, HD Audio Device
+ 0x00 , 0x1B, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ //
+ //Bus , Dev, Func, SMBUS device
+ //
+ //Bus , Dev, Func, PCIe Root Port #1
+ 0x00 , 0x1C, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, PCIe Root Port #2
+ 0x00 , 0x1C, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, PCIe Root Port #3
+ 0x00 , 0x1C, 0x02,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, PCIe Root Port #4
+ 0x00 , 0x1C, 0x03,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //
+ //Bus , Dev, Func, VGA bus1
+ //
+ //Bus , Dev, Func, LPIO1 DMA Device
+ 0x00 , 0x1E, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 PWM0 Device
+ 0x00 , 0x1E, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 PWM1 Device
+ 0x00 , 0x1E, 0x02,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 HSUART0 Device
+ 0x00 , 0x1E, 0x03,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 HSUART1 Device
+ 0x00 , 0x1E, 0x04,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 SPI Device
+ 0x00 , 0x1E, 0x05,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 SPI2 Device
+ 0x00 , 0x1E, 0x06,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, LPIO1 SPI3 Device
+ 0x00 , 0x1E, 0x07,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, PCU Device
+ 0x00 , 0x1F, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x00 , 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, SMBUS Device
+ 0x00 , 0x1F, 0x03,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x32 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ //
+ //Bus , Dev, Func, Bus 1 Function 0
+ 0x01 , 0x00, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0x58 , 0x93, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 1 Function 1
+ 0x01 , 0x00, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 2 Function 0
+ 0x02 , 0x00, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 2 Function 1
+ 0x02 , 0x00, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 3 Function 0
+ 0x03 , 0x00, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 3 Function 1
+ 0x03 , 0x00, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 4 Function 0
+ 0x04 , 0x00, 0x00,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //Bus , Dev, Func, Bus 4 Function 1
+ 0x04 , 0x00, 0x01,
+ //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
+ 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+
+ //
+ //0xFF indicates the end of the table
+ //
+ 0xFF
+ };
+
+ //
+ // These registers have to set in byte order
+ //
+ UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings
+
+ //
+ // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
+ // and vital to S3 resume. That's why we put save code here
+ //
+ PciAddress.Bus = 0;
+ PciAddress.Device = 0;
+ PciAddress.Function = 0;
+ PciAddress.ExtendedRegister = 0;
+
+ for (Index = 0; Index < 2; Index++) {
+ //
+ // Read SRAM setting from Pci(0, 0, 0)
+ //
+ PciAddress.Register = ExtReg[Index];
+ Data8 = MmioRead8 (
+ MmPciAddress (0,
+ PciAddress.Bus,
+ PciAddress.Device,
+ PciAddress.Function,
+ PciAddress.Register
+ )
+ );
+
+ //
+ // Save latest settings to runtime script table
+ //
+ S3BootScriptSavePciCfgWrite (
+ S3BootScriptWidthUint8,
+ *(UINT64 *) &PciAddress,
+ 1,
+ &Data8
+ );
+ }
+
+ //
+ // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
+ // and vital to S3 resume. That's why we put save code here
+ //
+ Index = 0;
+ while (RegTable[Index] != 0xFF) {
+
+ PciAddress.Bus = RegTable[Index++];
+ PciAddress.Device = RegTable[Index++];
+ PciAddress.Function = RegTable[Index++];
+ PciAddress.Register = 0;
+ PciAddress.ExtendedRegister = 0;
+
+ Data16 = MmioRead16 (
+ MmPciAddress (0,
+ PciAddress.Bus,
+ PciAddress.Device,
+ PciAddress.Function,
+ PciAddress.Register
+ )
+ );
+
+ if (Data16 == 0xFFFF) {
+ Index+=8;
+ continue;
+ }
+
+ for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
+
+ if (Mask == 0x00) {
+ Mask = 0x01;
+ }
+
+ if (RegTable[Index + Offset/32] & Mask ) {
+
+ PciAddress.Register = (UINT8) Offset;
+ Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
+
+ //
+ // Save latest settings to runtime script table
+ //
+ S3BootScriptSavePciCfgWrite (
+ S3BootScriptWidthUint32,
+ *(UINT64 *) &PciAddress,
+ 1,
+ &Data32
+ );
+ }
+ }
+
+ Index += 8;
+
+ }
+
+ //
+ // Save I/O ports to S3 script table
+ //
+
+ //
+ // Selftest KBC
+ //
+ Data8 = 0xAA;
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint8,
+ 0x64,
+ (UINTN)1,
+ &Data8
+ );
+
+ Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
+
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint32,
+ (mAcpiBaseAddr + R_PCH_SMI_EN),
+ 1,
+ &Data32
+ );
+
+ //
+ // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
+ //
+ Data16 = IoRead16 (mAcpiBaseAddr + R_PCH_TCO_CNT);
+
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint16,
+ mAcpiBaseAddr + R_PCH_TCO_CNT,
+ 1,
+ &Data16
+ );
+
+ return EFI_SUCCESS;
+}