summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/PowerManagement/Smm
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/PowerManagement/Smm')
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.c333
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.cif13
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.dxs45
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.h68
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.inf97
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.mak64
-rw-r--r--ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.sdl25
7 files changed, 645 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.c b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.c
new file mode 100644
index 0000000..6a26231
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.c
@@ -0,0 +1,333 @@
+/** @file
+ This is the SMM driver for saving and restoring the powermanagement related MSRs
+
+@copyright
+ Copyright (c) 2011 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PowerMgmtS3.h"
+#include "PowerMgmtDefinitions.h"
+#include "CpuAccess.h"
+#include "CpuPlatformLib.h"
+
+#include EFI_PROTOCOL_DEPENDENCY (CpuPlatformPolicy)
+#include EFI_PROTOCOL_DEPENDENCY (SmmSwDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+
+///
+/// SMM system table pointer
+///
+EFI_SMM_SYSTEM_TABLE *mSmst;
+DXE_CPU_PLATFORM_POLICY_PROTOCOL *mCpuPlatformPolicy;
+///
+/// MSR table for S3 resume
+///
+STATIC EFI_MSR_VALUES mMsrValues[] = {
+ { MSR_IA32_PERF_CTRL, 0, B_IA32_PERF_CTRLP_STATE_TARGET, TRUE },
+ { MSR_PMG_IO_CAPTURE_BASE, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_PMG_CST_CONFIG, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_MISC_PWR_MGMT, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_IA32_MISC_ENABLE, 0, B_CPUID_POWER_MANAGEMENT_EAX_TURBO | B_MSR_IA32_MISC_DISABLE_TURBO | B_MSR_IA32_MISC_ENABLE_MONITOR | B_MSR_IA32_MISC_ENABLE_TME | B_MSR_IA32_MISC_ENABLE_EIST, TRUE },
+ { MSR_POWER_CTL, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_PACKAGE_POWER_LIMIT, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_PLATFORM_POWER_LIMIT, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_C_STATE_LATENCY_CONTROL_0, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_C_STATE_LATENCY_CONTROL_1, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_C_STATE_LATENCY_CONTROL_2, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_C_STATE_LATENCY_CONTROL_3, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_C_STATE_LATENCY_CONTROL_4, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_C_STATE_LATENCY_CONTROL_5, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_FLEX_RATIO, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_IA32_ENERGY_PERFORMANCE_BIAS, 0, 0xFFFFFFFFFFFFFFFF, TRUE },
+ { MSR_CONFIG_TDP_CONTROL, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_RFI_TUNNING, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_TURBO_ACTIVATION_RATIO, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_DDR_RAPL_LIMIT, 0, 0xFFFFFFFFFFFFFFFF, FALSE },
+ { MSR_TURBO_RATIO_LIMIT, 0, 0xFFFFFFFFFFFFFFFF, TRUE }
+};
+
+/**
+ Save processor MSR runtime settings for S3.
+
+ @retval EFI_SUCCESS Processor MSR setting is saved.
+**/
+STATIC
+EFI_STATUS
+S3SaveMsr (
+ VOID
+ )
+{
+ UINT32 Index;
+ EFI_CPUID_REGISTER Cpuid06 = { 0, 0, 0, 0 };
+ UINT64 MsrValue;
+
+ for (Index = 0; Index < sizeof (mMsrValues) / sizeof (EFI_MSR_VALUES); Index++) {
+ DEBUG ((EFI_D_INFO, " MSR Number: %x\n", mMsrValues[Index].Index));
+ if (mMsrValues[Index].Index == MSR_IA32_ENERGY_PERFORMANCE_BIAS) {
+ ///
+ /// MSR_IA32_ENERGY_PERFORMANCE_BIAS (1B0h) is accessible only if CPUID(6), ECX[3] = 1 to indicate feature availability.
+ ///
+ AsmCpuid (CPUID_FUNCTION_6, &Cpuid06.RegEax, &Cpuid06.RegEbx, &Cpuid06.RegEcx, &Cpuid06.RegEdx);
+ if (!(Cpuid06.RegEcx & B_CPUID_POWER_MANAGEMENT_ECX_ENERGY_EFFICIENT_POLICY_SUPPORT)) {
+ mMsrValues[Index].RestoreFlag = FALSE;
+ continue;
+ }
+ }
+ ///
+ /// Check for HSW specific MSRs
+ ///
+ MsrValue = AsmReadMsr64 (MSR_PLATFORM_INFO);
+ ///
+ ///
+ /// Check PLATFORM_INFO MSR[34:33] > 0 before accessing the MSR_CONFIG_TDP_CONTROL
+ ///
+ if ((mMsrValues[Index].Index == MSR_CONFIG_TDP_CONTROL) &&
+ ((RShiftU64 (MsrValue, N_MSR_PLATFORM_INFO_CONFIG_TDP_NUM_LEVELS_OFFSET) & 0x03))
+ ) {
+ mMsrValues[Index].RestoreFlag = TRUE;
+ }
+ ///
+ /// MSR_TURBO_ACTIVATION_RATIO, MSR_DDR_RAPL_LIMIT, MSR_RFI_TUNNING are supported only on HSW A0 or above.
+ ///
+ if (mMsrValues[Index].Index == MSR_TURBO_ACTIVATION_RATIO) {
+ mMsrValues[Index].RestoreFlag = TRUE;
+ }
+ if (mMsrValues[Index].Index == MSR_DDR_RAPL_LIMIT) {
+ mMsrValues[Index].RestoreFlag = TRUE;
+ }
+ ///
+ /// Check PLATFORM_INFO MSR[25] == 1 before accessing the MSR_RFI_TUNNING
+ ///
+ if (mMsrValues[Index].Index == MSR_RFI_TUNNING) {
+ if ((mCpuPlatformPolicy->PowerMgmtConfig->RfiFreqTunningOffset != AUTO) && (MsrValue & B_FIVR_RFI_TUNING_AVAIL)) {
+ mMsrValues[Index].RestoreFlag = TRUE;
+ }
+ }
+
+ if(GetCpuSku()== EnumCpuUlt) {
+ if ((mMsrValues[Index].Index == MSR_C_STATE_LATENCY_CONTROL_3) ||
+ (mMsrValues[Index].Index == MSR_C_STATE_LATENCY_CONTROL_4)||
+ (mMsrValues[Index].Index == MSR_C_STATE_LATENCY_CONTROL_5)){
+ mMsrValues[Index].RestoreFlag = TRUE;
+ }
+ }
+
+ ///
+ /// PL3 is supported on HSW ULT C0 & HSW C0 and later
+ ///
+ if (mMsrValues[Index].Index == MSR_PLATFORM_POWER_LIMIT) {
+ if (((GetCpuFamily() == EnumCpuHsw) && (GetCpuStepping() >= EnumHswC0))
+ || ((GetCpuFamily() == EnumCpuHswUlt) && (GetCpuStepping() >= EnumHswUltC0))) {
+ mMsrValues[Index].RestoreFlag = TRUE;
+ }
+ }
+
+ if (mMsrValues[Index].RestoreFlag == TRUE) {
+ mMsrValues[Index].Value = AsmReadMsr64 (mMsrValues[Index].Index);
+ DEBUG ((EFI_D_INFO, " MSR Number %x read Done \n", mMsrValues[Index].Index));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Restore processor MSR runtime settings for S3.
+
+ @param[in] DispatchHandle - The handle of this callback, obtained when registering
+ @param[in] DispatchContex - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+ @retval EFI_SUCCESS Processor MSR setting is restored.
+**/
+void
+S3RestoreMsr (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContex
+ )
+{
+ ///
+ /// Restore MSR's on all logical processors.
+ ///
+ RunOnAllLogicalProcessors (ApSafeRestoreMsr, NULL);
+}
+
+/**
+ Runs the specified procedure on all logical processors, passing in the
+ parameter buffer to the procedure.
+
+ @param[in] Procedure The function to be run.
+ @param[in] Buffer Pointer to a parameter buffer.
+
+ @retval EFI_SUCCESS
+**/
+STATIC
+EFI_STATUS
+RunOnAllLogicalProcessors (
+ IN OUT EFI_AP_PROCEDURE Procedure,
+ IN OUT VOID *Buffer
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+ ///
+ /// Run the procedure on all logical processors.
+ ///
+ (*Procedure)(Buffer);
+ for (Index = 1; Index < mSmst->NumberOfCpus; Index++) {
+ Status = EFI_NOT_READY;
+ while (Status != EFI_SUCCESS) {
+ Status = mSmst->SmmStartupThisAp (Procedure, Index, Buffer);
+ if (Status != EFI_SUCCESS) {
+ ///
+ /// SmmStartupThisAp might return failure if AP is busy executing some other code. Let's wait for sometime and try again.
+ ///
+ PchPmTimerStall (PPM_WAIT_PERIOD);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function will restore MSR settings.
+
+ This function must be MP safe.
+
+ @param[in] Buffer Unused
+
+ @retval EFI_SUCCESS MSR restored
+**/
+VOID
+EFIAPI
+ApSafeRestoreMsr (
+ IN OUT VOID *Buffer
+ )
+{
+ UINT32 Index;
+ UINT64 MsrValue;
+
+ for (Index = 0; Index < sizeof (mMsrValues) / sizeof (EFI_MSR_VALUES); Index++) {
+ ///
+ /// Check RestoreFlag and skip restoring the MSR if it is set to FALSE
+ ///
+ if (mMsrValues[Index].RestoreFlag == FALSE) {
+ DEBUG ((EFI_D_INFO, "Skipping MSR : %x as RestoreFalg is set to FALSE \n", mMsrValues[Index].Index));
+ continue;
+ }
+ ///
+ /// Check for Lock bits before programming
+ ///
+ MsrValue = AsmReadMsr64 (mMsrValues[Index].Index);
+ if ((mMsrValues[Index].Index == MSR_CONFIG_TDP_CONTROL) && (MsrValue & CONFIG_TDP_CONTROL_LOCK)) {
+ continue;
+ }
+
+ if ((mMsrValues[Index].Index == MSR_TURBO_ACTIVATION_RATIO) && (MsrValue & MSR_TURBO_ACTIVATION_RATIO_LOCK)) {
+ continue;
+ }
+
+ if ((mMsrValues[Index].Index == MSR_PACKAGE_POWER_LIMIT) && (MsrValue & B_POWER_LIMIT_LOCK)) {
+ continue;
+ }
+
+ if ((mMsrValues[Index].Index == MSR_PLATFORM_POWER_LIMIT) && (MsrValue & B_POWER_LIMIT_LOCK)) {
+ continue;
+ }
+
+ if ((mMsrValues[Index].Index == MSR_DDR_RAPL_LIMIT) && (MsrValue & B_POWER_LIMIT_LOCK)) {
+ continue;
+ }
+
+ MsrValue = AsmReadMsr64 (mMsrValues[Index].Index);
+ MsrValue &= ~mMsrValues[Index].BitMask;
+ MsrValue |= (mMsrValues[Index].Value & mMsrValues[Index].BitMask);
+ AsmWriteMsr64 (mMsrValues[Index].Index, MsrValue);
+ }
+
+ return;
+}
+
+/**
+ Initialize the S3 power management Handler.
+
+ @param[in] ImageHandle - Pointer to the loaded image protocol for this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The driver installes/initialized correctly.
+**/
+EFI_STATUS
+PowerMgmtS3SmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
+ EFI_HANDLE SwHandle;
+ EFI_SMM_BASE_PROTOCOL *SmmBase;
+
+ SwHandle = 0;
+ DEBUG ((EFI_D_INFO, " PpmS3SmmEntryPoint Started : \n"));
+ ///
+ /// Determine if we are in boot service or SMM.
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &SmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize global variables
+ ///
+ Status = SmmBase->GetSmstLocation (SmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate platform configuration information
+ ///
+ Status = gBS->LocateProtocol (&gDxeCpuPlatformPolicyProtocolGuid, NULL, (VOID **) &mCpuPlatformPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate the ICH SMM SW dispatch protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid, NULL, (VOID **) &SwDispatch);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Register ACPI S3 MSR restore handler
+ ///
+ SwContext.SwSmiInputValue = mCpuPlatformPolicy->PowerMgmtConfig->S3RestoreMsrSwSmiNumber;
+
+ Status = SwDispatch->Register (
+ SwDispatch,
+ (EFI_SMM_SW_DISPATCH) S3RestoreMsr,
+ &SwContext,
+ &SwHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Save MSRs for S3 Resume.
+ ///
+ DEBUG ((EFI_D_INFO, " Saving Processor MSR for S3 Resume \n"));
+
+ S3SaveMsr ();
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.cif b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.cif
new file mode 100644
index 0000000..8e974fc
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PowerMgmtS3"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Haswell\PowerManagement\Smm"
+ RefName = "PowerMgmtS3"
+[files]
+"PowerMgmtS3.mak"
+"PowerMgmtS3.sdl"
+"PowerMgmtS3.inf"
+"PowerMgmtS3.c"
+"PowerMgmtS3.dxs"
+"PowerMgmtS3.h"
+<endComponent>
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.dxs b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.dxs
new file mode 100644
index 0000000..9a4a4a2
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.dxs
@@ -0,0 +1,45 @@
+/** @file
+ Dispatch dependency expression file for the PpmS3Dxe driver.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+//-#include EFI_PROTOCOL_DEFINITION (SmmControl)
+#include EFI_PROTOCOL_DEFINITION (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmSwDispatch)
+#include EFI_PROTOCOL_DEFINITION (PowerMgmtInitDone)
+#include EFI_PROTOCOL_DEFINITION (SaInfo)
+#endif
+
+DEPENDENCY_START
+ //-EFI_SMM_CONTROL_PROTOCOL_GUID AND
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+ EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID AND
+ EFI_SA_INFO_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.h b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.h
new file mode 100644
index 0000000..211ef02
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file for PpmS3 Smm Driver.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _POWER_MGMT_S3_SMM_H_
+#define _POWER_MGMT_S3_SMM_H_
+
+#include "EdkIIGlueDxe.h"
+#include "EfiScriptLib.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+
+#define PPM_WAIT_PERIOD 15
+
+typedef struct _EFI_MSR_VALUES {
+ UINT16 Index;
+ UINT64 Value;
+ UINT64 BitMask;
+ BOOLEAN RestoreFlag;
+} EFI_MSR_VALUES;
+
+/**
+ Runs the specified procedure on all logical processors, passing in the
+ parameter buffer to the procedure.
+
+ @param[in] Procedure The function to be run.
+ @param[in] Buffer Pointer to a parameter buffer.
+
+ @retval EFI_SUCCESS
+**/
+STATIC
+EFI_STATUS
+RunOnAllLogicalProcessors (
+ IN OUT EFI_AP_PROCEDURE Procedure,
+ IN OUT VOID *Buffer
+ );
+/**
+ This function will restore MSR settings.
+
+ This function must be MP safe.
+
+ @param[in] Buffer Unused
+
+ @retval EFI_SUCCESS MSR restored
+**/
+VOID
+EFIAPI
+ApSafeRestoreMsr (
+ IN OUT VOID *Buffer
+ );
+
+#endif
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.inf b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.inf
new file mode 100644
index 0000000..8b93a5d
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.inf
@@ -0,0 +1,97 @@
+## @file
+# Component description file for PowerManagementDxe driver
+#
+#@copyright
+# Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PowerMgmtS3
+FILE_GUID = 8F0B5301-C79B-44f1-8FD3-26D73E316700
+COMPONENT_TYPE = RT_DRIVER
+
+[sources.common]
+ PowerMgmtS3.h
+ PowerMgmtS3.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+[includes.common]
+ .
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EFI_SOURCE)/Include
+ $(EFI_SOURCE)/Include/IndustryStandard
+ $(EFI_SOURCE)/Framework
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/protocol
+
+[libraries.common]
+ CpuGuidLib
+ CpuProtocolLib
+ DxeAslUpdateLib
+ EfiProtocolLib
+ EdkFrameworkProtocolLib
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EfiScriptLib
+ EdkProtocolLib
+ EfiRuntimeLib
+ PchPlatformLib
+ CpuPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PowerMgmtS3.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS)-D __EDKII_GLUE_MODULE_ENTRY_POINT__=PowerMgmtS3SmmEntryPoint
+ C_FLAGS = $(C_FLAGS)-D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \ No newline at end of file
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.mak b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.mak
new file mode 100644
index 0000000..e534020
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.mak
@@ -0,0 +1,64 @@
+# MAK file for the Module Part: PowerMgmtS3
+
+EDK : PowerMgmtS3
+
+BUILD_PowerMgmtS3_DIR = $(BUILD_DIR)\$(PowerMgmtS3_DIR)
+
+$(BUILD_DIR)\PowerMgmtS3.mak : $(PowerMgmtS3_DIR)\PowerMgmtS3.cif $(BUILD_RULES)
+ $(CIF2MAK) $(PowerMgmtS3_DIR)\PowerMgmtS3.cif $(CIF2MAK_DEFAULTS)
+
+PowerMgmtS3 : $(BUILD_DIR)\PowerMgmtS3.mak PowerMgmtS3Bin
+
+PowerMgmtS3_OBJECTS = \
+ $(BUILD_PowerMgmtS3_DIR)\PowerMgmtS3.obj
+
+
+PowerMgmtS3_MY_INCLUDES= \
+ $(EDK_INCLUDES) \
+ $(PROJECT_CPU_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(INTEL_MCH_INCLUDES)
+
+
+PowerMgmtS3_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PowerMgmtS3SmmEntryPoint"\
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__
+
+PowerMgmtS3_LIBS =\
+ $(EFIGUIDLIB)\
+ $(EDKFRAMEWORKGUIDLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(CpuProtocolLib_LIB)\
+ $(CpuPlatformLib_LIB)\
+ $(PchPlatformSmmLib_LIB)
+
+PowerMgmtS3Bin : $(PowerMgmtS3_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PowerMgmtS3.mak all\
+ MAKEFILE=$(BUILD_DIR)\PowerMgmtS3.mak \
+ "MY_INCLUDES=$(PowerMgmtS3_MY_INCLUDES)" \
+ "MY_DEFINES=$(PowerMgmtS3_DEFINES)"\
+ OBJECTS="$(PowerMgmtS3_OBJECTS)" \
+ GUID=8F0B5301-C79B-44f1-8FD3-26D73E316700\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER \
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PowerMgmtS3_DIR)\PowerMgmtS3.dxs \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+
diff --git a/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.sdl b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.sdl
new file mode 100644
index 0000000..513e535
--- /dev/null
+++ b/ReferenceCode/Haswell/PowerManagement/Smm/PowerMgmtS3.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "Haswell_PowerMgmtS3_SUPPORT"
+ Value = "1"
+ Help = "Main switch to include CPU RC PowerMgmtS3 driver to the Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PowerMgmtS3_DIR"
+End
+
+MODULE
+ Help = "Includes PowerMgmtS3.mak to Project"
+ File = "PowerMgmtS3.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PowerMgmtS3.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End